]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/iomap.c
fs: semove set but not checked AOP_FLAG_UNINTERRUPTIBLE flag
[karo-tx-linux.git] / fs / iomap.c
index a51cb4c07d4d8cd3a09715361c84126cecae2ca2..4b10892967a5ae9a4ece5d8571e47c01c72f74da 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/buffer_head.h>
 #include <linux/task_io_accounting_ops.h>
 #include <linux/dax.h>
+#include <linux/sched/signal.h>
+
 #include "internal.h"
 
 /*
@@ -41,7 +43,7 @@
  */
 loff_t
 iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags,
-               struct iomap_ops *ops, void *data, iomap_actor_t actor)
+               const struct iomap_ops *ops, void *data, iomap_actor_t actor)
 {
        struct iomap iomap = { 0 };
        loff_t written = 0, ret;
@@ -156,12 +158,6 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
        ssize_t written = 0;
        unsigned int flags = AOP_FLAG_NOFS;
 
-       /*
-        * Copies from kernel address space cannot fail (NFSD is a big user).
-        */
-       if (!iter_is_iovec(i))
-               flags |= AOP_FLAG_UNINTERRUPTIBLE;
-
        do {
                struct page *page;
                unsigned long offset;   /* Offset into pagecache page */
@@ -235,7 +231,7 @@ again:
 
 ssize_t
 iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *iter,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
 {
        struct inode *inode = iocb->ki_filp->f_mapping->host;
        loff_t pos = iocb->ki_pos, ret = 0, written = 0;
@@ -289,8 +285,7 @@ iomap_dirty_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
                        return PTR_ERR(rpage);
 
                status = iomap_write_begin(inode, pos, bytes,
-                               AOP_FLAG_NOFS | AOP_FLAG_UNINTERRUPTIBLE,
-                               &page, iomap);
+                                          AOP_FLAG_NOFS, &page, iomap);
                put_page(rpage);
                if (unlikely(status))
                        return status;
@@ -318,7 +313,7 @@ iomap_dirty_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
 
 int
 iomap_file_dirty(struct inode *inode, loff_t pos, loff_t len,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
 {
        loff_t ret;
 
@@ -341,8 +336,8 @@ static int iomap_zero(struct inode *inode, loff_t pos, unsigned offset,
        struct page *page;
        int status;
 
-       status = iomap_write_begin(inode, pos, bytes,
-                       AOP_FLAG_UNINTERRUPTIBLE | AOP_FLAG_NOFS, &page, iomap);
+       status = iomap_write_begin(inode, pos, bytes, AOP_FLAG_NOFS, &page,
+                                  iomap);
        if (status)
                return status;
 
@@ -358,7 +353,8 @@ static int iomap_dax_zero(loff_t pos, unsigned offset, unsigned bytes,
        sector_t sector = iomap->blkno +
                (((pos & ~(PAGE_SIZE - 1)) - iomap->offset) >> 9);
 
-       return __dax_zero_page_range(iomap->bdev, sector, offset, bytes);
+       return __dax_zero_page_range(iomap->bdev, iomap->dax_dev, sector,
+                       offset, bytes);
 }
 
 static loff_t
@@ -398,7 +394,7 @@ iomap_zero_range_actor(struct inode *inode, loff_t pos, loff_t count,
 
 int
 iomap_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
 {
        loff_t ret;
 
@@ -418,10 +414,10 @@ EXPORT_SYMBOL_GPL(iomap_zero_range);
 
 int
 iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
 {
-       unsigned blocksize = (1 << inode->i_blkbits);
-       unsigned off = pos & (blocksize - 1);
+       unsigned int blocksize = i_blocksize(inode);
+       unsigned int off = pos & (blocksize - 1);
 
        /* Block boundary? Nothing to do */
        if (!off)
@@ -445,11 +441,10 @@ iomap_page_mkwrite_actor(struct inode *inode, loff_t pos, loff_t length,
        return length;
 }
 
-int iomap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
-               struct iomap_ops *ops)
+int iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops)
 {
        struct page *page = vmf->page;
-       struct inode *inode = file_inode(vma->vm_file);
+       struct inode *inode = file_inode(vmf->vma->vm_file);
        unsigned long length;
        loff_t offset, size;
        ssize_t ret;
@@ -545,7 +540,7 @@ iomap_fiemap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
 }
 
 int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
-               loff_t start, loff_t len, struct iomap_ops *ops)
+               loff_t start, loff_t len, const struct iomap_ops *ops)
 {
        struct fiemap_ctx ctx;
        loff_t ret;
@@ -736,9 +731,9 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
                void *data, struct iomap *iomap)
 {
        struct iomap_dio *dio = data;
-       unsigned blkbits = blksize_bits(bdev_logical_block_size(iomap->bdev));
-       unsigned fs_block_size = (1 << inode->i_blkbits), pad;
-       unsigned align = iov_iter_alignment(dio->submit.iter);
+       unsigned int blkbits = blksize_bits(bdev_logical_block_size(iomap->bdev));
+       unsigned int fs_block_size = i_blocksize(inode), pad;
+       unsigned int align = iov_iter_alignment(dio->submit.iter);
        struct iov_iter iter;
        struct bio *bio;
        bool need_zeroout = false;
@@ -839,13 +834,14 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
 }
 
 ssize_t
-iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, struct iomap_ops *ops,
-               iomap_dio_end_io_t end_io)
+iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
+               const struct iomap_ops *ops, iomap_dio_end_io_t end_io)
 {
        struct address_space *mapping = iocb->ki_filp->f_mapping;
        struct inode *inode = file_inode(iocb->ki_filp);
        size_t count = iov_iter_count(iter);
-       loff_t pos = iocb->ki_pos, end = iocb->ki_pos + count - 1, ret = 0;
+       loff_t pos = iocb->ki_pos, start = pos;
+       loff_t end = iocb->ki_pos + count - 1, ret = 0;
        unsigned int flags = IOMAP_DIRECT;
        struct blk_plug plug;
        struct iomap_dio *dio;
@@ -885,16 +881,14 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, struct iomap_ops *ops,
                flags |= IOMAP_WRITE;
        }
 
-       if (mapping->nrpages) {
-               ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, end);
-               if (ret)
-                       goto out_free_dio;
+       ret = filemap_write_and_wait_range(mapping, start, end);
+       if (ret)
+               goto out_free_dio;
 
-               ret = invalidate_inode_pages2_range(mapping,
-                               iocb->ki_pos >> PAGE_SHIFT, end >> PAGE_SHIFT);
-               WARN_ON_ONCE(ret);
-               ret = 0;
-       }
+       ret = invalidate_inode_pages2_range(mapping,
+                       start >> PAGE_SHIFT, end >> PAGE_SHIFT);
+       WARN_ON_ONCE(ret);
+       ret = 0;
 
        inode_dio_begin(inode);
 
@@ -909,6 +903,9 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, struct iomap_ops *ops,
                        break;
                }
                pos += ret;
