--- Revision None +++ Revision 393961376566 @@ -0,0 +1,150 @@ +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index fc6401a..6016500 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -120,30 +120,26 @@ static int btrfs_dirty_inode(struct inode *inode); + + static void __endio_write_update_ordered(struct inode *inode, + u64 offset, u64 bytes, +- bool uptodate, bool cleanup); +- +-static inline void btrfs_endio_direct_write_update_ordered(struct inode *inode, +- u64 offset, +- u64 bytes, +- bool uptodate) +-{ +- return __endio_write_update_ordered(inode, offset, bytes, uptodate, false); +-} ++ bool uptodate); + + /* +- * Cleanup all submitted ordered extents in specified range to handle error +- * in cow_file_range() and run_delalloc_nocow(). +- * Compression handles error and ordered extent submission by itself, +- * so no need to call this function. ++ * Cleanup all submitted ordered extents in specified range to handle errors ++ * from the fill_dellaloc() callback. + * +- * NOTE: caller must ensure extent_clear_unlock_delalloc() in error handler +- * doesn't cover any range of submitted ordered extent. +- * Or we will double free metadata for submitted ordered extent. ++ * NOTE: caller must ensure that when an error happens, it can not call ++ * extent_clear_unlock_delalloc() to clear both the bits EXTENT_DO_ACCOUNTING ++ * and EXTENT_DELALLOC simultaneously, because that causes the reserved metadata ++ * to be released, which we want to happen only when finishing the ordered ++ * extent (btrfs_finish_ordered_io()). Also note that the caller of the ++ * fill_dealloc() callback already does proper cleanup for the first page of ++ * the range, that is, it invokes the callback writepage_end_io_hook() for the ++ * range of the first page. + */ + static inline void btrfs_cleanup_ordered_extents(struct inode *inode, + u64 offset, u64 bytes) + { +- return __endio_write_update_ordered(inode, offset, bytes, false, true); ++ return __endio_write_update_ordered(inode, offset + PAGE_SIZE, ++ bytes - PAGE_SIZE, false); + } + + #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS +@@ -958,7 +954,6 @@ static noinline int cow_file_range(struct inode *inode, + u64 disk_num_bytes; + u64 cur_alloc_size; + u64 blocksize = fs_info->sectorsize; +- u64 orig_start = start; + struct btrfs_key ins; + struct extent_map *em; + int ret = 0; +@@ -1100,7 +1095,6 @@ static noinline int cow_file_range(struct inode *inode, + EXTENT_DELALLOC | EXTENT_DEFRAG, + PAGE_UNLOCK | PAGE_CLEAR_DIRTY | + PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK); +- btrfs_cleanup_ordered_extents(inode, orig_start, end - orig_start + 1); + goto out; + } + +@@ -1526,8 +1520,6 @@ static noinline int run_delalloc_nocow(struct inode *inode, + PAGE_CLEAR_DIRTY | + PAGE_SET_WRITEBACK | + PAGE_END_WRITEBACK); +- if (ret) +- btrfs_cleanup_ordered_extents(inode, start, end - start + 1); + btrfs_free_path(path); + return ret; + } +@@ -1577,6 +1569,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, + ret = cow_file_range_async(inode, locked_page, start, end, + page_started, nr_written); + } ++ if (ret) ++ btrfs_cleanup_ordered_extents(inode, start, end - start + 1); + return ret; + } + +@@ -8176,7 +8170,7 @@ static void btrfs_endio_direct_read(struct bio *bio) + + static void __endio_write_update_ordered(struct inode *inode, + u64 offset, u64 bytes, +- bool uptodate, bool cleanup) ++ bool uptodate) + { + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_ordered_extent *ordered = NULL; +@@ -8194,16 +8188,6 @@ static void __endio_write_update_ordered(struct inode *inode, + func = btrfs_endio_write_helper; + } + +- /* +- * In cleanup case, the first page of the range will be handled +- * by end_extent_writepage() when called from __extent_writepage() +- * +- * So we must skip first page, or we will underflow ordered->bytes_left +- */ +- if (cleanup) { +- ordered_offset += PAGE_SIZE; +- ordered_bytes -= PAGE_SIZE; +- } + again: + ret = btrfs_dec_test_first_ordered_pending(inode, &ordered, + &ordered_offset, +@@ -8231,10 +8215,10 @@ static void btrfs_endio_direct_write(struct bio *bio) + struct btrfs_dio_private *dip = bio->bi_private; + struct bio *dio_bio = dip->dio_bio; + +- btrfs_endio_direct_write_update_ordered(dip->inode, +- dip->logical_offset, +- dip->bytes, +- !bio->bi_error); ++ __endio_write_update_ordered(dip->inode, ++ dip->logical_offset, ++ dip->bytes, ++ !bio->bi_error); + + kfree(dip); + +@@ -8595,10 +8579,10 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, + io_bio = NULL; + } else { + if (write) +- btrfs_endio_direct_write_update_ordered(inode, ++ __endio_write_update_ordered(inode, + file_offset, + dio_bio->bi_iter.bi_size, +- 0); ++ false); + else + unlock_extent(&BTRFS_I(inode)->io_tree, file_offset, + file_offset + dio_bio->bi_iter.bi_size - 1); +@@ -8733,11 +8717,11 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) + */ + if (dio_data.unsubmitted_oe_range_start < + dio_data.unsubmitted_oe_range_end) +- btrfs_endio_direct_write_update_ordered(inode, ++ __endio_write_update_ordered(inode, + dio_data.unsubmitted_oe_range_start, + dio_data.unsubmitted_oe_range_end - + dio_data.unsubmitted_oe_range_start, +- 0); ++ false); + } else if (ret >= 0 && (size_t)ret < count) + btrfs_delalloc_release_space(inode, offset, + count - (size_t)ret);