hjfs: fix getfree() races, fix very rare buf leak in deltraverse()
This commit is contained in:
parent
84ddc4cd4b
commit
08cd0ea8d4
1 changed files with 40 additions and 24 deletions
|
@ -62,44 +62,57 @@ int
|
|||
getfree(Fs *fs, uvlong *r)
|
||||
{
|
||||
Dev *d;
|
||||
Buf *b, *c;
|
||||
uvlong i, l;
|
||||
Buf *b;
|
||||
uvlong i, l, e;
|
||||
int j, have;
|
||||
|
||||
d = fs->d;
|
||||
while(nbrecv(fs->freelist, &l) > 0){
|
||||
i = fs->fstart + l / REFPERBLK;
|
||||
j = l % REFPERBLK;
|
||||
b = getbuf(d, i, TREF, 0);
|
||||
if(b != nil){
|
||||
if(b->refs[j] == 0){
|
||||
b->refs[j] = 1;
|
||||
*r = l;
|
||||
goto found;
|
||||
}
|
||||
putbuf(b);
|
||||
}
|
||||
}
|
||||
|
||||
b = getbuf(d, SUPERBLK, TSUPERBLOCK, 0);
|
||||
if(b == nil)
|
||||
return -1;
|
||||
if(nbrecv(fs->freelist, r) > 0)
|
||||
goto found;
|
||||
e = b->sb.fend;
|
||||
putbuf(b);
|
||||
|
||||
have = 0;
|
||||
for(i = b->sb.fstart, l = 0; i < b->sb.fend; i++){
|
||||
c = getbuf(d, i, TREF, 0);
|
||||
if(c == nil){
|
||||
putbuf(b);
|
||||
return -1;
|
||||
for(l = 0, i = fs->fstart; i < e; i++){
|
||||
b = getbuf(d, i, TREF, 0);
|
||||
if(b == nil){
|
||||
l += REFPERBLK;
|
||||
continue;
|
||||
}
|
||||
for(j = 0; j < REFPERBLK; j++, l++)
|
||||
if(c->refs[j] == 0){
|
||||
if(b->refs[j] == 0){
|
||||
if(!have){
|
||||
have = 1;
|
||||
b->refs[j] = 1;
|
||||
*r = l;
|
||||
}else if(nbsend(fs->freelist, &l) <= 0){
|
||||
putbuf(c);
|
||||
goto done;
|
||||
have = 1;
|
||||
}
|
||||
else if(nbsend(fs->freelist, &l) <= 0)
|
||||
goto found;
|
||||
}
|
||||
putbuf(c);
|
||||
}
|
||||
done:
|
||||
if(!have){
|
||||
werrstr("disk full");
|
||||
return -1;
|
||||
if(have)
|
||||
goto found;
|
||||
putbuf(b);
|
||||
}
|
||||
werrstr("disk full");
|
||||
return -1;
|
||||
found:
|
||||
b->op |= BDELWRI;
|
||||
putbuf(b);
|
||||
if(chref(fs, *r, 1) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -854,14 +867,17 @@ deltraverse(Fs *fs, Del *p, Buf *b, Del **last)
|
|||
Del *dd;
|
||||
|
||||
frb = b == nil;
|
||||
if(b == nil){
|
||||
if(frb){
|
||||
b = getbuf(fs->d, p->blk, TDENTRY, 0);
|
||||
if(b == nil)
|
||||
return -1;
|
||||
}
|
||||
d = getdent(p, b);
|
||||
if(d == nil)
|
||||
if(d == nil){
|
||||
if(frb)
|
||||
putbuf(b);
|
||||
return -1;
|
||||
}
|
||||
s = d->size;
|
||||
for(i = 0; i < s; i++){
|
||||
rc = getblk(fs, p, b, i, &r, GBREAD);
|
||||
|
|
Loading…
Reference in a new issue