Skip to contentSkip to conversation

Misc fixups and cleanups

PATCH In review David Sterba 4 participants 30 messages May 25, 2021 – May 26, 2021

Subsystems (2)
lore
Share & tools
lore

David Sterba

author maintainer
#0 lore raw

cover Misc fixups and cleanups

David Sterba (9):
btrfs: sysfs: fix format string for some discard stats
btrfs: clear defrag status of a root if starting transaction fails
btrfs: clear log tree recovering status if starting transaction fails
btrfs: scrub: factor out common scrub_stripe constraints
btrfs: document byte swap optimization of root_item::flags accessors
btrfs: reduce compressed_bio members' types
btrfs: remove extra sb::s_id from message in
btrfs_validate_metadata_buffer
btrfs: simplify eb checksum verification in
btrfs_validate_metadata_buffer
btrfs: clean up header members offsets in write helpers

 fs/btrfs/compression.c |  2 +-
 fs/btrfs/compression.h | 20 ++++++++++----------
 fs/btrfs/ctree.h       |  2 ++
 fs/btrfs/disk-io.c     | 14 +++++++-------
 fs/btrfs/extent_io.c   | 13 +++++++------
 fs/btrfs/scrub.c       |  9 ++-------
 fs/btrfs/sysfs.c       |  4 ++--
 fs/btrfs/transaction.c |  6 ++++--
 fs/btrfs/tree-log.c    |  1 +
 9 files changed, 36 insertions(+), 35 deletions(-)
Signature · 1 line
2.29.2
author maintainer
#1 lore raw

PATCH 1/9 btrfs: sysfs: fix format string for some discard stats

The type of discard_bitmap_bytes and discard_extent_bytes is u64 so the format should be %llu, though the actual values would hardly ever overflow to negative values.

---
 fs/btrfs/sysfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/sysfs.c +2 -2
