fix a create()/unlink() deadlock
This commit is contained in:
		
							parent
							
								
									31ef85f552
								
							
						
					
					
						commit
						8607051b5f
					
				
					 1 changed files with 20 additions and 15 deletions
				
			
		
							
								
								
									
										19
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								fs.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -330,22 +330,27 @@ iunlock(struct inode *ip)
 | 
			
		|||
void
 | 
			
		||||
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){
 | 
			
		||||
 | 
			
		||||
  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--;
 | 
			
		||||
  release(&icache.lock);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue