fix a create()/unlink() deadlock
This commit is contained in:
		
							parent
							
								
									31ef85f552
								
							
						
					
					
						commit
						8607051b5f
					
				
					 1 changed files with 20 additions and 15 deletions
				
			
		
							
								
								
									
										35
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										35
									
								
								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){ | ||||
|       // 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); | ||||
| 
 | ||||
|   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
		Add a link
		
	
		Reference in a new issue
	
	 Robert Morris
						Robert Morris