index c45d9b6dfdb5..4b508938e728 100644
@@ -429,7 +429,7 @@ static ssize_t btrfs_discard_bitmap_bytes_show(struct kobject *kobj,
 {
 	struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
 
-	return scnprintf(buf, PAGE_SIZE, "%lld\n",
+	return scnprintf(buf, PAGE_SIZE, "%llu\n",
 			fs_info->discard_ctl.discard_bitmap_bytes);
 }
 BTRFS_ATTR(discard, discard_bitmap_bytes, btrfs_discard_bitmap_bytes_show);
@@ -451,7 +451,7 @@ static ssize_t btrfs_discard_extent_bytes_show(struct kobject *kobj,
 {
 	struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
 
-	return scnprintf(buf, PAGE_SIZE, "%lld\n",
+	return scnprintf(buf, PAGE_SIZE, "%llu\n",
 			fs_info->discard_ctl.discard_extent_bytes);
 }
 BTRFS_ATTR(discard, discard_extent_bytes, btrfs_discard_extent_bytes_show);
Signature · 1 line
2.29.2
Reviewed-by on v1 1/9
#2 lore raw

Re: [PATCH 1/9] btrfs: sysfs: fix format string for some discard stats

Quoted 5 lines · David Sterba

The type of discard_bitmap_bytes and discard_extent_bytes is u64 so the format should be %llu, though the actual values would hardly ever overflow to negative values.

Thanks,
Qu

Quoted 27 lines
---
  fs/btrfs/sysfs.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/sysfs.c +2 -2
index c45d9b6dfdb5..4b508938e728 100644
@@ -429,7 +429,7 @@ static ssize_t btrfs_discard_bitmap_bytes_show(struct kobject *kobj,
  {
  	struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
 
-	return scnprintf(buf, PAGE_SIZE, "%lld\n",
+	return scnprintf(buf, PAGE_SIZE, "%llu\n",
  			fs_info->discard_ctl.discard_bitmap_bytes);
  }
  BTRFS_ATTR(discard, discard_bitmap_bytes, btrfs_discard_bitmap_bytes_show);
@@ -451,7 +451,7 @@ static ssize_t btrfs_discard_extent_bytes_show(struct kobject *kobj,
  {
  	struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
 
-	return scnprintf(buf, PAGE_SIZE, "%lld\n",
+	return scnprintf(buf, PAGE_SIZE, "%llu\n",
  			fs_info->discard_ctl.discard_extent_bytes);
  }
  BTRFS_ATTR(discard, discard_extent_bytes, btrfs_discard_extent_bytes_show);
Reviewed-by on v1 1/9
#3 lore raw

Re: [PATCH 1/9] btrfs: sysfs: fix format string for some discard stats

In reply to David Sterba
Quoted 5 lines · David Sterba

The type of discard_bitmap_bytes and discard_extent_bytes is u64 so the format should be %llu, though the actual values would hardly ever overflow to negative values.

Quoted 27 lines
---
  fs/btrfs/sysfs.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/sysfs.c +2 -2
index c45d9b6dfdb5..4b508938e728 100644
@@ -429,7 +429,7 @@ static ssize_t btrfs_discard_bitmap_bytes_show(struct kobject *kobj,
  {
  	struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
 
-	return scnprintf(buf, PAGE_SIZE, "%lld\n",
+	return scnprintf(buf, PAGE_SIZE, "%llu\n",
  			fs_info->discard_ctl.discard_bitmap_bytes);
  }
  BTRFS_ATTR(discard, discard_bitmap_bytes, btrfs_discard_bitmap_bytes_show);
@@ -451,7 +451,7 @@ static ssize_t btrfs_discard_extent_bytes_show(struct kobject *kobj,
  {
  	struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
 
-	return scnprintf(buf, PAGE_SIZE, "%lld\n",
+	return scnprintf(buf, PAGE_SIZE, "%llu\n",
  			fs_info->discard_ctl.discard_extent_bytes);
  }
  BTRFS_ATTR(discard, discard_extent_bytes, btrfs_discard_extent_bytes_show);
author maintainer
#4 lore raw

PATCH 2/9 btrfs: clear defrag status of a root if starting transaction fails

In reply to David Sterba

The defrag loop processes leaves in batches and starting transaction for each. The whole defragmentation on a given root is protected by a bit but in case the transaction fails, the bit is not cleared

In case the transaction fails the bit would prevent starting defragmentation again, so make sure it's cleared.

---
 fs/btrfs/transaction.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/transaction.c +4 -2
index e0a82aa7da89..22951621363f 100644
@@ -1406,8 +1406,10 @@ int btrfs_defrag_root(struct btrfs_root *root)
 
 	while (1) {
 		trans = btrfs_start_transaction(root, 0);
-		if (IS_ERR(trans))
-			return PTR_ERR(trans);
+		if (IS_ERR(trans)) {
+			ret = PTR_ERR(trans);
+			break;
+		}
 
 		ret = btrfs_defrag_leaves(trans, root);
 
Signature · 1 line
2.29.2
Reviewed-by on v1 2/9
#5 lore raw

Re: [PATCH 2/9] btrfs: clear defrag status of a root if starting transaction fails

Quoted 9 lines · David Sterba

The defrag loop processes leaves in batches and starting transaction for each. The whole defragmentation on a given root is protected by a bit but in case the transaction fails, the bit is not cleared

In case the transaction fails the bit would prevent starting defragmentation again, so make sure it's cleared.

Thanks,
Qu

Quoted 22 lines
---
  fs/btrfs/transaction.c | 6 ++++--
  1 file changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/transaction.c +4 -2
index e0a82aa7da89..22951621363f 100644
@@ -1406,8 +1406,10 @@ int btrfs_defrag_root(struct btrfs_root *root)
 
  	while (1) {
  		trans = btrfs_start_transaction(root, 0);
-		if (IS_ERR(trans))
-			return PTR_ERR(trans);
+		if (IS_ERR(trans)) {
+			ret = PTR_ERR(trans);
+			break;
+		}
 
  		ret = btrfs_defrag_leaves(trans, root);
 
Reviewed-by on v1 2/9
#6 lore raw

Re: [PATCH 2/9] btrfs: clear defrag status of a root if starting transaction fails

In reply to David Sterba
Quoted 9 lines · David Sterba

The defrag loop processes leaves in batches and starting transaction for each. The whole defragmentation on a given root is protected by a bit but in case the transaction fails, the bit is not cleared

In case the transaction fails the bit would prevent starting defragmentation again, so make sure it's cleared.

Thanks.

Quoted 22 lines
---
  fs/btrfs/transaction.c | 6 ++++--
  1 file changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/transaction.c +4 -2
index e0a82aa7da89..22951621363f 100644
@@ -1406,8 +1406,10 @@ int btrfs_defrag_root(struct btrfs_root *root)
 
  	while (1) {
  		trans = btrfs_start_transaction(root, 0);
-		if (IS_ERR(trans))
-			return PTR_ERR(trans);
+		if (IS_ERR(trans)) {
+			ret = PTR_ERR(trans);
+			break;
+		}
 
  		ret = btrfs_defrag_leaves(trans, root);
 
author maintainer
#7 lore raw

PATCH 3/9 btrfs: clear log tree recovering status if starting transaction fails

In reply to David Sterba

When a log recovery is in progress, lots of operations have to take that into account, so we keep this status per tree during the operation. Long time ago error handling revamp patch 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling") removed clearing of the status in an error branch. Add it back as was intended in e02119d5a7b4 ("Btrfs:
Add a write ahead tree log to optimize synchronous operations").

There are probably no visible effects, log replay is done only during mount and if it fails all structures are cleared so the stale status won't be kept.

Fixes 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling")
---
 fs/btrfs/tree-log.c | 1 +
 1 file changed, 1 insertion(+)
fs/btrfs/tree-log.c +1 -0
index c6d4aeede159..5c1d58706fa9 100644
@@ -6372,6 +6372,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 error:
 	if (wc.trans)
 		btrfs_end_transaction(wc.trans);
+	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
 	btrfs_free_path(path);
 	return ret;
 }
Signature · 1 line
2.29.2
Reviewed-by on v1 3/9
#8 lore raw

Re: [PATCH 3/9] btrfs: clear log tree recovering status if starting transaction fails

Quoted 7 lines · David Sterba

When a log recovery is in progress, lots of operations have to take that into account, so we keep this status per tree during the operation. Long time ago error handling revamp patch 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling") removed clearing of the status in an error branch. Add it back as was intended in e02119d5a7b4 ("Btrfs:
Add a write ahead tree log to optimize synchronous operations").

Quoted 6 lines

There are probably no visible effects, log replay is done only during mount and if it fails all structures are cleared so the stale status won't be kept.

Fixes 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling")

Thanks,
Qu

Quoted 17 lines
---
  fs/btrfs/tree-log.c | 1 +
  1 file changed, 1 insertion(+)
fs/btrfs/tree-log.c +1 -0
index c6d4aeede159..5c1d58706fa9 100644
@@ -6372,6 +6372,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
  error:
  	if (wc.trans)
  		btrfs_end_transaction(wc.trans);
+	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
  	btrfs_free_path(path);
  	return ret;
  }
Reviewed-by on v1 3/9
#9 lore raw

Re: [PATCH 3/9] btrfs: clear log tree recovering status if starting transaction fails

In reply to David Sterba
Quoted 7 lines · David Sterba

When a log recovery is in progress, lots of operations have to take that into account, so we keep this status per tree during the operation. Long time ago error handling revamp patch 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling") removed clearing of the status in an error branch. Add it back as was intended in e02119d5a7b4 ("Btrfs:
Add a write ahead tree log to optimize synchronous operations").

Quoted 6 lines

There are probably no visible effects, log replay is done only during mount and if it fails all structures are cleared so the stale status won't be kept.

Fixes 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling")

Thanks.

Quoted 17 lines
---
  fs/btrfs/tree-log.c | 1 +
  1 file changed, 1 insertion(+)
fs/btrfs/tree-log.c +1 -0
index c6d4aeede159..5c1d58706fa9 100644
@@ -6372,6 +6372,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
  error:
  	if (wc.trans)
  		btrfs_end_transaction(wc.trans);
+	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
  	btrfs_free_path(path);
  	return ret;
  }
author maintainer
#10 lore raw

PATCH 4/9 btrfs: scrub: factor out common scrub_stripe constraints

In reply to David Sterba

There are common values set for the stripe constraints, some of them are already factored out. Do that for increment and mirror_num as well.

---
 fs/btrfs/scrub.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
fs/btrfs/scrub.c +2 -7
index 518415d0c122..5839ad1e25a2 100644
@@ -3204,28 +3204,23 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
 	physical = map->stripes[num].physical;
 	offset = 0;
 	nstripes = div64_u64(length, map->stripe_len);
+	mirror_num = 1;
+	increment = map->stripe_len;
 	if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
 		offset = map->stripe_len * num;
 		increment = map->stripe_len * map->num_stripes;
-		mirror_num = 1;
 	} else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
 		int factor = map->num_stripes / map->sub_stripes;
 		offset = map->stripe_len * (num / map->sub_stripes);
 		increment = map->stripe_len * factor;
 		mirror_num = num % map->sub_stripes + 1;
 	} else if (map->type & BTRFS_BLOCK_GROUP_RAID1_MASK) {
-		increment = map->stripe_len;
 		mirror_num = num % map->num_stripes + 1;
 	} else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
-		increment = map->stripe_len;
 		mirror_num = num % map->num_stripes + 1;
 	} else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
 		get_raid56_logic_offset(physical, num, map, &offset, NULL);
 		increment = map->stripe_len * nr_data_stripes(map);
-		mirror_num = 1;
-	} else {
-		increment = map->stripe_len;
-		mirror_num = 1;
 	}
 
 	path = btrfs_alloc_path();
Signature · 1 line
2.29.2
Reviewed-by on v1 4/9
#11 lore raw

Re: [PATCH 4/9] btrfs: scrub: factor out common scrub_stripe constraints

Quoted 4 lines · David Sterba

There are common values set for the stripe constraints, some of them are already factored out. Do that for increment and mirror_num as well.

Thanks,
Qu

Quoted 40 lines
---
  fs/btrfs/scrub.c | 9 ++-------
  1 file changed, 2 insertions(+), 7 deletions(-)
fs/btrfs/scrub.c +2 -7
index 518415d0c122..5839ad1e25a2 100644
@@ -3204,28 +3204,23 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
  	physical = map->stripes[num].physical;
  	offset = 0;
  	nstripes = div64_u64(length, map->stripe_len);
+	mirror_num = 1;
+	increment = map->stripe_len;
  	if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
  		offset = map->stripe_len * num;
  		increment = map->stripe_len * map->num_stripes;
-		mirror_num = 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
  		int factor = map->num_stripes / map->sub_stripes;
  		offset = map->stripe_len * (num / map->sub_stripes);
  		increment = map->stripe_len * factor;
  		mirror_num = num % map->sub_stripes + 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_RAID1_MASK) {
-		increment = map->stripe_len;
  		mirror_num = num % map->num_stripes + 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
-		increment = map->stripe_len;
  		mirror_num = num % map->num_stripes + 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
  		get_raid56_logic_offset(physical, num, map, &offset, NULL);
  		increment = map->stripe_len * nr_data_stripes(map);
-		mirror_num = 1;
-	} else {
-		increment = map->stripe_len;
-		mirror_num = 1;
  	}
 
  	path = btrfs_alloc_path();
Reviewed-by on v1 4/9
#12 lore raw

Re: [PATCH 4/9] btrfs: scrub: factor out common scrub_stripe constraints

In reply to David Sterba
Quoted 4 lines · David Sterba

There are common values set for the stripe constraints, some of them are already factored out. Do that for increment and mirror_num as well.

Thanks.

Quoted 40 lines
---
  fs/btrfs/scrub.c | 9 ++-------
  1 file changed, 2 insertions(+), 7 deletions(-)
fs/btrfs/scrub.c +2 -7
index 518415d0c122..5839ad1e25a2 100644
@@ -3204,28 +3204,23 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
  	physical = map->stripes[num].physical;
  	offset = 0;
  	nstripes = div64_u64(length, map->stripe_len);
+	mirror_num = 1;
+	increment = map->stripe_len;
  	if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
  		offset = map->stripe_len * num;
  		increment = map->stripe_len * map->num_stripes;
-		mirror_num = 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
  		int factor = map->num_stripes / map->sub_stripes;
  		offset = map->stripe_len * (num / map->sub_stripes);
  		increment = map->stripe_len * factor;
  		mirror_num = num % map->sub_stripes + 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_RAID1_MASK) {
-		increment = map->stripe_len;
  		mirror_num = num % map->num_stripes + 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
-		increment = map->stripe_len;
  		mirror_num = num % map->num_stripes + 1;
  	} else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
  		get_raid56_logic_offset(physical, num, map, &offset, NULL);
  		increment = map->stripe_len * nr_data_stripes(map);
-		mirror_num = 1;
-	} else {
-		increment = map->stripe_len;
-		mirror_num = 1;
  	}
 
  	path = btrfs_alloc_path();
author maintainer
#13 lore raw

PATCH 5/9 btrfs: document byte swap optimization of root_item::flags accessors

In reply to David Sterba
---
 fs/btrfs/ctree.h | 2 ++
 1 file changed, 2 insertions(+)
fs/btrfs/ctree.h +2 -0
index d78cb2d89d7e..a3b628ea4d64 100644
@@ -2216,11 +2216,13 @@ BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item,
 
 static inline bool btrfs_root_readonly(const struct btrfs_root *root)
 {
+	/* Byte-swap the constant at compile time, root_item::flags is LE */
 	return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0;
 }
 
 static inline bool btrfs_root_dead(const struct btrfs_root *root)
 {
+	/* Byte-swap the constant at compile time, root_item::flags is LE */
 	return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0;
 }
 
Signature · 1 line
2.29.2
Reviewed-by on v1 5/9
#14 lore raw

Re: [PATCH 5/9] btrfs: document byte swap optimization of root_item::flags accessors

Quoted 1 line · David Sterba

Thanks.

Quoted 23 lines
---
  fs/btrfs/ctree.h | 2 ++
  1 file changed, 2 insertions(+)
fs/btrfs/ctree.h +2 -0
index d78cb2d89d7e..a3b628ea4d64 100644
@@ -2216,11 +2216,13 @@ BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item,
 
  static inline bool btrfs_root_readonly(const struct btrfs_root *root)
  {
+	/* Byte-swap the constant at compile time, root_item::flags is LE */
  	return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0;
  }
 
  static inline bool btrfs_root_dead(const struct btrfs_root *root)
  {
+	/* Byte-swap the constant at compile time, root_item::flags is LE */
  	return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0;
  }
 
author maintainer
#15 lore raw

PATCH 6/9 btrfs: reduce compressed_bio members' types

In reply to David Sterba

Several members of compressed_bio are of type that's unnecessarily big for the values that they'd hold:

- the size of the uncompressed and compressed data is 128K now, we can keep is as int
- same for number of pages
- the compress type fits to a byte
- the errors is 0/1

The size of the unpatched structure is 80 bytes with several holes. Reordering nr_pages next to the pages the hole after pending_bios is filled and the resulting size is 56 bytes. This keeps the csums array aligned to 8 bytes, which is nice. Further size optimizations may be possible but right now it looks good to me:

struct compressed_bio {

        refcount_t                 pending_bios;         /*     0     4 */
        unsigned int               nr_pages;             /*     4     4 */
        struct page * *            compressed_pages;     /*     8     8 */
        struct inode *             inode;                /*    16     8 */
        u64                        start;                /*    24     8 */
        unsigned int               len;                  /*    32     4 */
        unsigned int               compressed_len;       /*    36     4 */
        u8                         compress_type;        /*    40     1 */
        u8                         errors;               /*    41     1 */
        /* XXX 2 bytes hole, try to pack */

        int                        mirror_num;           /*    44     4 */
        struct bio *               orig_bio;             /*    48     8 */
        u8                         sums[];               /*    56     0 */

        /* size: 56, cachelines: 1, members: 12 */
        /* sum members: 54, holes: 1, sum holes: 2 */
        /* last cacheline: 56 bytes */
};
---
 fs/btrfs/compression.c |  2 +-
 fs/btrfs/compression.h | 20 ++++++++++----------
 2 files changed, 11 insertions(+), 11 deletions(-)
fs/btrfs/compression.c +1 -1
index 9a0c26e4e389..c006f5d81c2a 100644
@@ -507,7 +507,7 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
 		}
 		if (bytes_left < PAGE_SIZE) {
 			btrfs_info(fs_info,
-					"bytes left %lu compress len %lu nr %lu",
+					"bytes left %lu compress len %u nr %u",
 			       bytes_left, cb->compressed_len, cb->nr_pages);
 		}
 		bytes_left -= PAGE_SIZE;
fs/btrfs/compression.h +10 -10
index 8001b700ea3a..00d8439048c9 100644
@@ -31,6 +31,9 @@ struct compressed_bio {
 	/* number of bios pending for this compressed extent */
 	refcount_t pending_bios;
 
+	/* Number of compressed pages in the array */
+	unsigned int nr_pages;
+
 	/* the pages with the compressed data on them */
 	struct page **compressed_pages;
 
@@ -40,20 +43,17 @@ struct compressed_bio {
 	/* starting offset in the inode for our pages */
 	u64 start;
 
-	/* number of bytes in the inode we're working on */
-	unsigned long len;
-
-	/* number of bytes on disk */
-	unsigned long compressed_len;
+	/* Number of bytes in the inode we're working on */
+	unsigned int len;
 
-	/* the compression algorithm for this bio */
-	int compress_type;
+	/* Number of bytes on disk */
+	unsigned int compressed_len;
 
-	/* number of compressed pages in the array */
-	unsigned long nr_pages;
+	/* The compression algorithm for this bio */
+	u8 compress_type;
 
 	/* IO errors */
-	int errors;
+	u8 errors;
 	int mirror_num;
 
 	/* for reads, this is the bio we are copying the data into */
Signature · 1 line
2.29.2
#16 lore raw

PATCH 1/1 btrfs: optimize users of members of the struct compressed_bio

Commit
btrfs: reduce compressed_bio member's types
reduced some of the members size.

It has its cascading effects which are done here.

---
 fs/btrfs/compression.c | 18 +++++++++---------
 fs/btrfs/compression.h |  6 +++---
 2 files changed, 12 insertions(+), 12 deletions(-)
fs/btrfs/compression.c +9 -9
index c006f5d81c2a..36731b598770 100644
@@ -149,7 +149,7 @@ static int check_compressed_csum(struct btrfs_inode *inode, struct bio *bio,
 	const u32 csum_size = fs_info->csum_size;
 	const u32 sectorsize = fs_info->sectorsize;
 	struct page *page;
-	unsigned long i;
+	unsigned int i;
 	char *kaddr;
 	u8 csum[BTRFS_CSUM_SIZE];
 	struct compressed_bio *cb = bio->bi_private;
@@ -208,7 +208,7 @@ static void end_compressed_bio_read(struct bio *bio)
 	struct compressed_bio *cb = bio->bi_private;
 	struct inode *inode;
 	struct page *page;
-	unsigned long index;
+	unsigned int index;
 	unsigned int mirror = btrfs_io_bio(bio)->mirror_num;
 	int ret = 0;
 
@@ -334,7 +334,7 @@ static void end_compressed_bio_write(struct bio *bio)
 	struct compressed_bio *cb = bio->bi_private;
 	struct inode *inode;
 	struct page *page;
-	unsigned long index;
+	unsigned int index;
 
 	if (bio->bi_status)
 		cb->errors = 1;
@@ -387,10 +387,10 @@ static void end_compressed_bio_write(struct bio *bio)
  * the end io hooks.
  */
 blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
-				 unsigned long len, u64 disk_start,
-				 unsigned long compressed_len,
+				 unsigned int len, u64 disk_start,
+				 unsigned int compressed_len,
 				 struct page **compressed_pages,
-				 unsigned long nr_pages,
+				 unsigned int nr_pages,
 				 unsigned int write_flags,
 				 struct cgroup_subsys_state *blkcg_css)
 {
@@ -669,9 +669,9 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 	struct extent_map_tree *em_tree;
 	struct compressed_bio *cb;
-	unsigned long compressed_len;
-	unsigned long nr_pages;
-	unsigned long pg_index;
+	unsigned int compressed_len;
+	unsigned int nr_pages;
+	unsigned int pg_index;
 	struct page *page;
 	struct bio *comp_bio;
 	u64 cur_disk_byte = bio->bi_iter.bi_sector << 9;
fs/btrfs/compression.h +3 -3
index 00d8439048c9..c359f20920d0 100644
@@ -91,10 +91,10 @@ int btrfs_decompress_buf2page(const char *buf, unsigned long buf_start,
 			      struct bio *bio);
 
 blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
-				  unsigned long len, u64 disk_start,
-				  unsigned long compressed_len,
+				  unsigned int len, u64 disk_start,
+				  unsigned int compressed_len,
 				  struct page **compressed_pages,
-				  unsigned long nr_pages,
+				  unsigned int nr_pages,
 				  unsigned int write_flags,
 				  struct cgroup_subsys_state *blkcg_css);
 blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
Signature · 1 line
2.30.2
#17 lore raw

Re: [PATCH] btrfs: optimize users of members of the struct compressed_bio

Quoted 5 lines · Anand Jain

Commit
btrfs: reduce compressed_bio member's types
reduced some of the members size.

It has its cascading effects which are done here.

Agreed, feel free to send it as proper patch(es) (also updating the async_extent). The compression code uses a lot of types that are wider than necessary, so optimizing that could improve the stack footprint.

Reviewed-by on v1 6/9
#18 lore raw

Re: [PATCH 6/9] btrfs: reduce compressed_bio members' types

In reply to David Sterba
Quoted 26 lines · David Sterba

Several members of compressed_bio are of type that's unnecessarily big for the values that they'd hold:

- the size of the uncompressed and compressed data is 128K now, we can keep is as int
- same for number of pages
- the compress type fits to a byte
- the errors is 0/1

The size of the unpatched structure is 80 bytes with several holes. Reordering nr_pages next to the pages the hole after pending_bios is filled and the resulting size is 56 bytes. This keeps the csums array aligned to 8 bytes, which is nice. Further size optimizations may be possible but right now it looks good to me:

struct compressed_bio {

         refcount_t                 pending_bios;         /*     0     4 */
         unsigned int               nr_pages;             /*     4     4 */
         struct page * *            compressed_pages;     /*     8     8 */
         struct inode *             inode;                /*    16     8 */
         u64                        start;                /*    24     8 */
         unsigned int               len;                  /*    32     4 */
         unsigned int               compressed_len;       /*    36     4 */
         u8                         compress_type;        /*    40     1 */
         u8                         errors;               /*    41     1 */
Quoted 11 lines
         /* XXX 2 bytes hole, try to pack */

         int                        mirror_num;           /*    44     4 */
         struct bio *               orig_bio;             /*    48     8 */
         u8                         sums[];               /*    56     0 */

         /* size: 56, cachelines: 1, members: 12 */
         /* sum members: 54, holes: 1, sum holes: 2 */
         /* last cacheline: 56 bytes */
};

The following member types of struct compressed_bio are changed here:

- unsigned long len;
+ unsigned int len;

- int compress_type;
+ u8 compress_type;

- unsigned long nr_pages;
+ unsigned int nr_pages;

- unsigned long compressed_len;
+ unsigned int compressed_len;

- int errors;
+ u8 errors;

There are no warnings.

But in btrfs_submit_compressed_write()

Essentially struct compressed_bio is updated from struct async_extent.

struct async_extent {
        u64 start;
        u64 ram_size;
        u64 compressed_size;
        struct page **pages;
        unsigned long nr_pages;
        int compress_type;
        struct list_head list;
};

which can be looked into later.

For now, with the patch
btrfs: optimize users of members of the struct compressed_bio
which is sent to ML.

Quoted 62 lines
---
  fs/btrfs/compression.c |  2 +-
  fs/btrfs/compression.h | 20 ++++++++++----------
  2 files changed, 11 insertions(+), 11 deletions(-)
fs/btrfs/compression.c +1 -1
index 9a0c26e4e389..c006f5d81c2a 100644
@@ -507,7 +507,7 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
  		}
  		if (bytes_left < PAGE_SIZE) {
  			btrfs_info(fs_info,
-					"bytes left %lu compress len %lu nr %lu",
+					"bytes left %lu compress len %u nr %u",
  			       bytes_left, cb->compressed_len, cb->nr_pages);
  		}
  		bytes_left -= PAGE_SIZE;
fs/btrfs/compression.h +10 -10
index 8001b700ea3a..00d8439048c9 100644
@@ -31,6 +31,9 @@ struct compressed_bio {
  	/* number of bios pending for this compressed extent */
  	refcount_t pending_bios;
 
+	/* Number of compressed pages in the array */
+	unsigned int nr_pages;
+
  	/* the pages with the compressed data on them */
  	struct page **compressed_pages;
 
@@ -40,20 +43,17 @@ struct compressed_bio {
  	/* starting offset in the inode for our pages */
  	u64 start;
 
-	/* number of bytes in the inode we're working on */
-	unsigned long len;
-
-	/* number of bytes on disk */
-	unsigned long compressed_len;
+	/* Number of bytes in the inode we're working on */
+	unsigned int len;
 
-	/* the compression algorithm for this bio */
-	int compress_type;
+	/* Number of bytes on disk */
+	unsigned int compressed_len;
 
-	/* number of compressed pages in the array */
-	unsigned long nr_pages;
+	/* The compression algorithm for this bio */
+	u8 compress_type;
 
  	/* IO errors */
-	int errors;
+	u8 errors;
  	int mirror_num;
 
  	/* for reads, this is the bio we are copying the data into */
author maintainer
#19 lore raw

PATCH 7/9 btrfs: remove extra sb::s_id from message in btrfs_validate_metadata_buffer

In reply to David Sterba

The s_id is already printed by message helpers.

---
 fs/btrfs/disk-io.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/disk-io.c +2 -2
index 8c3db9076988..6dc137684899 100644
@@ -614,8 +614,8 @@ static int validate_extent_buffer(struct extent_buffer *eb)
 
 		read_extent_buffer(eb, &val, 0, csum_size);
 		btrfs_warn_rl(fs_info,
-	"%s checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
-			      fs_info->sb->s_id, eb->start,
+	"checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
+			      eb->start,
 			      CSUM_FMT_VALUE(csum_size, val),
 			      CSUM_FMT_VALUE(csum_size, result),
 			      btrfs_header_level(eb));
Signature · 1 line
2.29.2
Reviewed-by on v1 7/9
#20 lore raw

Re: [PATCH 7/9] btrfs: remove extra sb::s_id from message in btrfs_validate_metadata_buffer

Quoted 3 lines · David Sterba

The s_id is already printed by message helpers.

Thanks,
Qu

Quoted 20 lines
---
  fs/btrfs/disk-io.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/disk-io.c +2 -2
index 8c3db9076988..6dc137684899 100644
@@ -614,8 +614,8 @@ static int validate_extent_buffer(struct extent_buffer *eb)
 
  		read_extent_buffer(eb, &val, 0, csum_size);
  		btrfs_warn_rl(fs_info,
-	"%s checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
-			      fs_info->sb->s_id, eb->start,
+	"checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
+			      eb->start,
  			      CSUM_FMT_VALUE(csum_size, val),
  			      CSUM_FMT_VALUE(csum_size, result),
  			      btrfs_header_level(eb));
Reviewed-by on v1 7/9
#21 lore raw

Re: [PATCH 7/9] btrfs: remove extra sb::s_id from message in btrfs_validate_metadata_buffer

In reply to David Sterba
Quoted 3 lines · David Sterba

The s_id is already printed by message helpers.

Thanks.

Quoted 20 lines
---
  fs/btrfs/disk-io.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/disk-io.c +2 -2
index 8c3db9076988..6dc137684899 100644
@@ -614,8 +614,8 @@ static int validate_extent_buffer(struct extent_buffer *eb)
 
  		read_extent_buffer(eb, &val, 0, csum_size);
  		btrfs_warn_rl(fs_info,
-	"%s checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
-			      fs_info->sb->s_id, eb->start,
+	"checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
+			      eb->start,
  			      CSUM_FMT_VALUE(csum_size, val),
  			      CSUM_FMT_VALUE(csum_size, result),
  			      btrfs_header_level(eb));
author maintainer
#22 lore raw

PATCH 8/9 btrfs: simplify eb checksum verification in btrfs_validate_metadata_buffer

In reply to David Sterba

The verification copies the calculated checksum bytes to a temporary buffer but this is not necessary. We can map the eb header on the first page and use the checksum bytes directly.

This saves at least one function call and boundary checks so it could lead to a minor performance improvement.

---
 fs/btrfs/disk-io.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
fs/btrfs/disk-io.c +5 -5
index 6dc137684899..868e358f6923 100644
@@ -584,6 +584,7 @@ static int validate_extent_buffer(struct extent_buffer *eb)
 	const u32 csum_size = fs_info->csum_size;
 	u8 found_level;
 	u8 result[BTRFS_CSUM_SIZE];
+	const struct btrfs_header *header;
 	int ret = 0;
 
 	found_start = btrfs_header_bytenr(eb);
@@ -608,15 +609,14 @@ static int validate_extent_buffer(struct extent_buffer *eb)
 	}
 
 	csum_tree_block(eb, result);
+	header = page_address(eb->pages[0]) +
+		 get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));
 
-	if (memcmp_extent_buffer(eb, result, 0, csum_size)) {
-		u8 val[BTRFS_CSUM_SIZE] = { 0 };
-
-		read_extent_buffer(eb, &val, 0, csum_size);
+	if (memcmp(result, header->csum, csum_size) != 0) {
 		btrfs_warn_rl(fs_info,
 	"checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
 			      eb->start,
-			      CSUM_FMT_VALUE(csum_size, val),
+			      CSUM_FMT_VALUE(csum_size, header->csum),
 			      CSUM_FMT_VALUE(csum_size, result),
 			      btrfs_header_level(eb));
 		ret = -EUCLEAN;
Signature · 1 line
2.29.2
Reviewed-by on v1 8/9
#23 lore raw

Re: [PATCH 8/9] btrfs: simplify eb checksum verification in btrfs_validate_metadata_buffer

Quoted 8 lines · David Sterba

The verification copies the calculated checksum bytes to a temporary buffer but this is not necessary. We can map the eb header on the first page and use the checksum bytes directly.

This saves at least one function call and boundary checks so it could lead to a minor performance improvement.

The idea is good, and should be pretty simple to test.

But still a nitpick inlined below.

Quoted 17 lines
---
  fs/btrfs/disk-io.c | 10 +++++-----
  1 file changed, 5 insertions(+), 5 deletions(-)
fs/btrfs/disk-io.c +1 -0
index 6dc137684899..868e358f6923 100644
@@ -584,6 +584,7 @@ static int validate_extent_buffer(struct extent_buffer *eb)
  	const u32 csum_size = fs_info->csum_size;
  	u8 found_level;
  	u8 result[BTRFS_CSUM_SIZE];
+	const struct btrfs_header *header;
  	int ret = 0;
 
  	found_start = btrfs_header_bytenr(eb);

fs/btrfs/disk-io.c static int validate_extent_buffer(struct extent_buffer *eb) · line 613

Quoted 5 lines
fs/btrfs/disk-io.c +2 -0
@@ -608,15 +609,14 @@ static int validate_extent_buffer(struct extent_buffer *eb)
  	}
 
  	csum_tree_block(eb, result);
+	header = page_address(eb->pages[0]) +
+		 get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));

It takes me near a minute to figure why it's not just "get_eb_offset_in_page(eb, 0)".

I'm not sure if we really need that explicit way to just get 0, especially most of us (and even some advanced users) know that csum comes at the very beginning of a tree block.

And the mention of btrfs_leave can sometimes be confusing, especially when we could have tree nodes passed in.

Thanks,
Qu

Quoted 15 lines
fs/btrfs/disk-io.c +2 -5
-	if (memcmp_extent_buffer(eb, result, 0, csum_size)) {
-		u8 val[BTRFS_CSUM_SIZE] = { 0 };
-
-		read_extent_buffer(eb, &val, 0, csum_size);
+	if (memcmp(result, header->csum, csum_size) != 0) {
  		btrfs_warn_rl(fs_info,
  	"checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
  			      eb->start,
-			      CSUM_FMT_VALUE(csum_size, val),
+			      CSUM_FMT_VALUE(csum_size, header->csum),
  			      CSUM_FMT_VALUE(csum_size, result),
  			      btrfs_header_level(eb));
  		ret = -EUCLEAN;
 
#24 lore raw

Re: [PATCH 8/9] btrfs: simplify eb checksum verification in btrfs_validate_metadata_buffer

Quoted 41 lines · Qu Wenruo
Quoted 8 lines · David Sterba

The verification copies the calculated checksum bytes to a temporary buffer but this is not necessary. We can map the eb header on the first page and use the checksum bytes directly.

This saves at least one function call and boundary checks so it could lead to a minor performance improvement.

The idea is good, and should be pretty simple to test.

But still a nitpick inlined below.

Quoted 17 lines
---
  fs/btrfs/disk-io.c | 10 +++++-----
  1 file changed, 5 insertions(+), 5 deletions(-)
fs/btrfs/disk-io.c +1 -0
index 6dc137684899..868e358f6923 100644
@@ -584,6 +584,7 @@ static int validate_extent_buffer(struct extent_buffer *eb)
  	const u32 csum_size = fs_info->csum_size;
  	u8 found_level;
  	u8 result[BTRFS_CSUM_SIZE];
+	const struct btrfs_header *header;
  	int ret = 0;
 
  	found_start = btrfs_header_bytenr(eb);

fs/btrfs/disk-io.c static int validate_extent_buffer(struct extent_buffer *eb) · line 613

Quoted 5 lines
fs/btrfs/disk-io.c +2 -0
@@ -608,15 +609,14 @@ static int validate_extent_buffer(struct extent_buffer *eb)
  	}
 
  	csum_tree_block(eb, result);
+	header = page_address(eb->pages[0]) +
+		 get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));

It takes me near a minute to figure why it's not just "get_eb_offset_in_page(eb, 0)".

Quoted 6 lines

I'm not sure if we really need that explicit way to just get 0, especially most of us (and even some advanced users) know that csum comes at the very beginning of a tree block.

And the mention of btrfs_leave can sometimes be confusing, especially when we could have tree nodes passed in.

Ah right, I wanted to use the offsetof for clarity but that it could be used with nodes makes it confusing again. What if it's replaced by

	get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum));

