]> git.baikalelectronics.ru Git - kernel.git/commitdiff
btrfs: only call inode_sub_bytes in truncate paths that care
authorJosef Bacik <josef@toxicpanda.com>
Fri, 3 Dec 2021 22:18:11 +0000 (17:18 -0500)
committerDavid Sterba <dsterba@suse.com>
Fri, 7 Jan 2022 13:18:24 +0000 (14:18 +0100)
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 <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

index fd469beb09859d084db454bb15f3e8e2e8ef2b9d..d2f4716f8485e314d5ffc3dcc981a0831ebc492e 100644 (file)
@@ -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);
index 7bb9f557ee3d66d98698c90242c759559b6a7f67..278d579f50bdffc788c02a6053f51b6f1c25b107 100644 (file)
@@ -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:
                /*
index 883e150f011af4a2df15ac9b2a65415010ca479a..7b5b455262cbf28ef894c6158f609a8352bc847a 100644 (file)
@@ -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.
index f653242e3c19583443fe04d9508b690c4a0205b2..38f974b16fc0803659c0373d1adef06e6895417e 100644 (file)
@@ -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,