OSDN Git Service

btrfs: remove outdated logic from overwrite_item() and add assertion
authorFilipe Manana <fdmanana@suse.com>
Mon, 21 Nov 2022 10:23:24 +0000 (10:23 +0000)
committerDavid Sterba <dsterba@suse.com>
Mon, 5 Dec 2022 17:00:59 +0000 (18:00 +0100)
As of commit 193df6245704 ("btrfs: search for last logged dir index if
it's not cached in the inode"), the overwrite_item() function is always
called for a root that is from a fs/subvolume tree. In other words, now
it's only used during log replay to modify a fs/subvolume tree. Therefore
we can remove the logic that checks if we are dealing with a log tree at
overwrite_item().

So remove that logic, replacing it with an assertion and document that if
we ever need to support a log root there, we will need to clone the leaf
from the fs/subvolume tree and then release it before modifying the log
tree, which is needed to avoid a potential deadlock, similar to the one
recently fixed by a patch with the subject:

  "btrfs: do not modify log tree while holding a leaf from fs tree locked"

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

index bcc8717..a3c43f0 100644 (file)
@@ -391,11 +391,16 @@ static int overwrite_item(struct btrfs_trans_handle *trans,
        int save_old_i_size = 0;
        unsigned long src_ptr;
        unsigned long dst_ptr;
-       int overwrite_root = 0;
        bool inode_item = key->type == BTRFS_INODE_ITEM_KEY;
 
-       if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
-               overwrite_root = 1;
+       /*
+        * This is only used during log replay, so the root is always from a
+        * fs/subvolume tree. In case we ever need to support a log root, then
+        * we'll have to clone the leaf in the path, release the path and use
+        * the leaf before writing into the log tree. See the comments at
+        * copy_items() for more details.
+        */
+       ASSERT(root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID);
 
        item_size = btrfs_item_size(eb, slot);
        src_ptr = btrfs_item_ptr_offset(eb, slot);
@@ -548,8 +553,7 @@ insert:
                        goto no_copy;
                }
 
-               if (overwrite_root &&
-                   S_ISDIR(btrfs_inode_mode(eb, src_item)) &&
+               if (S_ISDIR(btrfs_inode_mode(eb, src_item)) &&
                    S_ISDIR(btrfs_inode_mode(path->nodes[0], dst_item))) {
                        save_old_i_size = 1;
                        saved_i_size = btrfs_inode_size(path->nodes[0],