summaryrefslogtreecommitdiff
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2022-10-11 15:17:05 +0300
committerDavid Sterba <dsterba@suse.com>2022-12-05 20:00:39 +0300
commit56f5c19920d09bbf91efcf80e6ba301923400f4c (patch)
tree5d9935634bca7126acf42c190760d71bb95233d0 /fs/btrfs/backref.c
parentb629685803bc0cefbbd29240ea28d57d8a17bcbc (diff)
downloadlinux-56f5c19920d09bbf91efcf80e6ba301923400f4c.tar.xz
btrfs: remove useless logic when finding parent nodes
At find_parent_nodes(), at its last step, when iterating over all direct references, we are checking if we have a share context and if we have a reference with a different root from the one in the share context. However that logic is pointless because of two reasons: 1) After the previous patch in the series (subject "btrfs: remove roots ulist when checking data extent sharedness"), the roots argument is always NULL when using a share check context (struct share_check), so this code is never triggered; 2) Even before that previous patch, we could not hit this code because if we had a reference with a root different from the one in our share context, then we would have exited earlier when doing either of the following: - Adding a second direct ref to the direct refs red black tree resulted in extent_is_shared() returning true when called from add_direct_ref() -> add_prelim_ref(), after processing delayed references or while processing references in the extent tree; - When adding a second reference to the indirect refs red black tree (same as above, extent_is_shared() returns true); - If we only have one indirect reference and no direct references, then when resolving it at resolve_indirect_refs() we immediately return that the target extent is shared, therefore never reaching that loop that iterates over all direct references at find_parent_nodes(); - If we have 1 indirect reference and 1 direct reference, then we also exit early because extent_is_shared() ends up returning true when called through add_prelim_ref() (by add_direct_ref() or add_indirect_ref()) or add_delayed_refs(). Same applies as when having a combination of direct, indirect and indirect with missing key references. This logic had been obsoleted since commit 3ec4d3238ab165 ("btrfs: allow backref search checks for shared extents"), which introduced the early exits in case an extent is shared. So just remove that logic, and assert at find_parent_nodes() that when we have a share context we don't have a roots ulist and that we haven't found the extent to be directly shared after processing delayed references and all references from the extent tree. Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 4d8573fa75b4..22ab13821ada 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -1219,6 +1219,10 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
.indirect_missing_keys = PREFTREE_INIT
};
+ /* Roots ulist is not needed when using a sharedness check context. */
+ if (sc)
+ ASSERT(roots == NULL);
+
key.objectid = bytenr;
key.offset = (u64)-1;
if (btrfs_fs_incompat(fs_info, SKINNY_METADATA))
@@ -1310,6 +1314,20 @@ again:
}
}
+ /*
+ * If we have a share context and we reached here, it means the extent
+ * is not directly shared (no multiple reference items for it),
+ * otherwise we would have exited earlier with a return value of
+ * BACKREF_FOUND_SHARED after processing delayed references or while
+ * processing inline or keyed references from the extent tree.
+ * The extent may however be indirectly shared through shared subtrees
+ * as a result from creating snapshots, so we determine below what is
+ * its parent node, in case we are dealing with a metadata extent, or
+ * what's the leaf (or leaves), from a fs tree, that has a file extent
+ * item pointing to it in case we are dealing with a data extent.
+ */
+ ASSERT(extent_is_shared(sc) == 0);
+
btrfs_release_path(path);
ret = add_missing_keys(fs_info, &preftrees, path->skip_locking == 0);
@@ -1347,11 +1365,6 @@ again:
* and would retain their original ref->count < 0.
*/
if (roots && ref->count && ref->root_id && ref->parent == 0) {
- if (sc && ref->root_id != sc->root_objectid) {
- ret = BACKREF_FOUND_SHARED;
- goto out;
- }
-
/* no parent == root of tree */
ret = ulist_add(roots, ref->root_id, 0, GFP_NOFS);
if (ret < 0)