From: Chandra Seetharaman <sekharan@us.ibm.com>
To: linux-btrfs@vger.kernel.org
Cc: Chandra Seetharaman <sekharan@us.ibm.com>
Subject: [PATCH 5/7] btrfs: subpagesize-blocksize: handle checksum calculations properly
Date: Wed, 11 Dec 2013 17:38:40 -0600 [thread overview]
Message-ID: <1386805122-23972-6-git-send-email-sekharan@us.ibm.com> (raw)
In-Reply-To: <1386805122-23972-1-git-send-email-sekharan@us.ibm.com>
With subpagesize-blocksize, the IO is done in pages but checksums are
calculated in blocks.
This patch makes sure the checksums are calculated, stored, and verfied
from proper indexes in the page.
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
fs/btrfs/file-item.c | 45 ++++++++++++++++++++++++++++++++++++---------
fs/btrfs/inode.c | 26 ++++++++++++++++++++------
2 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 6f38488..d75bda3 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -175,14 +175,16 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
u32 diff;
int nblocks;
int bio_index = 0;
- int count;
+ int count, bvec_count;
u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
+ unsigned int blocks_per_bvec;
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
nblocks = bio->bi_size >> inode->i_sb->s_blocksize_bits;
+ blocks_per_bvec = bvec->bv_len >> inode->i_sb->s_blocksize_bits;
if (!dst) {
if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) {
btrfs_bio->csum_allocated = kmalloc(nblocks * csum_size,
@@ -221,8 +223,10 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
if (dio)
offset = logical_offset;
while (bio_index < bio->bi_vcnt) {
+ bvec_count = 0;
if (!dio)
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
+same_bvec:
count = btrfs_find_ordered_sum(inode, offset, disk_bytenr,
(u32 *)csum, nblocks);
if (count)
@@ -281,12 +285,26 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
found:
csum += count * csum_size;
nblocks -= count;
- while (count--) {
+ while (count >= blocks_per_bvec) {
+ count -= blocks_per_bvec;
disk_bytenr += bvec->bv_len;
offset += bvec->bv_len;
bio_index++;
bvec++;
}
+
+ if (count) {
+ while (count--) {
+ bvec_count++;
+ disk_bytenr += inode->i_sb->s_blocksize;
+ offset += inode->i_sb->s_blocksize;
+ }
+ if (bvec_count == blocks_per_bvec) {
+ bio_index++;
+ bvec++;
+ } else
+ goto same_bvec;
+ }
}
btrfs_free_path(path);
return 0;
@@ -444,7 +462,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
int index;
unsigned long total_bytes = 0;
unsigned long this_sum_bytes = 0;
- u64 offset;
+ u64 offset, pg_offset;
+ size_t csum_size;
WARN_ON(bio->bi_vcnt <= 0);
sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS);
@@ -489,17 +508,25 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
index = 0;
}
+ if ((inode->i_sb->s_blocksize) < bvec->bv_len)
+ csum_size = inode->i_sb->s_blocksize;
+ else
+ csum_size = bvec->bv_len;
data = kmap_atomic(bvec->bv_page);
- sums->sums[index] = ~(u32)0;
- sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset,
+ pg_offset = bvec->bv_offset;
+ while (pg_offset < bvec->bv_offset + bvec->bv_len) {
+ sums->sums[index] = ~(u32)0;
+ sums->sums[index] = btrfs_csum_data(data + pg_offset,
sums->sums[index],
- bvec->bv_len);
+ csum_size);
+ btrfs_csum_final(sums->sums[index],
+ (char *)(sums->sums + index));
+ index++;
+ pg_offset += csum_size;
+ }
kunmap_atomic(data);
- btrfs_csum_final(sums->sums[index],
- (char *)(sums->sums + index));
bio_index++;
- index++;
total_bytes += bvec->bv_len;
this_sum_bytes += bvec->bv_len;
offset += bvec->bv_len;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c0c18ca..a87d0d0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2781,6 +2781,7 @@ static int btrfs_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
struct btrfs_root *root = BTRFS_I(inode)->root;
u32 csum_expected;
u32 csum = ~(u32)0;
+ u64 total_len, csum_len, csum_index;
static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
@@ -2799,14 +2800,27 @@ static int btrfs_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
return 0;
}
- phy_offset >>= inode->i_sb->s_blocksize_bits;
- csum_expected = *(((u32 *)io_bio->csum) + phy_offset);
+ total_len = end - start + 1;
+ if (inode->i_sb->s_blocksize < PAGE_CACHE_SIZE)
+ csum_len = inode->i_sb->s_blocksize;
+ else
+ csum_len = end - start + 1;
+
+ csum_index = phy_offset >> inode->i_sb->s_blocksize_bits;
kaddr = kmap_atomic(page);
- csum = btrfs_csum_data(kaddr + offset, csum, end - start + 1);
- btrfs_csum_final(csum, (char *)&csum);
- if (csum != csum_expected)
- goto zeroit;
+ while (total_len > 0) {
+ csum_expected = *(((u32 *)io_bio->csum) + csum_index);
+ csum = ~(u32)0;
+ csum = btrfs_csum_data(kaddr + offset, csum, csum_len);
+ btrfs_csum_final(csum, (char *)&csum);
+ if (csum != csum_expected)
+ goto zeroit;
+ offset += csum_len;
+ total_len -= csum_len;
+ csum_index += 1;
+ phy_offset += csum_len;
+ }
kunmap_atomic(kaddr);
good:
--
1.7.12.4
next prev parent reply other threads:[~2013-12-11 23:40 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-11 23:38 [PATCH 0/7] Patches to support subpagesize blocksize Chandra Seetharaman
2013-12-11 23:38 ` [PATCH 1/7] btrfs: subpagesize-blocksize: Define extent_buffer_head Chandra Seetharaman
2013-12-16 12:32 ` saeed bishara
2013-12-16 16:17 ` Chandra Seetharaman
2013-12-17 15:35 ` David Sterba
2013-12-11 23:38 ` [PATCH 2/7] btrfs: subpagesize-blocksize: Use a global alignment for size Chandra Seetharaman
2013-12-16 12:33 ` saeed bishara
2013-12-16 14:48 ` David Sterba
2013-12-16 16:18 ` Chandra Seetharaman
2013-12-11 23:38 ` [PATCH 3/7] btrfs: subpagesize-blocksize: Handle small extent maps properly Chandra Seetharaman
2013-12-11 23:38 ` [PATCH 4/7] btrfs: subpagesize-blocksize: Handle iosize properly in submit_extent_page() Chandra Seetharaman
2013-12-11 23:38 ` Chandra Seetharaman [this message]
2013-12-11 23:38 ` [PATCH 6/7] btrfs: subpagesize-blocksize: Handle relocation clusters appropriately Chandra Seetharaman
2013-12-11 23:38 ` [PATCH 7/7] btrfs: subpagesize-blocksize: Allow mounting filesystems where sectorsize != PAGE_SIZE Chandra Seetharaman
2013-12-13 1:07 ` David Sterba
2013-12-16 12:50 ` saeed bishara
2013-12-12 20:40 ` [PATCH 0/7] Patches to support subpagesize blocksize Josef Bacik
2013-12-13 1:17 ` David Sterba
2013-12-13 15:17 ` Chandra Seetharaman
2013-12-13 15:58 ` David Sterba
2013-12-13 18:39 ` Josef Bacik
2013-12-13 22:09 ` Chandra Seetharaman
2014-01-08 20:06 ` Chandra Seetharaman
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=1386805122-23972-6-git-send-email-sekharan@us.ibm.com \
--to=sekharan@us.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).