From 462b728ea83fa85f1c0d2b79efb6187745444ce5 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 3 Dec 2021 17:18:11 -0500 Subject: [PATCH] btrfs: only call inode_sub_bytes in truncate paths that care We currently have a bunch of awkward checks to make sure we only update the inode i_bytes if we're truncating the real inode. Instead keep track of the number of bytes we need to sub in the btrfs_truncate_control, and then do the appropriate adjustment in the truncate paths that care. Reviewed-by: Filipe Manana Signed-off-by: Josef Bacik Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/free-space-cache.c | 1 + fs/btrfs/inode-item.c | 19 ++++++------------- fs/btrfs/inode-item.h | 3 +++ fs/btrfs/inode.c | 1 + 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index fd469beb0985..d2f4716f8485 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -339,6 +339,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, */ ret = btrfs_truncate_inode_items(trans, root, inode, &control); + inode_sub_bytes(&inode->vfs_inode, control.sub_bytes); btrfs_inode_safe_disk_i_size_write(inode, control.last_size); unlock_extent_cached(&inode->io_tree, 0, (u64)-1, &cached_state); diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c index 7bb9f557ee3d..278d579f50bd 100644 --- a/fs/btrfs/inode-item.c +++ b/fs/btrfs/inode-item.c @@ -466,6 +466,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, BUG_ON(new_size > 0 && control->min_type != BTRFS_EXTENT_DATA_KEY); control->last_size = new_size; + control->sub_bytes = 0; /* * For shareable roots we want to back off from time to time, this turns @@ -574,10 +575,8 @@ search_again: btrfs_set_file_extent_num_bytes(leaf, fi, extent_num_bytes); num_dec = (orig_num_bytes - extent_num_bytes); - if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state) && - extent_start != 0) - inode_sub_bytes(&inode->vfs_inode, - num_dec); + if (extent_start != 0) + control->sub_bytes += num_dec; btrfs_mark_buffer_dirty(leaf); } else { extent_num_bytes = @@ -587,12 +586,8 @@ search_again: /* FIXME blocksize != 4096 */ num_dec = btrfs_file_extent_num_bytes(leaf, fi); - if (extent_start != 0) { - if (test_bit(BTRFS_ROOT_SHAREABLE, - &root->state)) - inode_sub_bytes(&inode->vfs_inode, - num_dec); - } + if (extent_start != 0) + control->sub_bytes += num_dec; } clear_len = num_dec; } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { @@ -625,9 +620,7 @@ search_again: clear_len = fs_info->sectorsize; } - if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) - inode_sub_bytes(&inode->vfs_inode, - item_end + 1 - new_size); + control->sub_bytes += item_end + 1 - new_size; } delete: /* diff --git a/fs/btrfs/inode-item.h b/fs/btrfs/inode-item.h index 883e150f011a..7b5b455262cb 100644 --- a/fs/btrfs/inode-item.h +++ b/fs/btrfs/inode-item.h @@ -29,6 +29,9 @@ struct btrfs_truncate_control { /* OUT: the last size we truncated this inode to. */ u64 last_size; + /* OUT: the number of bytes to sub from this inode. */ + u64 sub_bytes; + /* * IN: minimum key type to remove. All key types with this type are * removed only if their offset >= new_size. diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f653242e3c19..38f974b16fc0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8621,6 +8621,7 @@ static int btrfs_truncate(struct inode *inode, bool skip_writeback) ret = btrfs_truncate_inode_items(trans, root, BTRFS_I(inode), &control); + inode_sub_bytes(inode, control.sub_bytes); btrfs_inode_safe_disk_i_size_write(BTRFS_I(inode), control.last_size); unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, -- 2.11.0