aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
-rw-r--r--fs/xfs/xfs_bmap_util.c31
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
1857out_trans_cancel: 1856out_trans_cancel:
1858 xfs_trans_cancel(tp, 0); 1857 xfs_trans_cancel(tp, 0);
1859 goto out_unlock; 1858 goto out;
1860} 1859}