All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Josef Bacik <josef@toxicpanda.com>,
	Johannes Thumshirn <johannes.thumshirn@wdc.com>,
	ethanwu <ethanwu@synology.com>, David Sterba <dsterba@suse.com>
Subject: [PATCH 5.4 10/32] btrfs: backref, dont add refs from shared block when resolving normal backref
Date: Fri,  5 Feb 2021 15:07:25 +0100	[thread overview]
Message-ID: <20210205140652.781147189@linuxfoundation.org> (raw)
In-Reply-To: <20210205140652.348864025@linuxfoundation.org>

From: ethanwu <ethanwu@synology.com>

commit ed58f2e66e849c34826083e5a6c1b506ee8a4d8e upstream.

All references from the block of SHARED_DATA_REF belong to that shared
block backref.

For example:

  item 11 key (40831553536 EXTENT_ITEM 4194304) itemoff 15460 itemsize 95
      extent refs 24 gen 7302 flags DATA
      extent data backref root 257 objectid 260 offset 65536 count 5
      extent data backref root 258 objectid 265 offset 0 count 9
      shared data backref parent 394985472 count 10

Block 394985472 might be leaf from root 257, and the item obejctid and
(file_pos - file_extent_item::offset) in that leaf just happens to be
260 and 65536 which is equal to the first extent data backref entry.

Before this patch, when we resolve backref:

  root 257 objectid 260 offset 65536

we will add those refs in block 394985472 and wrongly treat those as the
refs we want.

Fix this by checking if the leaf we are processing is shared data
backref, if so, just skip this leaf.

Shared data refs added into preftrees.direct have all entry value = 0
(root_id = 0, key = NULL, level = 0) except parent entry.

Other refs from indirect tree will have key value and root id != 0, and
these values won't be changed when their parent is resolved and added to
preftrees.direct. Therefore, we could reuse the preftrees.direct and
search ref with all values = 0 except parent is set to avoid getting
those resolved refs block.

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 |   61 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 52 insertions(+), 9 deletions(-)

--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -386,8 +386,34 @@ static int add_indirect_ref(const struct
 			      wanted_disk_byte, count, sc, gfp_mask);
 }
 
+static int is_shared_data_backref(struct preftrees *preftrees, u64 bytenr)
+{
+	struct rb_node **p = &preftrees->direct.root.rb_root.rb_node;
+	struct rb_node *parent = NULL;
+	struct prelim_ref *ref = NULL;
+	struct prelim_ref target = {0};
+	int result;
+
+	target.parent = bytenr;
+
+	while (*p) {
+		parent = *p;
+		ref = rb_entry(parent, struct prelim_ref, rbnode);
+		result = prelim_ref_compare(ref, &target);
+
+		if (result < 0)
+			p = &(*p)->rb_left;
+		else if (result > 0)
+			p = &(*p)->rb_right;
+		else
+			return 1;
+	}
+	return 0;
+}
+
 static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