This makes it clear that it's the checksum and from the experience we know it's at offset 0. I'd rather avoid magic constants and offsets but you're right that everybody knows that the checksum is at the beginning of btree block.

#25 lore raw

Re: [PATCH 8/9] btrfs: simplify eb checksum verification in btrfs_validate_metadata_buffer

Quoted 16 lines · David Sterba
Quoted 6 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	header = page_address(eb->pages[0]) +
+		 get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));

It takes me near a minute to figure why it's not just "get_eb_offset_in_page(eb, 0)".

Quoted 6 lines

I'm not sure if we really need that explicit way to just get 0, especially most of us (and even some advanced users) know that csum comes at the very beginning of a tree block.

And the mention of btrfs_leave can sometimes be confusing, especially when we could have tree nodes passed in.

Ah right, I wanted to use the offsetof for clarity but that it could be used with nodes makes it confusing again. What if it's replaced by

Quoted 6 lines
	get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum));

This makes it clear that it's the checksum and from the experience we know it's at offset 0. I'd rather avoid magic constants and offsets but you're right that everybody knows that the checksum is at the beginning of btree block.

fs/btrfs/disk-io.c +5 -5
@@ -584,7 +584,7 @@ static int validate_extent_buffer(struct extent_buffer *eb)
        const u32 csum_size = fs_info->csum_size;
        u8 found_level;
        u8 result[BTRFS_CSUM_SIZE];
