All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH v2 4/5] btrfs-progs: check: handle csum generation properly for `--init-csum-tree --init-extent-tree`
Date: Fri, 14 Jan 2022 08:51:22 +0800	[thread overview]
Message-ID: <20220114005123.19426-5-wqu@suse.com> (raw)
In-Reply-To: <20220114005123.19426-1-wqu@suse.com>

When using `--init-csum-tree` with `--init-extent-tree`, csum tree
population will be done by iterating all file extent items.

This allow us to skip preallocated extents, but it still has the
folllwing problems:

- Inodes with NODATASUM

- Hole file extents

- Written preallocated extents
  We will generate csum for the whole extent, while other part may still
  be unwritten.

Make it to follow the same behavior of recently introduced
fill_csum_for_file_extent(), so we can generate correct csum.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 check/mode-common.c | 53 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 49 insertions(+), 4 deletions(-)

diff --git a/check/mode-common.c b/check/mode-common.c
index 4c6dca2d5973..e487f2f0bb8e 100644
--- a/check/mode-common.c
+++ b/check/mode-common.c
@@ -1225,6 +1225,7 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans,
 	struct extent_buffer *node;
 	struct btrfs_file_extent_item *fi;
 	char *buf = NULL;
+	u64 skip_ino = 0;
 	u64 start = 0;
 	u64 len = 0;
 	int slot = 0;
@@ -1243,24 +1244,68 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans,
 		goto out;
 	/* Iterate all regular file extents and fill its csum */
 	while (1) {
+		u8 type;
+
 		btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
 
-		if (key.type != BTRFS_EXTENT_DATA_KEY)
+		if (key.type != BTRFS_EXTENT_DATA_KEY &&
+		    key.type != BTRFS_INODE_ITEM_KEY)
+			goto next;
+
+		/* This item belongs to an inode with NODATASUM, skip it */
+		if (key.objectid == skip_ino)
 			goto next;
+
+		if (key.type == BTRFS_INODE_ITEM_KEY) {
+			struct btrfs_inode_item *ii;
+
+			ii = btrfs_item_ptr(path.nodes[0], path.slots[0],
+					    struct btrfs_inode_item);
+			/* Check if the inode has NODATASUM flag */
+			if (btrfs_inode_flags(path.nodes[0], ii) &
+			    BTRFS_INODE_NODATASUM)
+				skip_ino = key.objectid;
+			goto next;
+		}
 		node = path.nodes[0];
 		slot = path.slots[0];
 		fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item);
-		if (btrfs_file_extent_type(node, fi) != BTRFS_FILE_EXTENT_REG)
+		type = btrfs_file_extent_type(node, fi);
+
+		/* Skip inline extents */
+		if (type == BTRFS_FILE_EXTENT_INLINE)
 			goto next;
-		start = btrfs_file_extent_disk_bytenr(node, fi);
-		len = btrfs_file_extent_disk_num_bytes(node, fi);
 
+		start = btrfs_file_extent_disk_bytenr(node, fi);
+		/* Skip holes */
+		if (start == 0)
+			goto next;
+		/*
+		 * Always generate the csum for the whole preallocated/regular
+		 * first, then remove the csum for preallocated range.
+		 *
+		 * This is to handle holes on regular extents like:
+		 * xfs_io -f -c "pwrite 0 8k" -c "sync" -c "punch 0 4k".
+		 *
+		 * This behavior will cost extra IO/CPU time, but there is
+		 * not other way to ensure the correctness.
+		 */
 		csum_root = btrfs_csum_root(gfs_info, start);
+		len = btrfs_file_extent_disk_num_bytes(node, fi);
 		ret = populate_csum(trans, csum_root, buf, start, len);
 		if (ret == -EEXIST)
 			ret = 0;
 		if (ret < 0)
 			goto out;
+
+		/* Delete the csum for the preallocated range */
+		if (type == BTRFS_FILE_EXTENT_PREALLOC) {
+			start += btrfs_file_extent_offset(node, fi);
+			len = btrfs_file_extent_num_bytes(node, fi);
+			ret = btrfs_del_csums(trans, start, len);
+			if (ret < 0)
+				goto out;
+		}
 next:
 		/*
 		 * TODO: if next leaf is corrupted, jump to nearest next valid
-- 
2.34.1


  parent reply	other threads:[~2022-01-14  0:51 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-14  0:51 [PATCH v2 0/5] btrfs-progs: check: properly generate csum for various complex combinations Qu Wenruo
2022-01-14  0:51 ` [PATCH v2 1/5] btrfs-progs: backref: properly queue indirect refs Qu Wenruo
2022-01-14  0:51 ` [PATCH v2 2/5] btrfs-progs: check: move csum tree population into mode-common.[ch] Qu Wenruo
2022-01-14  0:51 ` [PATCH v2 3/5] btrfs-progs: check: don't calculate csum for preallocated file extents Qu Wenruo
2022-01-14  0:51 ` Qu Wenruo [this message]
2022-01-14  0:51 ` [PATCH v2 5/5] btrfs-progs: fsck-tests: add test case for init-csum-tree Qu Wenruo
2022-01-14 16:40   ` David Sterba
2022-01-14 23:40     ` Qu Wenruo
2022-01-17 13:50       ` David Sterba
2022-01-14 16:50 ` [PATCH v2 0/5] btrfs-progs: check: properly generate csum for various complex combinations David Sterba

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=20220114005123.19426-5-wqu@suse.com \
    --to=wqu@suse.com \
    --cc=linux-btrfs@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.