iomap: sub-block dio needs to zeroout beyond EOF
[sfrench/cifs-2.6.git] / fs / iomap.c
index ec15cf2ec696dae1f77a2c45fe4fd7129bbc2e29..77c214194edf6f4cd68f2b150541a89571f7900d 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/task_io_accounting_ops.h>
 #include <linux/dax.h>
 #include <linux/sched/signal.h>
-#include <linux/swap.h>
 
 #include "internal.h"
 
@@ -1057,7 +1056,7 @@ iomap_page_mkwrite_actor(struct inode *inode, loff_t pos, loff_t length,
        return length;
 }
 
-int iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops)
+vm_fault_t iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops)
 {
        struct page *page = vmf->page;
        struct inode *inode = file_inode(vmf->vma->vm_file);
@@ -1597,12 +1596,13 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
 
        if (iomap->flags & IOMAP_F_NEW) {
                need_zeroout = true;
-       } else {
+       } else if (iomap->type == IOMAP_MAPPED) {
                /*
-                * Use a FUA write if we need datasync semantics, this
-                * is a pure data IO that doesn't require any metadata
-                * updates and the underlying device supports FUA. This
-                * allows us to avoid cache flushes on IO completion.
+                * Use a FUA write if we need datasync semantics, this is a pure
+                * data IO that doesn't require any metadata updates (including
+                * after IO completion such as unwritten extent conversion) and
+                * the underlying device supports FUA. This allows us to avoid
+                * cache flushes on IO completion.
                 */
                if (!(iomap->flags & (IOMAP_F_SHARED|IOMAP_F_DIRTY)) &&
                    (dio->flags & IOMAP_DIO_WRITE_FUA) &&
@@ -1677,7 +1677,14 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
                dio->submit.cookie = submit_bio(bio);
        } while (nr_pages);
 
-       if (need_zeroout) {
+       /*
+        * We need to zeroout the tail of a sub-block write if the extent type
+        * requires zeroing or the write extends beyond EOF. If we don't zero
+        * the block tail in the latter case, we can expose stale data via mmap
+        * reads of the EOF block.
+        */
+       if (need_zeroout ||
+           ((dio->flags & IOMAP_DIO_WRITE) && pos >= i_size_read(inode))) {
                /* zero out from the end of the write to the end of the block */
                pad = pos & (fs_block_size - 1);
                if (pad)
@@ -1795,7 +1802,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
                if (pos >= dio->i_size)
                        goto out_free_dio;
 
-               if (iter->type == ITER_IOVEC)
+               if (iter_is_iovec(iter) && iov_iter_rw(iter) == READ)
                        dio->flags |= IOMAP_DIO_DIRTY;
        } else {
                flags |= IOMAP_WRITE;