Merge branch 'for-4.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[muen/linux.git] / fs / btrfs / inode.c
index 128f3e58634f4a6821b4cf18547db075cfbe03d5..d94e3f68b9b134f8e3027dec70f1952c42e8ce52 100644 (file)
@@ -135,6 +135,18 @@ static inline void btrfs_cleanup_ordered_extents(struct inode *inode,
                                                 const u64 offset,
                                                 const u64 bytes)
 {
+       unsigned long index = offset >> PAGE_SHIFT;
+       unsigned long end_index = (offset + bytes - 1) >> PAGE_SHIFT;
+       struct page *page;
+
+       while (index <= end_index) {
+               page = find_get_page(inode->i_mapping, index);
+               index++;
+               if (!page)
+                       continue;
+               ClearPagePrivate2(page);
+               put_page(page);
+       }
        return __endio_write_update_ordered(inode, offset + PAGE_SIZE,
                                            bytes - PAGE_SIZE, false);
 }
@@ -8357,11 +8369,8 @@ static void btrfs_endio_direct_read(struct bio *bio)
        struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
        blk_status_t err = bio->bi_status;
 
-       if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) {
+       if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED)
                err = btrfs_subio_endio_read(inode, io_bio, err);
-               if (!err)
-                       bio->bi_status = 0;
-       }
 
        unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
                      dip->logical_offset + dip->bytes - 1);
@@ -8369,7 +8378,7 @@ static void btrfs_endio_direct_read(struct bio *bio)
 
        kfree(dip);
 
-       dio_bio->bi_status = bio->bi_status;
+       dio_bio->bi_status = err;
        dio_end_io(dio_bio);
 
        if (io_bio->end_io)
@@ -8387,6 +8396,7 @@ static void __endio_write_update_ordered(struct inode *inode,
        btrfs_work_func_t func;
        u64 ordered_offset = offset;
        u64 ordered_bytes = bytes;
+       u64 last_offset;
        int ret;
 
        if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
@@ -8398,6 +8408,7 @@ static void __endio_write_update_ordered(struct inode *inode,
        }
 
 again:
+       last_offset = ordered_offset;
        ret = btrfs_dec_test_first_ordered_pending(inode, &ordered,
                                                   &ordered_offset,
                                                   ordered_bytes,
@@ -8408,6 +8419,12 @@ again:
        btrfs_init_work(&ordered->work, func, finish_ordered_fn, NULL, NULL);
        btrfs_queue_work(wq, &ordered->work);
 out_test:
+       /*
+        * If btrfs_dec_test_ordered_pending does not find any ordered extent
+        * in the range, we can exit.
+        */
+       if (ordered_offset == last_offset)
+               return;
        /*
         * our bio might span multiple ordered extents.  If we haven't
         * completed the accounting for the whole dio, go back and try again