Skip to content

Commit c40a3d3

Browse files
Chandan Rajendrakdave
authored andcommitted
Btrfs: Compute and look up csums based on sectorsized blocks
Checksums are applicable to sectorsize units. The current code uses bio->bv_len units to compute and look up checksums. This works on machines where sectorsize == PAGE_SIZE. This patch makes the checksum computation and look up code to work with sectorsize units. Reviewed-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 2e78c92 commit c40a3d3

File tree

1 file changed

+59
-33
lines changed

1 file changed

+59
-33
lines changed

fs/btrfs/file-item.c

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
172172
u64 item_start_offset = 0;
173173
u64 item_last_offset = 0;
174174
u64 disk_bytenr;
175+
u64 page_bytes_left;
175176
u32 diff;
176177
int nblocks;
177178
int bio_index = 0;
@@ -220,6 +221,8 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
220221
disk_bytenr = (u64)bio->bi_iter.bi_sector << 9;
221222
if (dio)
222223
offset = logical_offset;
224+
225+
page_bytes_left = bvec->bv_len;
223226
while (bio_index < bio->bi_vcnt) {
224227
if (!dio)
225228
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
@@ -243,7 +246,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
243246
if (BTRFS_I(inode)->root->root_key.objectid ==
244247
BTRFS_DATA_RELOC_TREE_OBJECTID) {
245248
set_extent_bits(io_tree, offset,
246-
offset + bvec->bv_len - 1,
249+
offset + root->sectorsize - 1,
247250
EXTENT_NODATASUM, GFP_NOFS);
248251
} else {
249252
btrfs_info(BTRFS_I(inode)->root->fs_info,
@@ -281,11 +284,17 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
281284
found:
282285
csum += count * csum_size;
283286
nblocks -= count;
284-
bio_index += count;
287+
285288
while (count--) {
286-
disk_bytenr += bvec->bv_len;
287-
offset += bvec->bv_len;
288-
bvec++;
289+
disk_bytenr += root->sectorsize;
290+
offset += root->sectorsize;
291+
page_bytes_left -= root->sectorsize;
292+
if (!page_bytes_left) {
293+
bio_index++;
294+
bvec++;
295+
page_bytes_left = bvec->bv_len;
296+
}
297+
289298
}
290299
}
291300
btrfs_free_path(path);
@@ -432,6 +441,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
432441
struct bio_vec *bvec = bio->bi_io_vec;
433442
int bio_index = 0;
434443
int index;
444+
int nr_sectors;
445+
int i;
435446
unsigned long total_bytes = 0;
436447
unsigned long this_sum_bytes = 0;
437448
u64 offset;
@@ -459,41 +470,56 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
459470
if (!contig)
460471
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
461472

462-
if (offset >= ordered->file_offset + ordered->len ||
463-
offset < ordered->file_offset) {
464-
unsigned long bytes_left;
465-
sums->len = this_sum_bytes;
466-
this_sum_bytes = 0;
467-
btrfs_add_ordered_sum(inode, ordered, sums);
468-
btrfs_put_ordered_extent(ordered);
473+
data = kmap_atomic(bvec->bv_page);
469474

470-
bytes_left = bio->bi_iter.bi_size - total_bytes;
475+
nr_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info,
476+
bvec->bv_len + root->sectorsize
477+
- 1);
478+
479+
for (i = 0; i < nr_sectors; i++) {
480+
if (offset >= ordered->file_offset + ordered->len ||
481+
offset < ordered->file_offset) {
482+
unsigned long bytes_left;
483+
484+
kunmap_atomic(data);
485+
sums->len = this_sum_bytes;
486+
this_sum_bytes = 0;
487+
btrfs_add_ordered_sum(inode, ordered, sums);
488+
btrfs_put_ordered_extent(ordered);
489+
490+
bytes_left = bio->bi_iter.bi_size - total_bytes;
491+
492+
sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
493+
GFP_NOFS);
494+
BUG_ON(!sums); /* -ENOMEM */
495+
sums->len = bytes_left;
496+
ordered = btrfs_lookup_ordered_extent(inode,
497+
offset);
498+
ASSERT(ordered); /* Logic error */
499+
sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9)
500+
+ total_bytes;
501+
index = 0;
502+
503+
data = kmap_atomic(bvec->bv_page);
504+
}
471505

472-
sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
473-
GFP_NOFS);
474-
BUG_ON(!sums); /* -ENOMEM */
475-
sums->len = bytes_left;
476-
ordered = btrfs_lookup_ordered_extent(inode, offset);
477-
BUG_ON(!ordered); /* Logic error */
478-
sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9) +
479-
total_bytes;
480-
index = 0;
506+
sums->sums[index] = ~(u32)0;
507+
sums->sums[index]
508+
= btrfs_csum_data(data + bvec->bv_offset
509+
+ (i * root->sectorsize),
510+
sums->sums[index],
511+
root->sectorsize);
512+
btrfs_csum_final(sums->sums[index],
513+
(char *)(sums->sums + index));
514+
index++;
515+
offset += root->sectorsize;
516+
this_sum_bytes += root->sectorsize;
517+
total_bytes += root->sectorsize;
481518
}
482519

483-
data = kmap_atomic(bvec->bv_page);
484-
sums->sums[index] = ~(u32)0;
485-
sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset,
486-
sums->sums[index],
487-
bvec->bv_len);
488520
kunmap_atomic(data);
489-
btrfs_csum_final(sums->sums[index],
490-
(char *)(sums->sums + index));
491521

492522
bio_index++;
493-
index++;
494-
total_bytes += bvec->bv_len;
495-
this_sum_bytes += bvec->bv_len;
496-
offset += bvec->bv_len;
497523
bvec++;
498524
}
499525
this_sum_bytes = 0;

0 commit comments

Comments
 (0)