-       const struct btrfs_header *header;
+       const u8 *header_csum;
        int ret = 0;
 
        found_start = btrfs_header_bytenr(eb);
@@ -609,14 +609,14 @@ static int validate_extent_buffer(struct extent_buffer *eb)
        }
 
        csum_tree_block(eb, result);
-       header = page_address(eb->pages[0]) +
-                get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));
+       header_csum = page_address(eb->pages[0]) +
+               get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum));
 
-       if (memcmp(result, header->csum, csum_size) != 0) {
+       if (memcmp(result, header_csum, csum_size) != 0) {
                btrfs_warn_rl(fs_info,
        "checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
                              eb->start,
-                             CSUM_FMT_VALUE(csum_size, header->csum),
+                             CSUM_FMT_VALUE(csum_size, header_csum),
                              CSUM_FMT_VALUE(csum_size, result),
                              btrfs_header_level(eb));
                ret = -EUCLEAN;
#26 lore raw

Re: [PATCH 8/9] btrfs: simplify eb checksum verification in btrfs_validate_metadata_buffer

Quoted 36 lines · David Sterba
Quoted 22 lines · David Sterba
Quoted 6 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	header = page_address(eb->pages[0]) +
+		 get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));

It takes me near a minute to figure why it's not just "get_eb_offset_in_page(eb, 0)".

