diff options
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 22a5dcb70b32..7efa23e72a90 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -1599,13 +1599,6 @@ xfs_swap_extent_flush( | |||
1599 | /* Verify O_DIRECT for ftmp */ | 1599 | /* Verify O_DIRECT for ftmp */ |
1600 | if (VFS_I(ip)->i_mapping->nrpages) | 1600 | if (VFS_I(ip)->i_mapping->nrpages) |
1601 | return -EINVAL; | 1601 | return -EINVAL; |
1602 | |||
1603 | /* | ||
1604 | * Don't try to swap extents on mmap()d files because we can't lock | ||
1605 | * out races against page faults safely. | ||
1606 | */ | ||
1607 | if (mapping_mapped(VFS_I(ip)->i_mapping)) | ||
1608 | return -EBUSY; | ||
1609 | return 0; | 1602 | return 0; |
1610 | } | 1603 | } |
1611 | 1604 | ||
@@ -1633,13 +1626,14 @@ xfs_swap_extents( | |||
1633 | } | 1626 | } |
1634 | 1627 | ||
1635 | /* | 1628 | /* |
1636 | * Lock up the inodes against other IO and truncate to begin with. | 1629 | * Lock the inodes against other IO, page faults and truncate to |
1637 | * Then we can ensure the inodes are flushed and have no page cache | 1630 | * begin with. Then we can ensure the inodes are flushed and have no |
1638 | * safely. Once we have done this we can take the ilocks and do the rest | 1631 | * page cache safely. Once we have done this we can take the ilocks and |
1639 | * of the checks. | 1632 | * do the rest of the checks. |
1640 | */ | 1633 | */ |
1641 | lock_flags = XFS_IOLOCK_EXCL; | 1634 | lock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; |
1642 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); | 1635 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); |
1636 | xfs_lock_two_inodes(ip, tip, XFS_MMAPLOCK_EXCL); | ||
1643 | 1637 | ||
1644 | /* Verify that both files have the same format */ | 1638 | /* Verify that both files have the same format */ |
1645 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { | 1639 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { |
@@ -1666,8 +1660,16 @@ xfs_swap_extents( | |||
1666 | xfs_trans_cancel(tp, 0); | 1660 | xfs_trans_cancel(tp, 0); |
1667 | goto out_unlock; | 1661 | goto out_unlock; |
1668 | } | 1662 | } |
1663 | |||
1664 | /* | ||
1665 | * Lock and join the inodes to the tansaction so that transaction commit | ||
1666 | * or cancel will unlock the inodes from this point onwards. | ||
1667 | */ | ||
1669 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | 1668 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); |
1670 | lock_flags |= XFS_ILOCK_EXCL; | 1669 | lock_flags |= XFS_ILOCK_EXCL; |
1670 | xfs_trans_ijoin(tp, ip, lock_flags); | ||
1671 | xfs_trans_ijoin(tp, tip, lock_flags); | ||
1672 | |||
1671 | 1673 | ||
1672 | /* Verify all data are being swapped */ | 1674 | /* Verify all data are being swapped */ |
1673 | if (sxp->sx_offset != 0 || | 1675 | if (sxp->sx_offset != 0 || |
@@ -1720,9 +1722,6 @@ xfs_swap_extents( | |||
1720 | goto out_trans_cancel; | 1722 | goto out_trans_cancel; |
1721 | } | 1723 | } |
1722 | 1724 | ||
1723 | xfs_trans_ijoin(tp, ip, lock_flags); | ||
1724 | xfs_trans_ijoin(tp, tip, lock_flags); | ||
1725 | |||
1726 | /* | 1725 | /* |
1727 | * Before we've swapped the forks, lets set the owners of the forks | 1726 | * Before we've swapped the forks, lets set the owners of the forks |
1728 | * appropriately. We have to do this as we are demand paging the btree | 1727 | * appropriately. We have to do this as we are demand paging the btree |
@@ -1856,5 +1855,5 @@ out_unlock: | |||
1856 | 1855 | ||
1857 | out_trans_cancel: | 1856 | out_trans_cancel: |
1858 | xfs_trans_cancel(tp, 0); | 1857 | xfs_trans_cancel(tp, 0); |
1859 | goto out_unlock; | 1858 | goto out; |
1860 | } | 1859 | } |