Commit 1f23920dbf1377fa9e4aef4f3d20c34a06a71a35

Authored by Felix Blyakher
1 parent 28e211700a

xfs: fix double unlock in xfs_swap_extents()

Regreesion from commit ef8f7fc, which rearranged the code in
xfs_swap_extents() leading to double unlock of xfs inode ilock.
That resulted in xfs_fsr deadlocking itself on platforms, which
don't handle double unlock of rw_semaphore nicely. It caused the
count go negative, which represents the write holder, without
really having one. ia64 is one of the platforms where deadlock
was easily reproduced and the fix was tested.

Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Reviewed-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: Felix Blyakher <felixb@sgi.com>

Showing 1 changed file with 5 additions and 3 deletions Side-by-side Diff

... ... @@ -347,12 +347,14 @@
347 347  
348 348 error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
349 349  
350   -out_unlock:
351   - xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
352   - xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
353 350 out:
354 351 kmem_free(tempifp);
355 352 return error;
  353 +
  354 +out_unlock:
  355 + xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
  356 + xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
  357 + goto out;
356 358  
357 359 out_trans_cancel:
358 360 xfs_trans_cancel(tp, 0);