fix a create()/unlink() deadlock
This commit is contained in:
parent
31ef85f552
commit
8607051b5f
35
fs.c
35
fs.c
|
@ -330,22 +330,27 @@ iunlock(struct inode *ip)
|
||||||
void
|
void
|
||||||
iput(struct inode *ip)
|
iput(struct inode *ip)
|
||||||
{
|
{
|
||||||
acquiresleep(&ip->lock);
|
|
||||||
if(ip->valid && ip->nlink == 0){
|
|
||||||
acquire(&icache.lock);
|
|
||||||
int r = ip->ref;
|
|
||||||
release(&icache.lock);
|
|
||||||
if(r == 1){
|
|
||||||
// inode has no links and no other references: truncate and free.
|
|
||||||
itrunc(ip);
|
|
||||||
ip->type = 0;
|
|
||||||
iupdate(ip);
|
|
||||||
ip->valid = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
releasesleep(&ip->lock);
|
|
||||||
|
|
||||||
acquire(&icache.lock);
|
acquire(&icache.lock);
|
||||||
|
|
||||||
|
if(ip->ref == 1 && ip->valid && ip->nlink == 0){
|
||||||
|
// inode has no links and no other references: truncate and free.
|
||||||
|
|
||||||
|
// ip->ref == 1 means no other process can have ip locked,
|
||||||
|
// so this acquiresleep() won't block (or deadlock).
|
||||||
|
acquiresleep(&ip->lock);
|
||||||
|
|
||||||
|
release(&icache.lock);
|
||||||
|
|
||||||
|
itrunc(ip);
|
||||||
|
ip->type = 0;
|
||||||
|
iupdate(ip);
|
||||||
|
ip->valid = 0;
|
||||||
|
|
||||||
|
releasesleep(&ip->lock);
|
||||||
|
|
||||||
|
acquire(&icache.lock);
|
||||||
|
}
|
||||||
|
|
||||||
ip->ref--;
|
ip->ref--;
|
||||||
release(&icache.lock);
|
release(&icache.lock);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue