[PATCH 4/5] btrfs-progs: check: skip NODATASUM inodes for `--init-csum-tree --init-extent-tree`
From: Qu Wenruo <hidden>
Date: 2021-12-24 05:50:52
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 <redacted> --- check/mode-common.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/check/mode-common.c b/check/mode-common.c
index dd0b1d695bfa..1c1374bae70b 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;
@@ -1245,15 +1246,51 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans, while (1) { 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); + + /* Skip preallocated/inline extents */ if (btrfs_file_extent_type(node, fi) != BTRFS_FILE_EXTENT_REG) goto next; - start = btrfs_file_extent_disk_bytenr(node, fi); - len = btrfs_file_extent_disk_num_bytes(node, fi); + + /* Skip hole extents */ + if (btrfs_file_extent_disk_bytenr(node, fi) == 0) + goto next; + + if (btrfs_file_extent_compression(node, fi) == + BTRFS_COMPRESS_NONE) { + /* + * Non-compressed extent, only calculate csum for the + * referred part, as the original larger extent can + * be preallocated. + */ + start = btrfs_file_extent_disk_bytenr(node, fi) + + btrfs_file_extent_offset(node, fi); + len = btrfs_file_extent_num_bytes(node, fi); + } else { + start = btrfs_file_extent_disk_bytenr(node, fi); + len = btrfs_file_extent_disk_num_bytes(node, fi); + } csum_root = btrfs_csum_root(gfs_info, start); ret = populate_csum(trans, csum_root, buf, start, len);
--
2.34.1