Get rid of warning messages (1) "could not write super block; waiting 10 seconds" and (2) "blistAlloc: called on clean block". (1) Add a waitlock parameter to blockWrite, so superWrite can tell it to wait when it finds the dependent root block locked when trying to write out the new epoch's super block. (2) Don't try to allocate an unneeded BList to remove the old epoch's root block from the active file system, in the rare case when the super block has already been written out. Reference: /n/sources/patch/applied/fossil-superblock-write Date: Mon Mar 26 12:15:15 CES 2012 Signed-off-by: miller@hamnavoe.com --- /sys/src/cmd/fossil/9fsys.c Mon Mar 26 12:14:40 2012 +++ /sys/src/cmd/fossil/9fsys.c Mon Mar 26 12:14:37 2012 @@ -662,7 +662,7 @@ goto Out1; n = 0; for(;;){ - if(blockWrite(bb)){ + if(blockWrite(bb, Waitlock)){ while(bb->iostate != BioClean){ assert(bb->iostate == BioWriting); vtSleep(bb->ioready); --- /sys/src/cmd/fossil/cache.c Mon Mar 26 12:14:47 2012 +++ /sys/src/cmd/fossil/cache.c Mon Mar 26 12:14:43 2012 @@ -9,9 +9,6 @@ typedef struct BAddr BAddr; enum { - Nowaitlock, - Waitlock, - BadHeap = ~0, }; @@ -1171,7 +1168,7 @@ * Otherwise, bail. */ int -blockWrite(Block *b) +blockWrite(Block *b, int waitlock) { uchar *dmap; Cache *c; @@ -1195,7 +1192,7 @@ } lockfail = 0; - bb = _cacheLocalLookup(c, p->part, p->addr, p->vers, Nowaitlock, + bb = _cacheLocalLookup(c, p->part, p->addr, p->vers, waitlock, &lockfail); if(bb == nil){ if(lockfail) @@ -1476,10 +1473,13 @@ bl.next = nil; bl.recurse = recurse; - p = blistAlloc(b); + if(b->part == PartSuper && b->iostate == BioClean) + p = nil; + else + p = blistAlloc(b); if(p == nil){ /* - * We were out of blists so blistAlloc wrote b to disk. + * b has already been written to disk. */ doRemoveLink(b->c, &bl); return; @@ -2008,7 +2008,7 @@ b = _cacheLocalLookup(c, p->part, p->addr, p->vers, Nowaitlock, &lockfail); - if(b && blockWrite(b)){ + if(b && blockWrite(b, Nowaitlock)){ c->nflush++; blockPut(b); return 1; --- /sys/src/cmd/fossil/dat.h Mon Mar 26 12:14:50 2012 +++ /sys/src/cmd/fossil/dat.h Mon Mar 26 12:14:48 2012 @@ -34,6 +34,9 @@ }; enum { + Nowaitlock, + Waitlock, + NilBlock = (~0UL), MaxBlock = (1UL<<31), }; --- /sys/src/cmd/fossil/fns.h Mon Mar 26 12:14:54 2012 +++ /sys/src/cmd/fossil/fns.h Mon Mar 26 12:14:52 2012 @@ -39,7 +39,7 @@ void blockSetIOState(Block*, int); Block* _blockSetLabel(Block*, Label*); int blockSetLabel(Block*, Label*, int); -int blockWrite(Block*); +int blockWrite(Block*, int); Disk* diskAlloc(int); int diskBlockSize(Disk*); --- /sys/src/cmd/fossil/fs.c Mon Mar 26 12:14:58 2012 +++ /sys/src/cmd/fossil/fs.c Mon Mar 26 12:14:56 2012 @@ -204,8 +204,8 @@ superPack(super, b->data); blockDirty(b); if(forceWrite){ - while(!blockWrite(b)){ - /* BUG: what should really happen here? */ + while(!blockWrite(b, Waitlock)){ + /* this should no longer happen */ fprint(2, "%s: could not write super block; " "waiting 10 seconds\n", argv0); sleep(10*1000);