]> 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 561cf1456c6ca1ed07484e5daf455c6f40015959..dd6cacf59b5aa0d48850de0d2a626a8dd3d02de0 100644 (file)
@@ -1360,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 ||
@@ -1444,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: