diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index ae496e41692ae9450244bb9a188e415d522d6069..176a61967a8ad1606013655dcdb3a1edf8938d56 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3119,7 +3119,7 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, int nr); int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, - struct extent_state **cached_state); + struct extent_state **cached_state, int dedupe); int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, struct btrfs_root *new_root, struct btrfs_root *parent_root, diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index f12a0f90d6e40fb8ed275ac906dd56a67d0e420e..e26e3feca500fe42b21a9505ea72eff1e245e17a 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1730,7 +1730,7 @@ STATIC u64 find_lock_delalloc_range(struct inode *inode, } void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, - struct page *locked_page, + u64 delalloc_end, struct page *locked_page, unsigned clear_bits, unsigned long page_ops) { diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 28cd88fccc7eaa0e6776229cb00e6e336799263d..60536f3bf434db6c7a010804f24a54d29ce03865 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -413,7 +413,7 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset, void extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end); void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end); void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, - struct page *locked_page, + u64 delalloc_end, struct page *locked_page, unsigned bits_to_clear, unsigned long page_ops); struct bio * diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index fea31a4a6e36844d97a53c80a7f442c166e82b60..f1f1ae6ff08bcd8ff6bf9fe149590fe7abc592a7 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -503,7 +503,7 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, end_of_last_block = start_pos + num_bytes - 1; err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, - cached); + cached, 0); if (err) return err; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e6811c42e41ef34d27119ee5420d4c6653df8519..8c63752b0a962c7cd77376f7c998a9328037e27e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -560,8 +560,9 @@ static noinline void compress_file_range(struct inode *inode, * we don't need to create any more async work items. * Unlock and free up our temp pages. */ - extent_clear_unlock_delalloc(inode, start, end, NULL, - clear_flags, PAGE_UNLOCK | + extent_clear_unlock_delalloc(inode, start, end, end, + NULL, clear_flags, + PAGE_UNLOCK | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | page_error_op | @@ -835,6 +836,8 @@ static noinline void submit_compressed_extents(struct inode *inode, * clear dirty, set writeback and unlock the pages. */ extent_clear_unlock_delalloc(inode, async_extent->start, + async_extent->start + + async_extent->ram_size - 1, async_extent->start + async_extent->ram_size - 1, NULL, EXTENT_LOCKED | EXTENT_DELALLOC, @@ -856,7 +859,8 @@ static noinline void submit_compressed_extents(struct inode *inode, tree->ops->writepage_end_io_hook(p, start, end, NULL, 0); p->mapping = NULL; - extent_clear_unlock_delalloc(inode, start, end, NULL, 0, + extent_clear_unlock_delalloc(inode, start, end, end, + NULL, 0, PAGE_END_WRITEBACK | PAGE_SET_ERROR); free_async_extent_pages(async_extent); @@ -871,6 +875,8 @@ static noinline void submit_compressed_extents(struct inode *inode, btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); out_free: extent_clear_unlock_delalloc(inode, async_extent->start, + async_extent->start + + async_extent->ram_size - 1, async_extent->start + async_extent->ram_size - 1, NULL, EXTENT_LOCKED | EXTENT_DELALLOC | @@ -966,7 +972,8 @@ static noinline int cow_file_range(struct inode *inode, ret = cow_file_range_inline(root, inode, start, end, 0, 0, NULL); if (ret == 0) { - extent_clear_unlock_delalloc(inode, start, end, NULL, + extent_clear_unlock_delalloc(inode, start, end, + delalloc_end, NULL, EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DEFRAG, PAGE_UNLOCK | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | @@ -1062,7 +1069,8 @@ static noinline int cow_file_range(struct inode *inode, op |= PAGE_SET_PRIVATE2; extent_clear_unlock_delalloc(inode, start, - start + ram_size - 1, locked_page, + start + ram_size - 1, + delalloc_end, locked_page, EXTENT_LOCKED | EXTENT_DELALLOC, op); disk_num_bytes -= cur_alloc_size; @@ -1079,7 +1087,8 @@ static noinline int cow_file_range(struct inode *inode, btrfs_dec_block_group_reservations(root->fs_info, ins.objectid); btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); out_unlock: - extent_clear_unlock_delalloc(inode, start, end, locked_page, + extent_clear_unlock_delalloc(inode, start, end, delalloc_end, + locked_page, EXTENT_LOCKED | EXTENT_DO_ACCOUNTING | EXTENT_DELALLOC | EXTENT_DEFRAG, PAGE_UNLOCK | PAGE_CLEAR_DIRTY | @@ -1258,7 +1267,8 @@ static noinline int run_delalloc_nocow(struct inode *inode, path = btrfs_alloc_path(); if (!path) { - extent_clear_unlock_delalloc(inode, start, end, locked_page, + extent_clear_unlock_delalloc(inode, start, end, end, + locked_page, EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, PAGE_UNLOCK | @@ -1276,7 +1286,8 @@ static noinline int run_delalloc_nocow(struct inode *inode, trans = btrfs_join_transaction(root); if (IS_ERR(trans)) { - extent_clear_unlock_delalloc(inode, start, end, locked_page, + extent_clear_unlock_delalloc(inode, start, end, end, + locked_page, EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, PAGE_UNLOCK | @@ -1490,7 +1501,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, } extent_clear_unlock_delalloc(inode, cur_offset, - cur_offset + num_bytes - 1, + cur_offset + num_bytes - 1, end, locked_page, EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_CLEAR_DATA_RESV, @@ -1522,7 +1533,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, ret = err; if (ret && cur_offset < end) - extent_clear_unlock_delalloc(inode, cur_offset, end, + extent_clear_unlock_delalloc(inode, cur_offset, end, end, locked_page, EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, PAGE_UNLOCK | @@ -1988,7 +1999,7 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, } int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, - struct extent_state **cached_state) + struct extent_state **cached_state, int dedupe) { WARN_ON((end & (PAGE_SIZE - 1)) == 0); return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, @@ -2052,7 +2063,8 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) goto out; } - btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state); + btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state, + 0); ClearPageChecked(page); set_page_dirty(page); out: @@ -4757,7 +4769,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, 0, 0, &cached_state, GFP_NOFS); ret = btrfs_set_extent_delalloc(inode, block_start, block_end, - &cached_state); + &cached_state, 0); if (ret) { unlock_extent_cached(io_tree, block_start, block_end, &cached_state, GFP_NOFS); @@ -9054,7 +9066,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) 0, 0, &cached_state, GFP_NOFS); ret = btrfs_set_extent_delalloc(inode, page_start, end, - &cached_state); + &cached_state, 0); if (ret) { unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS); diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index c0c13dc6fe1286673982dfa78d9930cb219927dd..7d53f2acb09ef6156324b061e74eb3acaa337acc 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3203,7 +3203,7 @@ static int relocate_file_extent_cluster(struct inode *inode, nr++; } - btrfs_set_extent_delalloc(inode, page_start, page_end, NULL); + btrfs_set_extent_delalloc(inode, page_start, page_end, NULL, 0); set_page_dirty(page); unlock_extent(&BTRFS_I(inode)->io_tree, diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c index 9f72aeda922041f9bec7de131be16817f38abc19..0bf46808ce8f2d53cdf32820f02da5165258a5f4 100644 --- a/fs/btrfs/tests/inode-tests.c +++ b/fs/btrfs/tests/inode-tests.c @@ -968,7 +968,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) /* [BTRFS_MAX_EXTENT_SIZE] */ BTRFS_I(inode)->outstanding_extents++; ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, - NULL); + NULL, 0); if (ret) { test_msg("btrfs_set_extent_delalloc returned %d\n", ret); goto out; @@ -984,7 +984,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) BTRFS_I(inode)->outstanding_extents++; ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, BTRFS_MAX_EXTENT_SIZE + sectorsize - 1, - NULL); + NULL, 0); if (ret) { test_msg("btrfs_set_extent_delalloc returned %d\n", ret); goto out; @@ -1019,7 +1019,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1, - NULL); + NULL, 0); if (ret) { test_msg("btrfs_set_extent_delalloc returned %d\n", ret); goto out; @@ -1042,7 +1042,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize, (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1, - NULL); + NULL, 0); if (ret) { test_msg("btrfs_set_extent_delalloc returned %d\n", ret); goto out; @@ -1060,7 +1060,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) BTRFS_I(inode)->outstanding_extents++; ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE + sectorsize, - BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL); + BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0); if (ret) { test_msg("btrfs_set_extent_delalloc returned %d\n", ret); goto out; @@ -1097,7 +1097,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) BTRFS_I(inode)->outstanding_extents++; ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE + sectorsize, - BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL); + BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0); if (ret) { test_msg("btrfs_set_extent_delalloc returned %d\n", ret); goto out;