btrfs: add truncate control struct
authorJosef Bacik <josef@toxicpanda.com>
Fri, 3 Dec 2021 22:18:09 +0000 (17:18 -0500)
committerDavid Sterba <dsterba@suse.com>
Fri, 7 Jan 2022 13:18:24 +0000 (14:18 +0100)
I'm going to be adding more arguments and counters to
btrfs_truncate_inode_items, so add a control struct to handle all of the
extra arguments to make it easier to follow.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/free-space-cache.c
fs/btrfs/inode-item.c
fs/btrfs/inode-item.h
fs/btrfs/inode.c
fs/btrfs/tree-log.c

index 28b9c63..a05dd3d 100644 (file)
@@ -291,6 +291,10 @@ int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans,
                                    struct btrfs_block_group *block_group,
                                    struct inode *vfs_inode)
 {
+       struct btrfs_truncate_control control = {
+               .new_size = 0,
+               .min_type = BTRFS_EXTENT_DATA_KEY,
+       };
        struct btrfs_inode *inode = BTRFS_I(vfs_inode);
        struct btrfs_root *root = inode->root;
        struct extent_state *cached_state = NULL;
@@ -333,8 +337,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, 0,
-                                        BTRFS_EXTENT_DATA_KEY, NULL);
+       ret = btrfs_truncate_inode_items(trans, root, inode, &control);
        unlock_extent_cached(&inode->io_tree, 0, (u64)-1, &cached_state);
        if (ret)
                goto fail;
index b795788..0946a39 100644 (file)
@@ -425,16 +425,8 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
  * @trans:             A transaction handle.
  * @root:              The root from which to remove items.
  * @inode:             The inode whose items we want to remove.
- * @new_size:          The new i_size for the inode. This is only applicable when
- *                     @min_type is BTRFS_EXTENT_DATA_KEY, must be 0 otherwise.
- * @min_type:          The minimum key type to remove. All keys with a type
- *                     greater than this value are removed and all keys with
- *                     this type are removed only if their offset is >= @new_size.
- * @extents_found:     Output parameter that will contain the number of file
- *                     extent items that were removed or adjusted to the new
- *                     inode i_size. The caller is responsible for initializing
- *                     the counter. Also, it can be NULL if the caller does not
- *                     need this counter.
+ * @control:           The btrfs_truncate_control to control how and what we
+ *                     are truncating.
  *
  * Remove all keys associated with the inode from the given root that have a key
  * with a type greater than or equals to @min_type. When @min_type has a value of
@@ -448,8 +440,7 @@ 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,
-                              u64 new_size, u32 min_type,
-                              u64 *extents_found)
+                              struct btrfs_truncate_control *control)
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct btrfs_path *path;
@@ -457,6 +448,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
        struct btrfs_file_extent_item *fi;
        struct btrfs_key key;
        struct btrfs_key found_key;
+       u64 new_size = control->new_size;
        u64 extent_num_bytes = 0;
        u64 extent_offset = 0;
        u64 item_end = 0;
@@ -472,7 +464,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
        bool be_nice = false;
        bool should_throttle = false;
 
-       BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY);
+       BUG_ON(new_size > 0 && control->min_type != BTRFS_EXTENT_DATA_KEY);
 
        /*
         * For shareable roots we want to back off from time to time, this turns
@@ -525,7 +517,7 @@ search_again:
                if (found_key.objectid != ino)
                        break;
 
-               if (found_type < min_type)
+               if (found_type < control->min_type)
                        break;
 
                item_end = found_key.offset;
@@ -548,7 +540,7 @@ search_again:
                        }
                        item_end--;
                }
-               if (found_type > min_type) {
+               if (found_type > control->min_type) {
                        del_item = 1;
                } else {
                        if (item_end < new_size)
@@ -563,8 +555,7 @@ search_again:
                if (found_type != BTRFS_EXTENT_DATA_KEY)
                        goto delete;
 
-               if (extents_found != NULL)
-                       (*extents_found)++;
+               control->extents_found++;
 
                if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
                        u64 num_dec;
index 4464d70..beefba1 100644 (file)
@@ -19,10 +19,24 @@ struct extent_buffer;
  */
 #define BTRFS_NEED_TRUNCATE_BLOCK              1
 
