fix a create()/unlink() deadlock

This commit is contained in:
Robert Morris 2019-06-06 10:38:11 -04:00
parent 31ef85f552
commit 8607051b5f

35
fs.c
View file

@ -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);
} }