Quoted 6 lines

I'm not sure if we really need that explicit way to just get 0, especially most of us (and even some advanced users) know that csum comes at the very beginning of a tree block.

And the mention of btrfs_leave can sometimes be confusing, especially when we could have tree nodes passed in.

Ah right, I wanted to use the offsetof for clarity but that it could be used with nodes makes it confusing again. What if it's replaced by

	get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum));

This makes it clear that it's the checksum and from the experience we know it's at offset 0. I'd rather avoid magic constants and offsets but you're right that everybody knows that the checksum is at the beginning of btree block.

fs/btrfs/disk-io.c +1 -1
@@ -584,7 +584,7 @@ static int validate_extent_buffer(struct extent_buffer *eb)
         const u32 csum_size = fs_info->csum_size;
         u8 found_level;
         u8 result[BTRFS_CSUM_SIZE];
-       const struct btrfs_header *header;
+       const u8 *header_csum;
         int ret = 0;
 
         found_start = btrfs_header_bytenr(eb);

fs/btrfs/disk-io.c static int validate_extent_buffer(struct extent_buffer *eb) · line 613

Quoted 7 lines
fs/btrfs/disk-io.c +2 -2
@@ -609,14 +609,14 @@ static int validate_extent_buffer(struct extent_buffer *eb)
         }
 
         csum_tree_block(eb, result);
