]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/xfs/xfs_aops.c
Merge branch 'xfs-4.10-misc-fixes-1' into for-next
[mirror_ubuntu-bionic-kernel.git] / fs / xfs / xfs_aops.c
index 3e57a56cf8294770475e5edd04d03ee5565516fa..dd6cacf59b5aa0d48850de0d2a626a8dd3d02de0 100644 (file)
@@ -1298,8 +1298,7 @@ __xfs_get_blocks(
        sector_t                iblock,
        struct buffer_head      *bh_result,
        int                     create,
-       bool                    direct,
-       bool                    dax_fault)
+       bool                    direct)
 {
        struct xfs_inode        *ip = XFS_I(inode);
        struct xfs_mount        *mp = ip->i_mount;
@@ -1361,6 +1360,26 @@ __xfs_get_blocks(
        if (error)
                goto out_unlock;
 
+       /*
+        * The only time we can ever safely find delalloc blocks on direct I/O
+        * is a dio write to post-eof speculative preallocation. All other
+        * scenarios are indicative of a problem or misuse (such as mixing
+        * direct and mapped I/O).
+        *
+        * The file may be unmapped by the time we get here so we cannot
+        * reliably fail the I/O based on mapping. Instead, fail the I/O if this
+        * is a read or a write within eof. Otherwise, carry on but warn as a
+        * precuation if the file happens to be mapped.
+        */
+       if (direct && imap.br_startblock == DELAYSTARTBLOCK) {
+               if (!create || offset < i_size_read(VFS_I(ip))) {
+                       WARN_ON_ONCE(1);
+                       error = -EIO;
+                       goto out_unlock;
+               }
+               WARN_ON_ONCE(mapping_mapped(VFS_I(ip)->i_mapping));
+       }
+
        /* for DAX, we convert unwritten extents directly */
        if (create &&
            (!nimaps ||
@@ -1420,13 +1439,8 @@ __xfs_get_blocks(
                if (ISUNWRITTEN(&imap))
                        set_buffer_unwritten(bh_result);
                /* direct IO needs special help */
-               if (create) {
-                       if (dax_fault)
-                               ASSERT(!ISUNWRITTEN(&imap));
-                       else
-                               xfs_map_direct(inode, bh_result, &imap, offset,
-                                               is_cow);
-               }
+               if (create)
+                       xfs_map_direct(inode, bh_result, &imap, offset, is_cow);
        }
 
        /*
@@ -1450,8 +1464,6 @@ __xfs_get_blocks(
             (new || ISUNWRITTEN(&imap))))
                set_buffer_new(bh_result);
 
-       BUG_ON(direct && imap.br_startblock == DELAYSTARTBLOCK);
-
        return 0;
 
 out_unlock:
@@ -1466,7 +1478,7 @@ xfs_get_blocks(
        struct buffer_head      *bh_result,
        int                     create)
 {
-       return __xfs_get_blocks(inode, iblock, bh_result, create, false, false);
+       return __xfs_get_blocks(inode, iblock, bh_result, create, false);
 }
 
 int
@@ -1476,17 +1488,7 @@ xfs_get_blocks_direct(
        struct buffer_head      *bh_result,
        int                     create)
 {
-       return __xfs_get_blocks(inode, iblock, bh_result, create, true, false);
-}
-
-int
-xfs_get_blocks_dax_fault(
-       struct inode            *inode,
-       sector_t                iblock,
-       struct buffer_head      *bh_result,
-       int                     create)
-{
-       return __xfs_get_blocks(inode, iblock, bh_result, create, true, true);
+       return __xfs_get_blocks(inode, iblock, bh_result, create, true);
 }
 
 /*