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>
This commit is contained in:
Родитель
2e78c927d7
Коммит
c40a3d38af
|
@ -172,6 +172,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
|
||||||
u64 item_start_offset = 0;
|
u64 item_start_offset = 0;
|
||||||
u64 item_last_offset = 0;
|
u64 item_last_offset = 0;
|
||||||
u64 disk_bytenr;
|
u64 disk_bytenr;
|
||||||
|
u64 page_bytes_left;
|
||||||
u32 diff;
|
u32 diff;
|
||||||
int nblocks;
|
int nblocks;
|
||||||
int bio_index = 0;
|
int bio_index = 0;
|
||||||
|
@ -220,6 +221,8 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
|
||||||
disk_bytenr = (u64)bio->bi_iter.bi_sector << 9;
|
disk_bytenr = (u64)bio->bi_iter.bi_sector << 9;
|
||||||
if (dio)
|
if (dio)
|
||||||
offset = logical_offset;
|
offset = logical_offset;
|
||||||
|
|
||||||
|
page_bytes_left = bvec->bv_len;
|
||||||
while (bio_index < bio->bi_vcnt) {
|
while (bio_index < bio->bi_vcnt) {
|
||||||
if (!dio)
|
if (!dio)
|
||||||
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
|
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
|
||||||
|
@ -243,7 +246,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
|
||||||
if (BTRFS_I(inode)->root->root_key.objectid ==
|
if (BTRFS_I(inode)->root->root_key.objectid ==
|
||||||
BTRFS_DATA_RELOC_TREE_OBJECTID) {
|
BTRFS_DATA_RELOC_TREE_OBJECTID) {
|
||||||
set_extent_bits(io_tree, offset,
|
set_extent_bits(io_tree, offset,
|
||||||
offset + bvec->bv_len - 1,
|
offset + root->sectorsize - 1,
|
||||||
EXTENT_NODATASUM, GFP_NOFS);
|
EXTENT_NODATASUM, GFP_NOFS);
|
||||||
} else {
|
} else {
|
||||||
btrfs_info(BTRFS_I(inode)->root->fs_info,
|
btrfs_info(BTRFS_I(inode)->root->fs_info,
|
||||||
|
@ -281,11 +284,17 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
|
||||||
found:
|
found:
|
||||||
csum += count * csum_size;
|
csum += count * csum_size;
|
||||||
nblocks -= count;
|
nblocks -= count;
|
||||||
bio_index += count;
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
disk_bytenr += bvec->bv_len;
|
disk_bytenr += root->sectorsize;
|
||||||
offset += bvec->bv_len;
|
offset += root->sectorsize;
|
||||||
bvec++;
|
page_bytes_left -= root->sectorsize;
|
||||||
|
if (!page_bytes_left) {
|
||||||
|
bio_index++;
|
||||||
|
bvec++;
|
||||||
|
page_bytes_left = bvec->bv_len;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
|
@ -432,6 +441,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
|
||||||
struct bio_vec *bvec = bio->bi_io_vec;
|
struct bio_vec *bvec = bio->bi_io_vec;
|
||||||
int bio_index = 0;
|
int bio_index = 0;
|
||||||
int index;
|
int index;
|
||||||
|
int nr_sectors;
|
||||||
|
int i;
|
||||||
unsigned long total_bytes = 0;
|
unsigned long total_bytes = 0;
|
||||||
unsigned long this_sum_bytes = 0;
|
unsigned long this_sum_bytes = 0;
|
||||||
u64 offset;
|
u64 offset;
|
||||||
|
@ -459,41 +470,56 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
|
||||||
if (!contig)
|
if (!contig)
|
||||||
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
|
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
|
||||||
|
|
||||||
if (offset >= ordered->file_offset + ordered->len ||
|
data = kmap_atomic(bvec->bv_page);
|
||||||
offset < ordered->file_offset) {
|
|
||||||
unsigned long bytes_left;
|
|
||||||
sums->len = this_sum_bytes;
|
|
||||||
this_sum_bytes = 0;
|
|
||||||
btrfs_add_ordered_sum(inode, ordered, sums);
|
|
||||||
btrfs_put_ordered_extent(ordered);
|
|
||||||
|
|
||||||
bytes_left = bio->bi_iter.bi_size - total_bytes;
|
nr_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info,
|
||||||
|
bvec->bv_len + root->sectorsize
|
||||||
|
- 1);
|
||||||
|
|
||||||
sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
|
for (i = 0; i < nr_sectors; i++) {
|
||||||
GFP_NOFS);
|
if (offset >= ordered->file_offset + ordered->len ||
|
||||||
BUG_ON(!sums); /* -ENOMEM */
|
offset < ordered->file_offset) {
|
||||||
sums->len = bytes_left;
|
unsigned long bytes_left;
|
||||||
ordered = btrfs_lookup_ordered_extent(inode, offset);
|
|
||||||
BUG_ON(!ordered); /* Logic error */
|
kunmap_atomic(data);
|
||||||
sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9) +
|
sums->len = this_sum_bytes;
|
||||||
total_bytes;
|
this_sum_bytes = 0;
|
||||||
index = 0;
|
btrfs_add_ordered_sum(inode, ordered, sums);
|
||||||
|
btrfs_put_ordered_extent(ordered);
|
||||||
|
|
||||||
|
bytes_left = bio->bi_iter.bi_size - total_bytes;
|
||||||
|
|
||||||
|
sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
|
||||||
|
GFP_NOFS);
|
||||||
|
BUG_ON(!sums); /* -ENOMEM */
|
||||||
|
sums->len = bytes_left;
|
||||||
|
ordered = btrfs_lookup_ordered_extent(inode,
|
||||||
|
offset);
|
||||||
|
ASSERT(ordered); /* Logic error */
|
||||||
|
sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9)
|
||||||
|
+ total_bytes;
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
data = kmap_atomic(bvec->bv_page);
|
||||||
|
}
|
||||||
|
|
||||||
|
sums->sums[index] = ~(u32)0;
|
||||||
|
sums->sums[index]
|
||||||
|
= btrfs_csum_data(data + bvec->bv_offset
|
||||||
|
+ (i * root->sectorsize),
|
||||||
|
sums->sums[index],
|
||||||
|
root->sectorsize);
|
||||||
|
btrfs_csum_final(sums->sums[index],
|
||||||
|
(char *)(sums->sums + index));
|
||||||
|
index++;
|
||||||
|
offset += root->sectorsize;
|
||||||
|
this_sum_bytes += root->sectorsize;
|
||||||
|
total_bytes += root->sectorsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = kmap_atomic(bvec->bv_page);
|
|
||||||
sums->sums[index] = ~(u32)0;
|
|
||||||
sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset,
|
|
||||||
sums->sums[index],
|
|
||||||
bvec->bv_len);
|
|
||||||
kunmap_atomic(data);
|
kunmap_atomic(data);
|
||||||
btrfs_csum_final(sums->sums[index],
|
|
||||||
(char *)(sums->sums + index));
|
|
||||||
|
|
||||||
bio_index++;
|
bio_index++;
|
||||||
index++;
|
|
||||||
total_bytes += bvec->bv_len;
|
|
||||||
this_sum_bytes += bvec->bv_len;
|
|
||||||
offset += bvec->bv_len;
|
|
||||||
bvec++;
|
bvec++;
|
||||||
}
|
}
|
||||||
this_sum_bytes = 0;
|
this_sum_bytes = 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче