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
 | 
					void
 | 
				
			||||||
iput(struct inode *ip)
 | 
					iput(struct inode *ip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  acquiresleep(&ip->lock);
 | 
					 | 
				
			||||||
  if(ip->valid && ip->nlink == 0){
 | 
					 | 
				
			||||||
  acquire(&icache.lock);
 | 
					  acquire(&icache.lock);
 | 
				
			||||||
    int r = ip->ref;
 | 
					
 | 
				
			||||||
    release(&icache.lock);
 | 
					  if(ip->ref == 1 && ip->valid && ip->nlink == 0){
 | 
				
			||||||
    if(r == 1){
 | 
					 | 
				
			||||||
    // inode has no links and no other references: truncate and free.
 | 
					    // 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);
 | 
					    itrunc(ip);
 | 
				
			||||||
    ip->type = 0;
 | 
					    ip->type = 0;
 | 
				
			||||||
    iupdate(ip);
 | 
					    iupdate(ip);
 | 
				
			||||||
    ip->valid = 0;
 | 
					    ip->valid = 0;
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
    releasesleep(&ip->lock);
 | 
					    releasesleep(&ip->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    acquire(&icache.lock);
 | 
					    acquire(&icache.lock);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ip->ref--;
 | 
					  ip->ref--;
 | 
				
			||||||
  release(&icache.lock);
 | 
					  release(&icache.lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue