struct btrfs_root *root,
                           struct btrfs_ordered_sum *sums);
 blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
-                               u64 file_start, int contig);
+                               u64 offset, bool one_ordered);
 int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
                             struct list_head *list, int search_commit);
 void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
 
        return ret;
 }
 
-/*
- * btrfs_csum_one_bio - Calculates checksums of the data contained inside a bio
+/**
+ * Calculate checksums of the data contained inside a bio
+ *
  * @inode:      Owner of the data inside the bio
  * @bio:        Contains the data to be checksummed
- * @file_start:  offset in file this bio begins to describe
- * @contig:     Boolean. If true/1 means all bio vecs in this bio are
- *              contiguous and they begin at @file_start in the file. False/0
- *              means this bio can contain potentially discontiguous bio vecs
- *              so the logical offset of each should be calculated separately.
+ * @offset:      If (u64)-1, @bio may contain discontiguous bio vecs, so the
+ *               file offsets are determined from the page offsets in the bio.
+ *               Otherwise, this is the starting file offset of the bio vecs in
+ *               @bio, which must be contiguous.
+ * @one_ordered: If true, @bio only refers to one ordered extent.
  */
 blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
-                      u64 file_start, int contig)
+                               u64 offset, bool one_ordered)
 {
        struct btrfs_fs_info *fs_info = inode->root->fs_info;
        SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
        struct btrfs_ordered_sum *sums;
        struct btrfs_ordered_extent *ordered = NULL;
+       const bool use_page_offsets = (offset == (u64)-1);
        char *data;
        struct bvec_iter iter;
        struct bio_vec bvec;
        int index;
-       int nr_sectors;
+       unsigned int blockcount;
        unsigned long total_bytes = 0;
        unsigned long this_sum_bytes = 0;
        int i;
-       u64 offset;
        unsigned nofs_flag;
 
        nofs_flag = memalloc_nofs_save();
        sums->len = bio->bi_iter.bi_size;
        INIT_LIST_HEAD(&sums->list);
 
-       if (contig)
-               offset = file_start;
-       else
-               offset = 0; /* shut up gcc */
-
        sums->bytenr = bio->bi_iter.bi_sector << 9;
        index = 0;
 
        shash->tfm = fs_info->csum_shash;
 
        bio_for_each_segment(bvec, bio, iter) {
-               if (!contig)
+               if (use_page_offsets)
                        offset = page_offset(bvec.bv_page) + bvec.bv_offset;
 
                if (!ordered) {
                        }
                }
 
-               nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info,
+               blockcount = BTRFS_BYTES_TO_BLKS(fs_info,
                                                 bvec.bv_len + fs_info->sectorsize
                                                 - 1);
 
-               for (i = 0; i < nr_sectors; i++) {
-                       if (offset >= ordered->file_offset + ordered->num_bytes ||
-                           offset < ordered->file_offset) {
+               for (i = 0; i < blockcount; i++) {
+                       if (!one_ordered &&
+                           !in_range(offset, ordered->file_offset,
+                                     ordered->num_bytes)) {
                                unsigned long bytes_left;
 
                                sums->len = this_sum_bytes;
 
 static blk_status_t btrfs_submit_bio_start(struct inode *inode, struct bio *bio,
                                           u64 dio_file_offset)
 {
-       return btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0);
+       return btrfs_csum_one_bio(BTRFS_I(inode), bio, (u64)-1, false);
 }
 
 /*
                                          0, btrfs_submit_bio_start);
                goto out;
        } else if (!skip_sum) {
-               ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0);
+               ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, (u64)-1, false);
                if (ret)
                        goto out;
        }
                                                     struct bio *bio,
                                                     u64 dio_file_offset)
 {
-       return btrfs_csum_one_bio(BTRFS_I(inode), bio, dio_file_offset, 1);
+       return btrfs_csum_one_bio(BTRFS_I(inode), bio, dio_file_offset, false);
 }
 
 static void btrfs_end_dio_bio(struct bio *bio)
                 * If we aren't doing async submit, calculate the csum of the
                 * bio now.
                 */
-               ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, file_offset, 1);
+               ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, file_offset, false);
                if (ret)
                        goto err;
        } else {