From 71d18b53540f106a394cb35ed93b487b76678b06 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 3 Dec 2021 17:18:15 -0500 Subject: [PATCH] btrfs: add inode to truncate control In the future we're going to want to use btrfs_truncate_inode_items without looking up the associated inode. In order to accommodate this add the inode to btrfs_truncate_control and handle the case where control->inode is NULL appropriately. This is fairly straightforward, we simply need to add a helper for the trace points, as the file extent map update is controlled by a flag on btrfs_truncate_control. Reviewed-by: Filipe Manana Signed-off-by: Josef Bacik Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/free-space-cache.c | 3 ++- fs/btrfs/inode-item.c | 32 +++++++++++++++++++++----------- fs/btrfs/inode-item.h | 7 ++++++- fs/btrfs/inode.c | 8 ++++---- fs/btrfs/tree-log.c | 3 +-- 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index c2a34179bddc..01a408db5683 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -292,6 +292,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, struct inode *vfs_inode) { struct btrfs_truncate_control control = { + .inode = BTRFS_I(vfs_inode), .new_size = 0, .ino = btrfs_ino(BTRFS_I(vfs_inode)), .min_type = BTRFS_EXTENT_DATA_KEY, @@ -339,7 +340,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, * We skip the throttling logic for free space cache inodes, so we don't * need to check for -EAGAIN. */ - ret = btrfs_truncate_inode_items(trans, root, inode, &control); + ret = btrfs_truncate_inode_items(trans, root, &control); inode_sub_bytes(&inode->vfs_inode, control.sub_bytes); btrfs_inode_safe_disk_i_size_write(inode, control.last_size); diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c index a24ed49daa4e..44db08e46a49 100644 --- a/fs/btrfs/inode-item.c +++ b/fs/btrfs/inode-item.c @@ -419,6 +419,20 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root return ret; } +static inline void btrfs_trace_truncate(struct btrfs_inode *inode, + struct extent_buffer *leaf, + struct btrfs_file_extent_item *fi, + u64 offset, int extent_type, int slot) +{ + if (!inode) + return; + if (extent_type == BTRFS_FILE_EXTENT_INLINE) + trace_btrfs_truncate_show_fi_inline(inode, leaf, fi, slot, + offset); + else + trace_btrfs_truncate_show_fi_regular(inode, leaf, fi, offset); +} + /* * Remove inode items from a given root. * @@ -439,7 +453,6 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root */ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_inode *inode, struct btrfs_truncate_control *control) { struct btrfs_fs_info *fs_info = root->fs_info; @@ -462,6 +475,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, bool be_nice = false; bool should_throttle = false; + ASSERT(control->inode || !control->clear_extent_range); BUG_ON(new_size > 0 && control->min_type != BTRFS_EXTENT_DATA_KEY); control->last_size = new_size; @@ -526,19 +540,15 @@ search_again: fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); extent_type = btrfs_file_extent_type(leaf, fi); - if (extent_type != BTRFS_FILE_EXTENT_INLINE) { + if (extent_type != BTRFS_FILE_EXTENT_INLINE) item_end += btrfs_file_extent_num_bytes(leaf, fi); - - trace_btrfs_truncate_show_fi_regular( - inode, leaf, fi, found_key.offset); - } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { + else if (extent_type == BTRFS_FILE_EXTENT_INLINE) item_end += btrfs_file_extent_ram_bytes(leaf, fi); - trace_btrfs_truncate_show_fi_inline( - inode, leaf, fi, path->slots[0], - found_key.offset); - } + btrfs_trace_truncate(control->inode, leaf, fi, + found_key.offset, extent_type, + path->slots[0]); item_end--; } if (found_type > control->min_type) { @@ -628,7 +638,7 @@ delete: * normal truncate path. */ if (control->clear_extent_range) { - ret = btrfs_inode_clear_file_extent_range(inode, + ret = btrfs_inode_clear_file_extent_range(control->inode, clear_start, clear_len); if (ret) { btrfs_abort_transaction(trans, ret); diff --git a/fs/btrfs/inode-item.h b/fs/btrfs/inode-item.h index b0dc14efde30..a8fc16d0147f 100644 --- a/fs/btrfs/inode-item.h +++ b/fs/btrfs/inode-item.h @@ -20,6 +20,12 @@ struct extent_buffer; #define BTRFS_NEED_TRUNCATE_BLOCK 1 struct btrfs_truncate_control { + /* + * IN: the inode we're operating on, this can be NULL if + * ->clear_extent_range is false. + */ + struct btrfs_inode *inode; + /* IN: the size we're truncating to. */ u64 new_size; @@ -56,7 +62,6 @@ struct btrfs_truncate_control { int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_inode *inode, struct btrfs_truncate_control *control); int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ea1223c53a10..a88130c7782e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5252,6 +5252,7 @@ void btrfs_evict_inode(struct inode *inode) while (1) { struct btrfs_truncate_control control = { + .inode = BTRFS_I(inode), .ino = btrfs_ino(BTRFS_I(inode)), .new_size = 0, .min_type = 0, @@ -5263,8 +5264,7 @@ void btrfs_evict_inode(struct inode *inode) trans->block_rsv = rsv; - ret = btrfs_truncate_inode_items(trans, root, BTRFS_I(inode), - &control); + ret = btrfs_truncate_inode_items(trans, root, &control); trans->block_rsv = &fs_info->trans_block_rsv; btrfs_end_transaction(trans); btrfs_btree_balance_dirty(fs_info); @@ -8534,6 +8534,7 @@ out_noreserve: static int btrfs_truncate(struct inode *inode, bool skip_writeback) { struct btrfs_truncate_control control = { + .inode = BTRFS_I(inode), .ino = btrfs_ino(BTRFS_I(inode)), .min_type = BTRFS_EXTENT_DATA_KEY, .clear_extent_range = true, @@ -8621,8 +8622,7 @@ static int btrfs_truncate(struct inode *inode, bool skip_writeback) ALIGN(new_size, fs_info->sectorsize), (u64)-1, 0); - ret = btrfs_truncate_inode_items(trans, root, BTRFS_I(inode), - &control); + ret = btrfs_truncate_inode_items(trans, root, &control); inode_sub_bytes(inode, control.sub_bytes); btrfs_inode_safe_disk_i_size_write(BTRFS_I(inode), control.last_size); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 8c099cd40956..2c87626561aa 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4107,8 +4107,7 @@ static int truncate_inode_items(struct btrfs_trans_handle *trans, int ret; do { - ret = btrfs_truncate_inode_items(trans, log_root, inode, - &control); + ret = btrfs_truncate_inode_items(trans, log_root, &control); } while (ret == -EAGAIN); return ret;