xfs: fix multi-AG deadlock in xfs_bunmapi
Just like in the allocator we must avoid touching multiple AGs out of order when freeing blocks, as freeing still locks the AGF and can cause the same AB-BA deadlocks as in the allocation path. Signed-off-by: Christoph Hellwig <hch@lst.de> Reported-by: Nikolay Borisov <n.borisov.lkml@gmail.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
		
							parent
							
								
									6215894e11
								
							
						
					
					
						commit
						5b094d6dac
					
				| @ -5435,6 +5435,7 @@ __xfs_bunmapi( | ||||
| 	xfs_fsblock_t		sum; | ||||
| 	xfs_filblks_t		len = *rlen;	/* length to unmap in file */ | ||||
| 	xfs_fileoff_t		max_len; | ||||
| 	xfs_agnumber_t		prev_agno = NULLAGNUMBER, agno; | ||||
| 
 | ||||
| 	trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); | ||||
| 
 | ||||
| @ -5534,6 +5535,17 @@ __xfs_bunmapi( | ||||
| 		 */ | ||||
| 		del = got; | ||||
| 		wasdel = isnullstartblock(del.br_startblock); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * Make sure we don't touch multiple AGF headers out of order | ||||
| 		 * in a single transaction, as that could cause AB-BA deadlocks. | ||||
| 		 */ | ||||
| 		if (!wasdel) { | ||||
| 			agno = XFS_FSB_TO_AGNO(mp, del.br_startblock); | ||||
| 			if (prev_agno != NULLAGNUMBER && prev_agno > agno) | ||||
| 				break; | ||||
| 			prev_agno = agno; | ||||
| 		} | ||||
| 		if (got.br_startoff < start) { | ||||
| 			del.br_startoff = start; | ||||
| 			del.br_blockcount -= start - got.br_startoff; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user