Message ID | 20201103133108.148112-15-wqu@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/32] btrfs: extent_io: remove the extent_start/extent_len for end_bio_extent_readpage() | expand |
On 3.11.20 г. 15:30 ч., Qu Wenruo wrote: > Currently btrfs_readpage_end_io_hook() just pass the whole page to > check_data_csum(), which is fine since we only support sectorsize == > PAGE_SIZE. > > To support subpage, we need to properly honor per-sector > checksum verification, just like what we did in dio read path. > > This patch will do the csum verification in a for loop, starts with > pg_off == start - page_offset(page), with sectorsize increasement for > each loop. > > For sectorsize == PAGE_SIZE case, the pg_off will always be 0, and we > will only finish with just one loop. > > For subpage case, we do the loop to iterate each sector and if we found > any error, we return error. You refer to btrfs_readpage_end_io_hook but you actually change btrfs_verity_data_csum. I guess the changelog needs adjusting. > > Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> > Signed-off-by: Qu Wenruo <wqu@suse.com> > --- > fs/btrfs/inode.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index c54e0ed0b938..0432ca58eade 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -2888,9 +2888,11 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, > struct page *page, u64 start, u64 end, int mirror) > { > size_t offset = start - page_offset(page); > + size_t pg_off; nit: For offsets we should be using a more self-descriptive type such as loff_t > struct inode *inode = page->mapping->host; > struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; > struct btrfs_root *root = BTRFS_I(inode)->root; > + u32 sectorsize = root->fs_info->sectorsize; > > if (PageChecked(page)) { > ClearPageChecked(page); > @@ -2910,7 +2912,15 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, > } > > phy_offset >>= root->fs_info->sectorsize_bits; > - return check_data_csum(inode, io_bio, phy_offset, page, offset); > + for (pg_off = offset; pg_off < end - page_offset(page); > + pg_off += sectorsize, phy_offset++) { > + int ret; > + > + ret = check_data_csum(inode, io_bio, phy_offset, page, pg_off); > + if (ret < 0) > + return -EIO; > + } > + return 0; > } > > /* >
On Thu, Nov 05, 2020 at 04:28:12PM +0200, Nikolay Borisov wrote: > > > On 3.11.20 г. 15:30 ч., Qu Wenruo wrote: > > Currently btrfs_readpage_end_io_hook() just pass the whole page to > > check_data_csum(), which is fine since we only support sectorsize == > > PAGE_SIZE. > > > > To support subpage, we need to properly honor per-sector > > checksum verification, just like what we did in dio read path. > > > > This patch will do the csum verification in a for loop, starts with > > pg_off == start - page_offset(page), with sectorsize increasement for > > each loop. > > > > For sectorsize == PAGE_SIZE case, the pg_off will always be 0, and we > > will only finish with just one loop. > > > > For subpage case, we do the loop to iterate each sector and if we found > > any error, we return error. > > You refer to btrfs_readpage_end_io_hook but you actually change > btrfs_verity_data_csum. I guess the changelog needs adjusting. > > > > > Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> > > Signed-off-by: Qu Wenruo <wqu@suse.com> > > --- > > fs/btrfs/inode.c | 12 +++++++++++- > > 1 file changed, 11 insertions(+), 1 deletion(-) > > > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > > index c54e0ed0b938..0432ca58eade 100644 > > --- a/fs/btrfs/inode.c > > +++ b/fs/btrfs/inode.c > > @@ -2888,9 +2888,11 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, > > struct page *page, u64 start, u64 end, int mirror) > > { > > size_t offset = start - page_offset(page); > > + size_t pg_off; > > nit: For offsets we should be using a more self-descriptive type such as > loff_t loff_t is meant for file offsets and is an overkill when it's used for offset in page that's fine with an u32.
On Fri, Nov 06, 2020 at 08:16:08PM +0100, David Sterba wrote: > On Thu, Nov 05, 2020 at 04:28:12PM +0200, Nikolay Borisov wrote: > > On 3.11.20 г. 15:30 ч., Qu Wenruo wrote: > > > --- a/fs/btrfs/inode.c > > > +++ b/fs/btrfs/inode.c > > > @@ -2888,9 +2888,11 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, > > > struct page *page, u64 start, u64 end, int mirror) > > > { > > > size_t offset = start - page_offset(page); > > > + size_t pg_off; > > > > nit: For offsets we should be using a more self-descriptive type such as > > loff_t > > loff_t is meant for file offsets and is an overkill when it's used for > offset in page that's fine with an u32. Ok, so page_offset also uses loff_t but there are now mixed loff_t, size_t and u64 in the function so I'd rather make it all u64.
On Tue, Nov 03, 2020 at 09:30:50PM +0800, Qu Wenruo wrote: > Currently btrfs_readpage_end_io_hook() just pass the whole page to > check_data_csum(), which is fine since we only support sectorsize == > PAGE_SIZE. > > To support subpage, we need to properly honor per-sector > checksum verification, just like what we did in dio read path. > > This patch will do the csum verification in a for loop, starts with > pg_off == start - page_offset(page), with sectorsize increasement for > each loop. > > For sectorsize == PAGE_SIZE case, the pg_off will always be 0, and we > will only finish with just one loop. > > For subpage case, we do the loop to iterate each sector and if we found > any error, we return error. > > Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> > Signed-off-by: Qu Wenruo <wqu@suse.com> > --- > fs/btrfs/inode.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index c54e0ed0b938..0432ca58eade 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -2888,9 +2888,11 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, > struct page *page, u64 start, u64 end, int mirror) > { > size_t offset = start - page_offset(page); > + size_t pg_off; > struct inode *inode = page->mapping->host; > struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; > struct btrfs_root *root = BTRFS_I(inode)->root; > + u32 sectorsize = root->fs_info->sectorsize; > > if (PageChecked(page)) { > ClearPageChecked(page); > @@ -2910,7 +2912,15 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, > } > > phy_offset >>= root->fs_info->sectorsize_bits; > - return check_data_csum(inode, io_bio, phy_offset, page, offset); > + for (pg_off = offset; pg_off < end - page_offset(page); You can reause offset and not add pg_off. > + pg_off += sectorsize, phy_offset++) { phy_offsset is u64 > + int ret; > + > + ret = check_data_csum(inode, io_bio, phy_offset, page, pg_off); Here it's passed as 'int icsum' to check_data_csum and pg_off is 'int pgoff', like what's on here ... > + if (ret < 0) > + return -EIO; > + } > + return 0; > } > > /* > -- > 2.29.2
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c54e0ed0b938..0432ca58eade 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2888,9 +2888,11 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, struct page *page, u64 start, u64 end, int mirror) { size_t offset = start - page_offset(page); + size_t pg_off; struct inode *inode = page->mapping->host; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_root *root = BTRFS_I(inode)->root; + u32 sectorsize = root->fs_info->sectorsize; if (PageChecked(page)) { ClearPageChecked(page); @@ -2910,7 +2912,15 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset, } phy_offset >>= root->fs_info->sectorsize_bits; - return check_data_csum(inode, io_bio, phy_offset, page, offset); + for (pg_off = offset; pg_off < end - page_offset(page); + pg_off += sectorsize, phy_offset++) { + int ret; + + ret = check_data_csum(inode, io_bio, phy_offset, page, pg_off); + if (ret < 0) + return -EIO; + } + return 0; } /*