diff --git a/sys/src/cmd/gefs/blk.c b/sys/src/cmd/gefs/blk.c index 6c2d0137c..588f54a5d 100644 --- a/sys/src/cmd/gefs/blk.c +++ b/sys/src/cmd/gefs/blk.c @@ -892,7 +892,7 @@ Again: } void -epochclean(void) +epochclean(int sync) { ulong c, e, ge; Limbo *p, *n; @@ -907,7 +907,7 @@ epochclean(void) for(i = 0; i < fs->nworker; i++){ e = agetl(&fs->lepoch[i]); if((e & Eactive) && e != (ge | Eactive)){ - if(c < fs->cmax/4) + if(!sync && c < fs->cmax/4) return; epochwait(); } diff --git a/sys/src/cmd/gefs/cons.c b/sys/src/cmd/gefs/cons.c index 54f377c35..77f6a341f 100644 --- a/sys/src/cmd/gefs/cons.c +++ b/sys/src/cmd/gefs/cons.c @@ -26,18 +26,12 @@ setdbg(int fd, char **ap, int na) } static void -sendsync(int fd, int halt) +asend(int fd, int op) { Amsg *a; - a = mallocz(sizeof(Amsg), 1); - if(a == nil){ - fprint(fd, "alloc sync msg: %r\n"); - free(a); - return; - } - a->op = AOsync; - a->halt = halt; + a = emalloc(sizeof(Amsg), 1); + a->op = op; a->fd = fd; chsend(fs->admchan, a); } @@ -45,14 +39,14 @@ sendsync(int fd, int halt) static void syncfs(int fd, char **, int) { - sendsync(fd, 0); + asend(fd, AOsync); fprint(fd, "synced\n"); } static void haltfs(int fd, char **, int) { - sendsync(fd, 1); + asend(fd, AOhalt); fprint(fd, "gefs: ending...\n"); } @@ -129,7 +123,7 @@ snapfs(int fd, char **ap, int na) strecpy(a->old, a->old+sizeof(a->old), ap[0]); if(na >= 2) strecpy(a->new, a->new+sizeof(a->new), ap[1]); - sendsync(fd, 0); + asend(fd, AOsync); chsend(fs->admchan, a); } diff --git a/sys/src/cmd/gefs/dat.h b/sys/src/cmd/gefs/dat.h index ec20c386e..ec65f243a 100644 --- a/sys/src/cmd/gefs/dat.h +++ b/sys/src/cmd/gefs/dat.h @@ -323,6 +323,7 @@ enum { AOnone, AOsnap, AOsync, + AOhalt, AOclear, AOrclose, }; @@ -398,6 +399,7 @@ struct Amsg { int op; int fd; union { + /* AOsync, AOhalt: no data */ struct { /* AOsnap */ char old[128]; char new[128]; @@ -405,9 +407,6 @@ struct Amsg { char delete; }; - struct { /* AOsync */ - int halt; - }; struct { /* AOclear, AOrclose */ Mount *mnt; Dent *dent; diff --git a/sys/src/cmd/gefs/fns.h b/sys/src/cmd/gefs/fns.h index 40c4a46aa..9e536a61d 100644 --- a/sys/src/cmd/gefs/fns.h +++ b/sys/src/cmd/gefs/fns.h @@ -59,7 +59,7 @@ void enqueue(Blk*); void epochstart(int); void epochend(int); void epochwait(void); -void epochclean(void); +void epochclean(int); void limbo(int op, Limbo*); void freeblk(Tree*, Blk*); void freebp(Tree*, Bptr); diff --git a/sys/src/cmd/gefs/fs.c b/sys/src/cmd/gefs/fs.c index a1f943127..cb4ced506 100644 --- a/sys/src/cmd/gefs/fs.c +++ b/sys/src/cmd/gefs/fs.c @@ -2563,7 +2563,7 @@ runmutate(int id, void *) assert(estacksz() == 0); epochend(id); qunlock(&fs->mutlk); - epochclean(); + epochclean(0); if(a != nil) chsend(fs->admchan, a); @@ -2612,7 +2612,7 @@ freetree(Bptr rb, vlong pred) freetree(bp, pred); /* leak b on error() */ qlock(&fs->mutlk); qunlock(&fs->mutlk); - epochclean(); + epochclean(0); } } if(rb.gen > pred) @@ -2648,7 +2648,7 @@ sweeptree(Tree *t) freebp(nil, bp); qlock(&fs->mutlk); qunlock(&fs->mutlk); - epochclean(); + epochclean(0); } btexit(&s); freetree(t->bp, t->pred); @@ -2672,20 +2672,27 @@ runsweep(int id, void*) while(1){ am = chrecv(fs->admchan); switch(am->op){ + case AOhalt: + if(!agetl(&fs->rdonly)){ + ainc(&fs->rdonly); + /* cycle through all epochs to clear them. */ + for(i = 0; i < 3; i++) + epochclean(1); + sync(); + } + postnote(PNGROUP, getpid(), "halted"); + exits(nil); + break; case AOsync: tracem("syncreq"); - if(!fs->snap.dirty && !am->halt) + if(!fs->snap.dirty || agetl(&fs->rdonly)) goto Next; - if(agetl(&fs->rdonly)) - goto Justhalt; if(waserror()){ fprint(2, "sync error: %s\n", errmsg()); ainc(&fs->rdonly); break; } - if(am->halt) - ainc(&fs->rdonly); for(i = 0; i < fs->narena; i++){ a = &fs->arenas[i]; oldhd[i].addr = -1; @@ -2709,7 +2716,7 @@ runsweep(int id, void*) poperror(); } qunlock(a); - epochclean(); + epochclean(0); } sync(); /* oldhd blocks leaked on error() */ @@ -2730,17 +2737,10 @@ runsweep(int id, void*) epochend(id); qunlock(&fs->mutlk); poperror(); - epochclean(); + epochclean(0); } } -Justhalt: - if(am->halt){ - assert(fs->snapdl.hd.addr == -1); - assert(fs->snapdl.tl.addr == -1); - postnote(PNGROUP, getpid(), "halted"); - exits(nil); - } poperror(); break; @@ -2852,7 +2852,7 @@ Justhalt: epochend(id); qunlock(&fs->mutlk); poperror(); - epochclean(); + epochclean(0); nm = 0; } } @@ -2911,7 +2911,6 @@ runtasks(int, void *) } a = emalloc(sizeof(Amsg), 1); a->op = AOsync; - a->halt = 0; a->fd = -1; chsend(fs->admchan, a);