-       header = page_address(eb->pages[0]) +
-                get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));
+       header_csum = page_address(eb->pages[0]) +
+               get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum));

This version looks better to me.

THanks,
Qu

Quoted 12 lines
fs/btrfs/disk-io.c +2 -2
-       if (memcmp(result, header->csum, csum_size) != 0) {
+       if (memcmp(result, header_csum, csum_size) != 0) {
                 btrfs_warn_rl(fs_info,
         "checksum verify failed on %llu wanted " CSUM_FMT " found " CSUM_FMT " level %d",
                               eb->start,
-                             CSUM_FMT_VALUE(csum_size, header->csum),
+                             CSUM_FMT_VALUE(csum_size, header_csum),
                               CSUM_FMT_VALUE(csum_size, result),
                               btrfs_header_level(eb));
                 ret = -EUCLEAN;
 
#27 lore raw

Re: [PATCH 8/9] btrfs: simplify eb checksum verification in btrfs_validate_metadata_buffer

Quoted 41 lines · Qu Wenruo
Quoted 38 lines · David Sterba
Quoted 22 lines · David Sterba
Quoted 6 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	header = page_address(eb->pages[0]) +
+		 get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));

It takes me near a minute to figure why it's not just "get_eb_offset_in_page(eb, 0)".

Quoted 6 lines

