diff mbox series

[5.4,11/32] btrfs: backref, only search backref entries from leaves of the same root

Message ID 20210205140652.826044858@linuxfoundation.org
State New
Headers show
Series None | expand

Commit Message

Greg KH Feb. 5, 2021, 2:07 p.m. UTC
From: ethanwu <ethanwu@synology.com>

commit cfc0eed0ec89db7c4a8d461174cabfaa4a0912c7 upstream.

We could have some nodes/leaves in subvolume whose owner are not the
that subvolume. In this way, when we resolve normal backrefs of that
subvolume, we should avoid collecting those references from these blocks.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: ethanwu <ethanwu@synology.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/btrfs/backref.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
diff mbox series

Patch

--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -443,11 +443,14 @@  static int add_all_parents(struct btrfs_
 	 *    slot == nritems.
 	 * 2. We are searching for normal backref but bytenr of this leaf
 	 *    matches shared data backref
+	 * 3. The leaf owner is not equal to the root we are searching
+	 *
 	 * For these cases, go to the next leaf before we continue.
 	 */
 	eb = path->nodes[0];
 	if (path->slots[0] >= btrfs_header_nritems(eb) ||
-	    is_shared_data_backref(preftrees, eb->start)) {
+	    is_shared_data_backref(preftrees, eb->start) ||
+	    ref->root_id != btrfs_header_owner(eb)) {
 		if (time_seq == SEQ_LAST)
 			ret = btrfs_next_leaf(root, path);
 		else
@@ -466,9 +469,12 @@  static int add_all_parents(struct btrfs_
 
 		/*
 		 * We are searching for normal backref but bytenr of this leaf
-		 * matches shared data backref.
+		 * matches shared data backref, OR
+		 * the leaf owner is not equal to the root we are searching for
 		 */
-		if (slot == 0 && is_shared_data_backref(preftrees, eb->start)) {
+		if (slot == 0 &&
+		    (is_shared_data_backref(preftrees, eb->start) ||
+		     ref->root_id != btrfs_header_owner(eb))) {
 			if (time_seq == SEQ_LAST)
 				ret = btrfs_next_leaf(root, path);
 			else