+struct btrfs_truncate_control {
+       /* IN: the size we're truncating to. */
+       u64 new_size;
+
+       /* OUT: the number of extents truncated. */
+       u64 extents_found;
+
+       /*
+        * IN: minimum key type to remove.  All key types with this type are
+        * removed only if their offset >= new_size.
+        */
+       u32 min_type;
+};
+
 int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root,
-                              struct btrfs_inode *inode, u64 new_size,
-                              u32 min_type, u64 *extents_found);
+                              struct btrfs_inode *inode,
+                              struct btrfs_truncate_control *control);
 int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root,
                           const char *name, int name_len,
index 7aabf41..9eb57d9 100644 (file)
@@ -5251,6 +5251,11 @@ void btrfs_evict_inode(struct inode *inode)
        btrfs_i_size_write(BTRFS_I(inode), 0);
 
        while (1) {
+               struct btrfs_truncate_control control = {
+                       .new_size = 0,
+                       .min_type = 0,
+               };
+
                trans = evict_refill_and_join(root, rsv);
                if (IS_ERR(trans))
                        goto free_rsv;
@@ -5258,7 +5263,7 @@ void btrfs_evict_inode(struct inode *inode)
                trans->block_rsv = rsv;
 
                ret = btrfs_truncate_inode_items(trans, root, BTRFS_I(inode),
-                                                0, 0, NULL);
+                                                &control);
                trans->block_rsv = &fs_info->trans_block_rsv;
                btrfs_end_transaction(trans);
                btrfs_btree_balance_dirty(fs_info);
@@ -8527,6 +8532,9 @@ out_noreserve:
 
 static int btrfs_truncate(struct inode *inode, bool skip_writeback)
 {
+       struct btrfs_truncate_control control = {
+               .min_type = BTRFS_EXTENT_DATA_KEY,
+       };
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_block_rsv *rsv;
@@ -8534,7 +8542,6 @@ static int btrfs_truncate(struct inode *inode, bool skip_writeback)
        struct btrfs_trans_handle *trans;
        u64 mask = fs_info->sectorsize - 1;
        u64 min_size = btrfs_calc_metadata_size(fs_info, 1);
-       u64 extents_found = 0;
 
        if (!skip_writeback) {
                ret = btrfs_wait_ordered_range(inode, inode->i_size & (~mask),
@@ -8599,6 +8606,7 @@ static int btrfs_truncate(struct inode *inode, bool skip_writeback)
                const u64 new_size = inode->i_size;
                const u64 lock_start = ALIGN_DOWN(new_size, fs_info->sectorsize);
 
+               control.new_size = new_size;
                lock_extent_bits(&BTRFS_I(inode)->io_tree, lock_start, (u64)-1,
                                 &cached_state);
                /*
@@ -8611,9 +8619,7 @@ static int btrfs_truncate(struct inode *inode, bool skip_writeback)
                                        (u64)-1, 0);
 
                ret = btrfs_truncate_inode_items(trans, root, BTRFS_I(inode),
-                                                inode->i_size,
-                                                BTRFS_EXTENT_DATA_KEY,
-                                                &extents_found);
+                                                &control);
                unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start,
                                     (u64)-1, &cached_state);
 
@@ -8692,7 +8698,7 @@ out:
         * between the old i_size and the new i_size, and there were no prealloc
         * extents beyond i_size to drop.
         */
-       if (extents_found > 0)
+       if (control.extents_found > 0)
                set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
 
        return ret;
index 64b42f4..c732a42 100644 (file)
@@ -4098,11 +4098,15 @@ static int truncate_inode_items(struct btrfs_trans_handle *trans,
                                struct btrfs_inode *inode,
                                u64 new_size, u32 min_type)
 {
+       struct btrfs_truncate_control control = {
+               .new_size = new_size,
+               .min_type = min_type,
+       };
        int ret;
 
        do {
                ret = btrfs_truncate_inode_items(trans, log_root, inode,
-                                                new_size, min_type, NULL);
+                                                &control);
        } while (ret == -EAGAIN);
 
        return ret;