]> git.baikalelectronics.ru Git - kernel.git/commitdiff
btrfs: move open coded extent map tree deletion out of inode eviction
authorFilipe Manana <fdmanana@suse.com>
Mon, 19 Sep 2022 14:06:32 +0000 (15:06 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 29 Sep 2022 15:08:30 +0000 (17:08 +0200)
Move the loop that removes all the extent maps from the inode's extent
map tree during inode eviction out of inode.c and into extent_map.c, to
btrfs_drop_extent_map_range(). Anything manipulating extent maps or the
extent map tree should be in extent_map.c.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent_map.c
fs/btrfs/inode.c

index 28c5e0243adc7a69524471730b7919dc8cf27b34..7376c0aa2bca81f6bbb5147fa44b177719fc4da7 100644 (file)
@@ -660,6 +660,29 @@ int btrfs_add_extent_mapping(struct btrfs_fs_info *fs_info,
        return ret;
 }
 
+/*
+ * Drop all extent maps from a tree in the fastest possible way, rescheduling
+ * if needed. This avoids searching the tree, from the root down to the first
+ * extent map, before each deletion.
+ */
+static void drop_all_extent_maps_fast(struct extent_map_tree *tree)
+{
+       write_lock(&tree->lock);
+       while (!RB_EMPTY_ROOT(&tree->map.rb_root)) {
+               struct extent_map *em;
+               struct rb_node *node;
+
+               node = rb_first_cached(&tree->map);
+               em = rb_entry(node, struct extent_map, rb_node);
+               clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+               clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
+               remove_extent_mapping(tree, em);
+               free_extent_map(em);
+               cond_resched_rwlock_write(&tree->lock);
+       }
+       write_unlock(&tree->lock);
+}
+
 /*
  * Drop all extent maps in a given range.
  *
@@ -685,6 +708,10 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
 
        WARN_ON(end < start);
        if (end == (u64)-1) {
+               if (start == 0 && !skip_pinned) {
+                       drop_all_extent_maps_fast(em_tree);
+                       return;
+               }
                len = (u64)-1;
                testend = false;
        }
index 491c2b7f48bfd88f28ac6d38d3fb699fcefca86b..cbf920eba69ce69de46e08a29cba9b5f07c8675e 100644 (file)
@@ -5289,25 +5289,12 @@ static int btrfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentr
 static void evict_inode_truncate_pages(struct inode *inode)
 {
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
-       struct extent_map_tree *map_tree = &BTRFS_I(inode)->extent_tree;
        struct rb_node *node;
 
        ASSERT(inode->i_state & I_FREEING);
        truncate_inode_pages_final(&inode->i_data);
 
-       write_lock(&map_tree->lock);
-       while (!RB_EMPTY_ROOT(&map_tree->map.rb_root)) {
-               struct extent_map *em;
-
-               node = rb_first_cached(&map_tree->map);
-               em = rb_entry(node, struct extent_map, rb_node);
-               clear_bit(EXTENT_FLAG_PINNED, &em->flags);
-               clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
-               remove_extent_mapping(map_tree, em);
-               free_extent_map(em);
-               cond_resched_rwlock_write(&map_tree->lock);
-       }
-       write_unlock(&map_tree->lock);
+       btrfs_drop_extent_map_range(BTRFS_I(inode), 0, (u64)-1, false);
 
        /*
         * Keep looping until we have no more ranges in the io tree.