xfs: prepare xfs_break_layouts() to be called with XFS_MMAPLOCK_EXCL
authorDan Williams <dan.j.williams@intel.com>
Mon, 12 Mar 2018 21:12:29 +0000 (14:12 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 22 May 2018 14:19:08 +0000 (07:19 -0700)
In preparation for adding coordination between extent unmap operations
and busy dax-pages, update xfs_break_layouts() to permit it to be called
with the mmap lock held. This lock scheme will be required for
coordinating the break of 'dax layouts' (non-idle dax (ZONE_DEVICE)
pages mapped into the file's address space). Breaking dax layouts will
be added to xfs_break_layouts() in a future patch, for now this preps
the unmap call sites to take and hold XFS_MMAPLOCK_EXCL over the call to
xfs_break_layouts().

Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Dave Chinner <david@fromorbit.com>
Suggested-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <darrick.wong@oracle.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
fs/xfs/xfs_file.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_pnfs.c

index 299aee4..35309bd 100644 (file)
@@ -734,7 +734,7 @@ xfs_file_fallocate(
        struct xfs_inode        *ip = XFS_I(inode);
        long                    error;
        enum xfs_prealloc_flags flags = 0;
-       uint                    iolock = XFS_IOLOCK_EXCL;
+       uint                    iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
        loff_t                  new_size = 0;
        bool                    do_file_insert = false;
 
@@ -748,9 +748,6 @@ xfs_file_fallocate(
        if (error)
                goto out_unlock;
 
-       xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
-       iolock |= XFS_MMAPLOCK_EXCL;
-
        if (mode & FALLOC_FL_PUNCH_HOLE) {
                error = xfs_free_file_space(ip, offset, len);
                if (error)
index 89fb1eb..4151fad 100644 (file)
@@ -614,7 +614,7 @@ xfs_ioc_space(
        struct xfs_inode        *ip = XFS_I(inode);
        struct iattr            iattr;
        enum xfs_prealloc_flags flags = 0;
-       uint                    iolock = XFS_IOLOCK_EXCL;
+       uint                    iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
        int                     error;
 
        /*
@@ -648,9 +648,6 @@ xfs_ioc_space(
        if (error)
                goto out_unlock;
 
-       xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
-       iolock |= XFS_MMAPLOCK_EXCL;
-
        switch (bf->l_whence) {
        case 0: /*SEEK_SET*/
                break;
index a3ed3c8..138fb36 100644 (file)
@@ -1031,13 +1031,17 @@ xfs_vn_setattr(
 
        if (iattr->ia_valid & ATTR_SIZE) {
                struct xfs_inode        *ip = XFS_I(d_inode(dentry));
-               uint                    iolock = XFS_IOLOCK_EXCL;
+               uint                    iolock;
+
+               xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
+               iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
 
                error = xfs_break_layouts(d_inode(dentry), &iolock);
-               if (error)
+               if (error) {
+                       xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
                        return error;
+               }
 
-               xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
                error = xfs_vn_setattr_size(dentry, iattr);
                xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
        } else {
index aa6c5c1..6ea7b0b 100644 (file)
@@ -43,7 +43,8 @@ xfs_break_layouts(
        while ((error = break_layout(inode, false) == -EWOULDBLOCK)) {
                xfs_iunlock(ip, *iolock);
                error = break_layout(inode, true);
-               *iolock = XFS_IOLOCK_EXCL;
+               *iolock &= ~XFS_IOLOCK_SHARED;
+               *iolock |= XFS_IOLOCK_EXCL;
                xfs_ilock(ip, *iolock);
        }