]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/btrfs/inode.c
Merge branch 'for-4.13-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[mirror_ubuntu-artful-kernel.git] / fs / btrfs / inode.c
index 5d3c6ac960fd24c195a102812a9d3332cb8ab53f..8d050314591cd38bf4f40a212b0bc613b2773779 100644 (file)
@@ -836,13 +836,12 @@ retry:
                                NULL, EXTENT_LOCKED | EXTENT_DELALLOC,
                                PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
                                PAGE_SET_WRITEBACK);
-               ret = btrfs_submit_compressed_write(inode,
+               if (btrfs_submit_compressed_write(inode,
                                    async_extent->start,
                                    async_extent->ram_size,
                                    ins.objectid,
                                    ins.offset, async_extent->pages,
-                                   async_extent->nr_pages);
-               if (ret) {
+                                   async_extent->nr_pages)) {
                        struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
                        struct page *p = async_extent->pages[0];
                        const u64 start = async_extent->start;
@@ -1900,12 +1899,12 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
  * At IO completion time the cums attached on the ordered extent record
  * are inserted into the btree
  */
-static int __btrfs_submit_bio_start(void *private_data, struct bio *bio,
+static blk_status_t __btrfs_submit_bio_start(void *private_data, struct bio *bio,
                                    int mirror_num, unsigned long bio_flags,
                                    u64 bio_offset)
 {
        struct inode *inode = private_data;
-       int ret = 0;
+       blk_status_t ret = 0;
 
        ret = btrfs_csum_one_bio(inode, bio, 0, 0);
        BUG_ON(ret); /* -ENOMEM */
@@ -1920,17 +1919,17 @@ static int __btrfs_submit_bio_start(void *private_data, struct bio *bio,
  * At IO completion time the cums attached on the ordered extent record
  * are inserted into the btree
  */
-static int __btrfs_submit_bio_done(void *private_data, struct bio *bio,
+static blk_status_t __btrfs_submit_bio_done(void *private_data, struct bio *bio,
                          int mirror_num, unsigned long bio_flags,
                          u64 bio_offset)
 {
        struct inode *inode = private_data;
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       int ret;
+       blk_status_t ret;
 
        ret = btrfs_map_bio(fs_info, bio, mirror_num, 1);
        if (ret) {
-               bio->bi_error = ret;
+               bio->bi_status = ret;
                bio_endio(bio);
        }
        return ret;
@@ -1940,7 +1939,7 @@ static int __btrfs_submit_bio_done(void *private_data, struct bio *bio,
  * extent_io.c submission hook. This does the right thing for csum calculation
  * on write, or reading the csums from the tree before a read
  */
-static int btrfs_submit_bio_hook(void *private_data, struct bio *bio,
+static blk_status_t btrfs_submit_bio_hook(void *private_data, struct bio *bio,
                                 int mirror_num, unsigned long bio_flags,
                                 u64 bio_offset)
 {
@@ -1948,7 +1947,7 @@ static int btrfs_submit_bio_hook(void *private_data, struct bio *bio,
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        enum btrfs_wq_endio_type metadata = BTRFS_WQ_ENDIO_DATA;
-       int ret = 0;
+       blk_status_t ret = 0;
        int skip_sum;
        int async = !atomic_read(&BTRFS_I(inode)->sync_writers);
 
@@ -1993,8 +1992,8 @@ mapit:
        ret = btrfs_map_bio(fs_info, bio, mirror_num, 0);
 
 out:
-       if (ret < 0) {
-               bio->bi_error = ret;
+       if (ret) {
+               bio->bi_status = ret;
                bio_endio(bio);
        }
        return ret;
@@ -8051,7 +8050,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
        struct extent_io_tree *io_tree, *failure_tree;
        int i;
 
-       if (bio->bi_error)
+       if (bio->bi_status)
                goto end;
 
        ASSERT(bio->bi_vcnt == 1);
@@ -8140,7 +8139,7 @@ static void btrfs_retry_endio(struct bio *bio)
        int ret;
        int i;
 
-       if (bio->bi_error)
+       if (bio->bi_status)
                goto end;
 
        uptodate = 1;
@@ -8171,8 +8170,8 @@ end:
        bio_put(bio);
 }
 
-static int __btrfs_subio_endio_read(struct inode *inode,
-                                   struct btrfs_io_bio *io_bio, int err)
+static blk_status_t __btrfs_subio_endio_read(struct inode *inode,
+               struct btrfs_io_bio *io_bio, blk_status_t err)
 {
        struct btrfs_fs_info *fs_info;
        struct bio_vec bvec;
@@ -8217,7 +8216,7 @@ try_again:
                                io_bio->mirror_num,
                                btrfs_retry_endio, &done);
                if (ret) {
-                       err = ret;
+                       err = errno_to_blk_status(ret);
                        goto next;
                }
 
@@ -8244,8 +8243,8 @@ next:
        return err;
 }
 
-static int btrfs_subio_endio_read(struct inode *inode,
-                                 struct btrfs_io_bio *io_bio, int err)
+static blk_status_t btrfs_subio_endio_read(struct inode *inode,
+               struct btrfs_io_bio *io_bio, blk_status_t err)
 {
        bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
 
@@ -8265,12 +8264,12 @@ static void btrfs_endio_direct_read(struct bio *bio)
        struct inode *inode = dip->inode;
        struct bio *dio_bio;
        struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
-       int err = bio->bi_error;
+       blk_status_t err = bio->bi_status;
 
        if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) {
                err = btrfs_subio_endio_read(inode, io_bio, err);
                if (!err)
-                       bio->bi_error = 0;
+                       bio->bi_status = 0;
        }
 
        unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
@@ -8279,11 +8278,11 @@ static void btrfs_endio_direct_read(struct bio *bio)
 
        kfree(dip);
 
-       dio_bio->bi_error = bio->bi_error;
-       dio_end_io(dio_bio, bio->bi_error);
+       dio_bio->bi_status = bio->bi_status;
+       dio_end_io(dio_bio);
 
        if (io_bio->end_io)
-               io_bio->end_io(io_bio, err);
+               io_bio->end_io(io_bio, blk_status_to_errno(err));
        bio_put(bio);
 }
 
@@ -8335,21 +8334,21 @@ static void btrfs_endio_direct_write(struct bio *bio)
        struct bio *dio_bio = dip->dio_bio;
 
        __endio_write_update_ordered(dip->inode, dip->logical_offset,
-                                    dip->bytes, !bio->bi_error);
+                                    dip->bytes, !bio->bi_status);
 
        kfree(dip);
 
-       dio_bio->bi_error = bio->bi_error;
-       dio_end_io(dio_bio, bio->bi_error);
+       dio_bio->bi_status = bio->bi_status;
+       dio_end_io(dio_bio);
        bio_put(bio);
 }
 
-static int __btrfs_submit_bio_start_direct_io(void *private_data,
+static blk_status_t __btrfs_submit_bio_start_direct_io(void *private_data,
                                    struct bio *bio, int mirror_num,
                                    unsigned long bio_flags, u64 offset)
 {
        struct inode *inode = private_data;
-       int ret;
+       blk_status_t ret;
        ret = btrfs_csum_one_bio(inode, bio, offset, 1);
        BUG_ON(ret); /* -ENOMEM */
        return 0;
@@ -8358,7 +8357,7 @@ static int __btrfs_submit_bio_start_direct_io(void *private_data,
 static void btrfs_end_dio_bio(struct bio *bio)
 {
        struct btrfs_dio_private *dip = bio->bi_private;
-       int err = bio->bi_error;
+       blk_status_t err = bio->bi_status;
 
        if (err)
                btrfs_warn(BTRFS_I(dip->inode)->root->fs_info,
@@ -8388,21 +8387,21 @@ static void btrfs_end_dio_bio(struct bio *bio)
        if (dip->errors) {
                bio_io_error(dip->orig_bio);
        } else {
-               dip->dio_bio->bi_error = 0;
+               dip->dio_bio->bi_status = 0;
                bio_endio(dip->orig_bio);
        }
 out:
        bio_put(bio);
 }
 
-static inline int btrfs_lookup_and_bind_dio_csum(struct inode *inode,
+static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode,
                                                 struct btrfs_dio_private *dip,
                                                 struct bio *bio,
                                                 u64 file_offset)
 {
        struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
        struct btrfs_io_bio *orig_io_bio = btrfs_io_bio(dip->orig_bio);
-       int ret;
+       blk_status_t ret;
 
        /*
         * We load all the csum data we need when we submit
@@ -8433,7 +8432,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_dio_private *dip = bio->bi_private;
        bool write = bio_op(bio) == REQ_OP_WRITE;
-       int ret;
+       blk_status_t ret;
 
        if (async_submit)
                async_submit = !atomic_read(&BTRFS_I(inode)->sync_writers);
@@ -8670,12 +8669,12 @@ free_ordered:
                        unlock_extent(&BTRFS_I(inode)->io_tree, file_offset,
                              file_offset + dio_bio->bi_iter.bi_size - 1);
 
-               dio_bio->bi_error = -EIO;
+               dio_bio->bi_status = BLK_STS_IOERR;
                /*
                 * Releases and cleans up our dio_bio, no need to bio_put()
                 * nor bio_endio()/bio_io_error() against dio_bio.
                 */
-               dio_end_io(dio_bio, ret);
+               dio_end_io(dio_bio);
        }
        if (bio)
                bio_put(bio);
@@ -8758,6 +8757,9 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                        dio_data.overwrite = 1;
                        inode_unlock(inode);
                        relock = true;
+               } else if (iocb->ki_flags & IOCB_NOWAIT) {
+                       ret = -EAGAIN;
+                       goto out;
                }
                ret = btrfs_delalloc_reserve_space(inode, &data_reserved,
                                                   offset, count);