I'm not sure if we really need that explicit way to just get 0, especially most of us (and even some advanced users) know that csum comes at the very beginning of a tree block.

And the mention of btrfs_leave can sometimes be confusing, especially when we could have tree nodes passed in.

Ah right, I wanted to use the offsetof for clarity but that it could be used with nodes makes it confusing again. What if it's replaced by

	get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum));

This makes it clear that it's the checksum and from the experience we know it's at offset 0. I'd rather avoid magic constants and offsets but you're right that everybody knows that the checksum is at the beginning of btree block.

fs/btrfs/disk-io.c +1 -1
@@ -584,7 +584,7 @@ static int validate_extent_buffer(struct extent_buffer *eb)
         const u32 csum_size = fs_info->csum_size;
         u8 found_level;
         u8 result[BTRFS_CSUM_SIZE];
-       const struct btrfs_header *header;
+       const u8 *header_csum;
         int ret = 0;
 
         found_start = btrfs_header_bytenr(eb);
@@ -609,14 +609,14 @@ static int validate_extent_buffer(struct extent_buffer *eb)
         }
 
Quoted 7 lines

fs/btrfs/disk-io.c static int validate_extent_buffer(struct extent_buffer *eb) · line 613

Quoted 5 lines
fs/btrfs/disk-io.c +2 -2
         csum_tree_block(eb, result);
