|
@@ -9,9 +9,6 @@ typedef struct FreeList FreeList;
|
|
|
typedef struct BAddr BAddr;
|
|
|
|
|
|
enum {
|
|
|
- Nowaitlock,
|
|
|
- Waitlock,
|
|
|
-
|
|
|
BadHeap = ~0,
|
|
|
};
|
|
|
|
|
@@ -25,7 +22,6 @@ enum {
|
|
|
struct Cache
|
|
|
{
|
|
|
VtLock *lk;
|
|
|
- VtLock *dirtylk;
|
|
|
int ref;
|
|
|
int mode;
|
|
|
|
|
@@ -163,7 +159,6 @@ cacheAlloc(Disk *disk, VtSession *z, ulong nblocks, int mode)
|
|
|
nbl = nblocks * 4;
|
|
|
|
|
|
c->lk = vtLockAlloc();
|
|
|
- c->dirtylk = vtLockAlloc(); /* allowed to dirty blocks */
|
|
|
c->ref = 1;
|
|
|
c->disk = disk;
|
|
|
c->z = z;
|
|
@@ -561,12 +556,15 @@ fprint(2, "%s: _cacheLocal want epoch %ud got %ud\n", argv0, epoch, b->l.epoch);
|
|
|
switch(b->iostate){
|
|
|
default:
|
|
|
abort();
|
|
|
- case BioEmpty:
|
|
|
case BioLabel:
|
|
|
- if(mode == OOverWrite){
|
|
|
- blockSetIOState(b, BioClean);
|
|
|
+ if(mode == OOverWrite)
|
|
|
+ /*
|
|
|
+ * leave iostate as BioLabel because data
|
|
|
+ * hasn't been read.
|
|
|
+ */
|
|
|
return b;
|
|
|
- }
|
|
|
+ /* fall through */
|
|
|
+ case BioEmpty:
|
|
|
diskRead(c->disk, b);
|
|
|
vtSleep(b->ioready);
|
|
|
break;
|
|
@@ -1098,16 +1096,14 @@ blockDirty(Block *b)
|
|
|
|
|
|
if(b->iostate == BioDirty)
|
|
|
return 1;
|
|
|
- assert(b->iostate == BioClean);
|
|
|
+ assert(b->iostate == BioClean || b->iostate == BioLabel);
|
|
|
|
|
|
- vtLock(c->dirtylk);
|
|
|
vtLock(c->lk);
|
|
|
b->iostate = BioDirty;
|
|
|
c->ndirty++;
|
|
|
if(c->ndirty > (c->maxdirty>>1))
|
|
|
vtWakeup(c->flush);
|
|
|
vtUnlock(c->lk);
|
|
|
- vtUnlock(c->dirtylk);
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
@@ -1171,7 +1167,7 @@ blockRollback(Block *b, uchar *buf)
|
|
|
* Otherwise, bail.
|
|
|
*/
|
|
|
int
|
|
|
-blockWrite(Block *b)
|
|
|
+blockWrite(Block *b, int waitlock)
|
|
|
{
|
|
|
uchar *dmap;
|
|
|
Cache *c;
|
|
@@ -1195,7 +1191,7 @@ blockWrite(Block *b)
|
|
|
}
|
|
|
|
|
|
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 +1472,13 @@ blockRemoveLink(Block *b, u32int addr, int type, u32int tag, int recurse)
|
|
|
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 +2007,7 @@ cacheFlushBlock(Cache *c)
|
|
|
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;
|
|
@@ -2088,12 +2087,6 @@ flushThread(void *a)
|
|
|
void
|
|
|
cacheFlush(Cache *c, int wait)
|
|
|
{
|
|
|
- /*
|
|
|
- * Lock c->dirtylk so that more blocks aren't being dirtied
|
|
|
- * while we try to write out what's already here.
|
|
|
- * Otherwise we might not ever finish!
|
|
|
- */
|
|
|
- vtLock(c->dirtylk);
|
|
|
vtLock(c->lk);
|
|
|
if(wait){
|
|
|
while(c->ndirty){
|
|
@@ -2106,7 +2099,6 @@ cacheFlush(Cache *c, int wait)
|
|
|
}else if(c->ndirty)
|
|
|
vtWakeup(c->flush);
|
|
|
vtUnlock(c->lk);
|
|
|
- vtUnlock(c->dirtylk);
|
|
|
}
|
|
|
|
|
|
/*
|