[PATCH v2 09/19] btrfs: make csum_tree_block() handle sectorsize smaller than page size

Qu Wenruo
2020-09-15T05:36:06Z

For subpage size support, we only need to handle the first page.

To make the code work for both cases, we modify the following behaviors:

- num_pages calcuation
Instead of "nodesize >> PAGE_SHIFT", we go
"DIV_ROUND_UP(nodesize, PAGE_SIZE)", this ensures we get at least one
page for subpage size support, while still get the same result for
reguar page size.

- The length for the first run
Instead of PAGE_SIZE - BTRFS_CSUM_SIZE, we go min(PAGE_SIZE, nodesize)
- BTRFS_CSUM_SIZE.
This allows us to handle both cases well.

- The start location of the first run
Instead of always use BTRFS_CSUM_SIZE as csum start position, add
offset_in_page(eb->start) to get proper offset for both cases.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
fs/btrfs/disk-io.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f6bba7eb1fa1..62dbd9bbd381 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -257,16 +257,16 @@ struct extent_map *btree_get_extent(struct btrfs_inode *inode,
static void csum_tree_block(struct extent_buffer *buf, u8 *result)
{
struct btrfs_fs_info *fs_info = buf->fs_info;
- const int num_pages = fs_info->nodesize >> PAGE_SHIFT;
+ const int num_pages = DIV_ROUND_UP(fs_info->nodesize, PAGE_SIZE);
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
char *kaddr;
int i;

shash->tfm = fs_info->csum_shash;
crypto_shash_init(shash);
- kaddr = page_address(buf->pages[0]);
+ kaddr = page_address(buf->pages[0]) + offset_in_page(buf->start);
crypto_shash_update(shash, kaddr + BTRFS_CSUM_SIZE,
- PAGE_SIZE - BTRFS_CSUM_SIZE);
+ min_t(u32, PAGE_SIZE, fs_info->nodesize) - BTRFS_CSUM_SIZE);

for (i = 1; i < num_pages; i++) {
kaddr = page_address(buf->pages[i]);
--
2.28.0