-			   struct ulist *parents, struct prelim_ref *ref,
+			   struct ulist *parents,
+			   struct preftrees *preftrees, struct prelim_ref *ref,
 			   int level, u64 time_seq, const u64 *extent_item_pos,
 			   u64 total_refs, bool ignore_offset)
 {
@@ -412,11 +438,16 @@ static int add_all_parents(struct btrfs_
 	}
 
 	/*
-	 * We normally enter this function with the path already pointing to
-	 * the first item to check. But sometimes, we may enter it with
-	 * slot==nritems. In that case, go to the next leaf before we continue.
+	 * 1. We normally enter this function with the path already pointing to
+	 *    the first item to check. But sometimes, we may enter it with
+	 *    slot == nritems.
+	 * 2. We are searching for normal backref but bytenr of this leaf
+	 *    matches shared data backref
+	 * For these cases, go to the next leaf before we continue.
 	 */
-	if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
+	eb = path->nodes[0];
+	if (path->slots[0] >= btrfs_header_nritems(eb) ||
+	    is_shared_data_backref(preftrees, eb->start)) {
 		if (time_seq == SEQ_LAST)
 			ret = btrfs_next_leaf(root, path);
 		else
@@ -433,6 +464,17 @@ static int add_all_parents(struct btrfs_
 		    key.type != BTRFS_EXTENT_DATA_KEY)
 			break;
 
+		/*
+		 * We are searching for normal backref but bytenr of this leaf
+		 * matches shared data backref.
+		 */
+		if (slot == 0 && is_shared_data_backref(preftrees, eb->start)) {
+			if (time_seq == SEQ_LAST)
+				ret = btrfs_next_leaf(root, path);
+			else
+				ret = btrfs_next_old_leaf(root, path, time_seq);
+			continue;
+		}
 		fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
 		disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
 		data_offset = btrfs_file_extent_offset(eb, fi);
@@ -484,6 +526,7 @@ next:
  */
 static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
 				struct btrfs_path *path, u64 time_seq,
+				struct preftrees *preftrees,
 				struct prelim_ref *ref, struct ulist *parents,
 				const u64 *extent_item_pos, u64 total_refs,
 				bool ignore_offset)
@@ -577,8 +620,8 @@ static int resolve_indirect_ref(struct b
 		eb = path->nodes[level];
 	}
 
-	ret = add_all_parents(root, path, parents, ref, level, time_seq,
-			      extent_item_pos, total_refs, ignore_offset);
+	ret = add_all_parents(root, path, parents, preftrees, ref, level,
+			      time_seq, extent_item_pos, total_refs, ignore_offset);
 out:
 	path->lowest_level = 0;
 	btrfs_release_path(path);
@@ -656,8 +699,8 @@ static int resolve_indirect_refs(struct
 			ret = BACKREF_FOUND_SHARED;
 			goto out;
 		}
-		err = resolve_indirect_ref(fs_info, path, time_seq, ref,
-					   parents, extent_item_pos,
+		err = resolve_indirect_ref(fs_info, path, time_seq, preftrees,
+					   ref, parents, extent_item_pos,
 					   total_refs, ignore_offset);
 		/*
 		 * we can only tolerate ENOENT,otherwise,we should catch error



  parent reply	other threads:[~2021-02-05 16:47 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-05 14:07 [PATCH 5.4 00/32] 5.4.96-rc1 review Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 01/32] net: dsa: bcm_sf2: put device node before return Greg Kroah-Hartman
2021-02-07  9:25   ` Pavel Machek
2021-02-05 14:07 ` [PATCH 5.4 02/32] net: switchdev: dont set port_obj_info->handled true when -EOPNOTSUPP Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 03/32] ibmvnic: Ensure that CRQ entry read are correctly ordered Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 04/32] Revert "Revert "block: end bio with BLK_STS_AGAIN in case of non-mq devs and REQ_NOWAIT"" Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 05/32] ACPI: thermal: Do not call acpi_thermal_check() directly Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 06/32] arm64: Fix kernel address detection of __is_lm_address() Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 07/32] arm64: Do not pass tagged addresses to __is_lm_address() Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 08/32] tcp: make TCP_USER_TIMEOUT accurate for zero window probes Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 09/32] btrfs: backref, only collect file extent items matching backref offset Greg Kroah-Hartman
2021-02-05 14:07 ` Greg Kroah-Hartman [this message]
2021-02-05 14:07 ` [PATCH 5.4 11/32] btrfs: backref, only search backref entries from leaves of the same root Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 12/32] btrfs: backref, use correct count to resolve normal data refs Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 13/32] net_sched: gen_estimator: support large ewma log Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 14/32] phy: cpcap-usb: Fix warning for missing regulator_disable Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 15/32] platform/x86: touchscreen_dmi: Add swap-x-y quirk for Goodix touchscreen on Estar Beauty HD tablet Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 16/32] platform/x86: intel-vbtn: Support for tablet mode on Dell Inspiron 7352 Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 17/32] x86: __always_inline __{rd,wr}msr() Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 18/32] scsi: scsi_transport_srp: Dont block target in failfast state Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 19/32] scsi: libfc: Avoid invoking response handler twice if ep is already completed Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 20/32] scsi: fnic: Fix memleak in vnic_dev_init_devcmd2 Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 21/32] ASoC: SOF: Intel: hda: Resume codec to do jack detection Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 22/32] mac80211: fix fast-rx encryption check Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 23/32] scsi: ibmvfc: Set default timeout to avoid crash during migration Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 24/32] ALSA: hda: Add Cometlake-R PCI ID Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 25/32] udf: fix the problem that the disc content is not displayed Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 26/32] nvme: check the PRINFO bit before deciding the host buffer length Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 27/32] selftests/powerpc: Only test lwm/stmw on big endian Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 28/32] drm/amd/display: Update dram_clock_change_latency for DCN2.1 Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 29/32] drm/amd/display: Change function decide_dp_link_settings to avoid infinite looping Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 30/32] objtool: Dont fail on missing symbol table Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 31/32] kthread: Extract KTHREAD_IS_PER_CPU Greg Kroah-Hartman
2021-02-05 14:07 ` [PATCH 5.4 32/32] workqueue: Restrict affinity change to rescuer Greg Kroah-Hartman
2021-02-05 20:58 ` [PATCH 5.4 00/32] 5.4.96-rc1 review Igor
2021-02-05 21:16 ` Florian Fainelli
2021-02-07 14:36   ` Greg Kroah-Hartman
2021-02-06 14:27 ` Naresh Kamboju
2021-02-06 16:02 ` Guenter Roeck
2021-02-07 15:34 ` Jon Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210205140652.781147189@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=dsterba@suse.com \
    --cc=ethanwu@synology.com \
    --cc=johannes.thumshirn@wdc.com \
    --cc=josef@toxicpanda.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.