+
+               if (iov_iter_rw(iter) == READ && pos >= dio->i_size)
+                       break;
        } while ((count = iov_iter_count(iter)) > 0);
        blk_finish_plug(&plug);
 
@@ -940,6 +937,8 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, struct iomap_ops *ops,
                __set_current_state(TASK_RUNNING);
        }
 
+       ret = iomap_dio_complete(dio);
+
        /*
         * Try again to invalidate clean pages which might have been cached by
         * non-direct readahead, or faulted in by get_user_pages() if the source
@@ -947,13 +946,13 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, struct iomap_ops *ops,
         * one is a pretty crazy thing to do, so we don't support it 100%.  If
         * this invalidation fails, tough, the write still worked...
         */
-       if (iov_iter_rw(iter) == WRITE && mapping->nrpages) {
-               ret = invalidate_inode_pages2_range(mapping,
-                               iocb->ki_pos >> PAGE_SHIFT, end >> PAGE_SHIFT);
-               WARN_ON_ONCE(ret);
+       if (iov_iter_rw(iter) == WRITE) {
+               int err = invalidate_inode_pages2_range(mapping,
+                               start >> PAGE_SHIFT, end >> PAGE_SHIFT);
+               WARN_ON_ONCE(err);
        }
 
-       return iomap_dio_complete(dio);
+       return ret;
 
 out_free_dio:
        kfree(dio);