Skip to content

Commit e331f6b

Browse files
osandovkdave
authored andcommitted
btrfs: don't advance offset for compressed bios in btrfs_csum_one_bio()
btrfs_csum_one_bio() loops over each filesystem block in the bio while keeping a cursor of its current logical position in the file in order to look up the ordered extent to add the checksums to. However, this doesn't make much sense for compressed extents, as a sector on disk does not correspond to a sector of decompressed file data. It happens to work because: 1) the compressed bio always covers one ordered extent 2) the size of the bio is always less than the size of the ordered extent However, the second point will not always be true for encoded writes. Let's add a boolean parameter to btrfs_csum_one_bio() to indicate that it can assume that the bio only covers one ordered extent. Since we're already changing the signature, let's get rid of the contig parameter and make it implied by the offset parameter, similar to the change we recently made to btrfs_lookup_bio_sums(). Additionally, let's rename nr_sectors to blockcount to make it clear that it's the number of filesystem blocks, not the number of 512-byte sectors. Reviewed-by: Josef Bacik <[email protected]> Reviewed-by: Nikolay Borisov <[email protected]> Signed-off-by: Omar Sandoval <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent f6f7a25 commit e331f6b

File tree

4 files changed

+23
-26
lines changed

4 files changed

+23
-26
lines changed

fs/btrfs/compression.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
591591

592592
if (submit) {
593593
if (!skip_sum) {
594-
ret = btrfs_csum_one_bio(inode, bio, start, 1);
594+
ret = btrfs_csum_one_bio(inode, bio, start, true);
595595
if (ret)
596596
goto finish_cb;
597597
}

fs/btrfs/ctree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3203,7 +3203,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
32033203
struct btrfs_root *root,
32043204
struct btrfs_ordered_sum *sums);
32053205
blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
3206-
u64 file_start, int contig);
3206+
u64 offset, bool one_ordered);
32073207
int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
32083208
struct list_head *list, int search_commit);
32093209
void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,

fs/btrfs/file-item.c

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -612,32 +612,33 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
612612
return ret;
613613
}
614614

615-
/*
616-
* btrfs_csum_one_bio - Calculates checksums of the data contained inside a bio
615+
/**
616+
* Calculate checksums of the data contained inside a bio
617+
*
617618
* @inode: Owner of the data inside the bio
618619
* @bio: Contains the data to be checksummed
619-
* @file_start: offset in file this bio begins to describe
620-
* @contig: Boolean. If true/1 means all bio vecs in this bio are
621-
* contiguous and they begin at @file_start in the file. False/0
622-
* means this bio can contain potentially discontiguous bio vecs
623-
* so the logical offset of each should be calculated separately.
620+
* @offset: If (u64)-1, @bio may contain discontiguous bio vecs, so the
621+
* file offsets are determined from the page offsets in the bio.
622+
* Otherwise, this is the starting file offset of the bio vecs in
623+
* @bio, which must be contiguous.
624+
* @one_ordered: If true, @bio only refers to one ordered extent.
624625
*/
625626
blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
626-
u64 file_start, int contig)
627+
u64 offset, bool one_ordered)
627628
{
628629
struct btrfs_fs_info *fs_info = inode->root->fs_info;
629630
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
630631
struct btrfs_ordered_sum *sums;
631632
struct btrfs_ordered_extent *ordered = NULL;
633+
const bool use_page_offsets = (offset == (u64)-1);
632634
char *data;
633635
struct bvec_iter iter;
634636
struct bio_vec bvec;
635637
int index;
636-
int nr_sectors;
638+
unsigned int blockcount;
637639
unsigned long total_bytes = 0;
638640
unsigned long this_sum_bytes = 0;
639641
int i;
640-
u64 offset;
641642
unsigned nofs_flag;
642643

643644
nofs_flag = memalloc_nofs_save();
@@ -651,18 +652,13 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
651652
sums->len = bio->bi_iter.bi_size;
652653
INIT_LIST_HEAD(&sums->list);
653654

654-
if (contig)
655-
offset = file_start;
656-
else
657-
offset = 0; /* shut up gcc */
658-
659655
sums->bytenr = bio->bi_iter.bi_sector << 9;
660656
index = 0;
661657

662658
shash->tfm = fs_info->csum_shash;
663659

664660
bio_for_each_segment(bvec, bio, iter) {
665-
if (!contig)
661+
if (use_page_offsets)
666662
offset = page_offset(bvec.bv_page) + bvec.bv_offset;
667663

668664
if (!ordered) {
@@ -681,13 +677,14 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
681677
}
682678
}
683679

684-
nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info,
680+
blockcount = BTRFS_BYTES_TO_BLKS(fs_info,
685681
bvec.bv_len + fs_info->sectorsize
686682
- 1);
687683

688-
for (i = 0; i < nr_sectors; i++) {
689-
if (offset >= ordered->file_offset + ordered->num_bytes ||
690-
offset < ordered->file_offset) {
684+
for (i = 0; i < blockcount; i++) {
685+
if (!one_ordered &&
686+
!in_range(offset, ordered->file_offset,
687+
ordered->num_bytes)) {
691688
unsigned long bytes_left;
692689

693690
sums->len = this_sum_bytes;

fs/btrfs/inode.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ void btrfs_clear_delalloc_extent(struct inode *vfs_inode,
23142314
static blk_status_t btrfs_submit_bio_start(struct inode *inode, struct bio *bio,
23152315
u64 dio_file_offset)
23162316
{
2317-
return btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0);
2317+
return btrfs_csum_one_bio(BTRFS_I(inode), bio, (u64)-1, false);
23182318
}
23192319

23202320
/*
@@ -2566,7 +2566,7 @@ blk_status_t btrfs_submit_data_bio(struct inode *inode, struct bio *bio,
25662566
0, btrfs_submit_bio_start);
25672567
goto out;
25682568
} else if (!skip_sum) {
2569-
ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0);
2569+
ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, (u64)-1, false);
25702570
if (ret)
25712571
goto out;
25722572
}
@@ -7845,7 +7845,7 @@ static blk_status_t btrfs_submit_bio_start_direct_io(struct inode *inode,
78457845
struct bio *bio,
78467846
u64 dio_file_offset)
78477847
{
7848-
return btrfs_csum_one_bio(BTRFS_I(inode), bio, dio_file_offset, 1);
7848+
return btrfs_csum_one_bio(BTRFS_I(inode), bio, dio_file_offset, false);
78497849
}
78507850

78517851
static void btrfs_end_dio_bio(struct bio *bio)
@@ -7902,7 +7902,7 @@ static inline blk_status_t btrfs_submit_dio_bio(struct bio *bio,
79027902
* If we aren't doing async submit, calculate the csum of the
79037903
* bio now.
79047904
*/
7905-
ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, file_offset, 1);
7905+
ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, file_offset, false);
79067906
if (ret)
79077907
goto err;
79087908
} else {

0 commit comments

Comments
 (0)