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>

+5 -3
+5 -3
fs/xfs/xfs_dfrag.c
··· 347 348 error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT); 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 out: 354 kmem_free(tempifp); 355 return error; 356 357 out_trans_cancel: 358 xfs_trans_cancel(tp, 0);
··· 347 348 error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT); 349 350 out: 351 kmem_free(tempifp); 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; 358 359 out_trans_cancel: 360 xfs_trans_cancel(tp, 0);