No title Revision 393961376566 (Thu Mar 02 2017 at 17:27) - Diff Link to this snippet: https://friendpaste.com/4zct2A5XQoSVJyMFBU2UkA Embed: manni perldoc borland colorful default murphy trac fruity autumn bw emacs pastie friendly Show line numbers Wrap lines 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.cindex 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);