-       header = page_address(eb->pages[0]) +
-                get_eb_offset_in_page(eb, offsetof(struct btrfs_leaf, header));
+       header_csum = page_address(eb->pages[0]) +
+               get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum));

This version looks better to me.

Thanks, I've preemptively squashed it to the commit, now in misc-next.

author maintainer
#28 lore raw

PATCH 9/9 btrfs: clean up header members offsets in write helpers

In reply to David Sterba

Move header offsetof() to the expression that calculates the address so it's part of get_eb_offset_in_page where the 2nd parameter is the member offset.

---
 fs/btrfs/extent_io.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
fs/btrfs/extent_io.c +7 -6
index 2b250c610562..2e924f60ea6f 100644
@@ -6519,9 +6519,10 @@ void write_extent_buffer_chunk_tree_uuid(const struct extent_buffer *eb,
 	char *kaddr;
 
 	assert_eb_page_uptodate(eb, eb->pages[0]);
-	kaddr = page_address(eb->pages[0]) + get_eb_offset_in_page(eb, 0);
-	memcpy(kaddr + offsetof(struct btrfs_header, chunk_tree_uuid), srcv,
-			BTRFS_FSID_SIZE);
+	kaddr = page_address(eb->pages[0]) +
+		get_eb_offset_in_page(eb, offsetof(struct btrfs_header,
+						   chunk_tree_uuid));
+	memcpy(kaddr, srcv, BTRFS_FSID_SIZE);
 }
 
 void write_extent_buffer_fsid(const struct extent_buffer *eb, const void *srcv)
@@ -6529,9 +6530,9 @@ void write_extent_buffer_fsid(const struct extent_buffer *eb, const void *srcv)
 	char *kaddr;
 
 	assert_eb_page_uptodate(eb, eb->pages[0]);
-	kaddr = page_address(eb->pages[0]) + get_eb_offset_in_page(eb, 0);
-	memcpy(kaddr + offsetof(struct btrfs_header, fsid), srcv,
-			BTRFS_FSID_SIZE);
+	kaddr = page_address(eb->pages[0]) +
+		get_eb_offset_in_page(eb, offsetof(struct btrfs_header, fsid));
+	memcpy(kaddr, srcv, BTRFS_FSID_SIZE);
 }
 
 void write_extent_buffer(const struct extent_buffer *eb, const void *srcv,
Signature · 1 line
2.29.2
Reviewed-by on v1 9/9
#29 lore raw

Re: [PATCH 9/9] btrfs: clean up header members offsets in write helpers

Quoted 5 lines · David Sterba

Move header offsetof() to the expression that calculates the address so it's part of get_eb_offset_in_page where the 2nd parameter is the member offset.

Indeed better than the original expression.

Thanks,
Qu

Quoted 36 lines
---
  fs/btrfs/extent_io.c | 13 +++++++------
  1 file changed, 7 insertions(+), 6 deletions(-)
fs/btrfs/extent_io.c +7 -6
index 2b250c610562..2e924f60ea6f 100644
@@ -6519,9 +6519,10 @@ void write_extent_buffer_chunk_tree_uuid(const struct extent_buffer *eb,
  	char *kaddr;
 
  	assert_eb_page_uptodate(eb, eb->pages[0]);
-	kaddr = page_address(eb->pages[0]) + get_eb_offset_in_page(eb, 0);
-	memcpy(kaddr + offsetof(struct btrfs_header, chunk_tree_uuid), srcv,
-			BTRFS_FSID_SIZE);
+	kaddr = page_address(eb->pages[0]) +
+		get_eb_offset_in_page(eb, offsetof(struct btrfs_header,
+						   chunk_tree_uuid));
+	memcpy(kaddr, srcv, BTRFS_FSID_SIZE);
  }
 
  void write_extent_buffer_fsid(const struct extent_buffer *eb, const void *srcv)
@@ -6529,9 +6530,9 @@ void write_extent_buffer_fsid(const struct extent_buffer *eb, const void *srcv)
  	char *kaddr;
 
  	assert_eb_page_uptodate(eb, eb->pages[0]);
-	kaddr = page_address(eb->pages[0]) + get_eb_offset_in_page(eb, 0);
-	memcpy(kaddr + offsetof(struct btrfs_header, fsid), srcv,
-			BTRFS_FSID_SIZE);
+	kaddr = page_address(eb->pages[0]) +
+		get_eb_offset_in_page(eb, offsetof(struct btrfs_header, fsid));
+	memcpy(kaddr, srcv, BTRFS_FSID_SIZE);
  }
 
  void write_extent_buffer(const struct extent_buffer *eb, const void *srcv,