|
@@ -7240,7 +7240,8 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
|
|
|
struct inode *inode = dip->inode;
|
|
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
|
|
struct bio *dio_bio;
|
|
|
- u32 *csums = (u32 *)dip->csum;
|
|
|
+ struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
|
|
|
+ u32 *csums = (u32 *)io_bio->csum;
|
|
|
u64 start;
|
|
|
int i;
|
|
|
|
|
@@ -7282,6 +7283,9 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
|
|
|
if (err)
|
|
|
clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
|
|
|
dio_end_io(dio_bio, err);
|
|
|
+
|
|
|
+ if (io_bio->end_io)
|
|
|
+ io_bio->end_io(io_bio, err);
|
|
|
bio_put(bio);
|
|
|
}
|
|
|
|
|
@@ -7421,13 +7425,20 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
|
|
|
ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1);
|
|
|
if (ret)
|
|
|
goto err;
|
|
|
- } else if (!skip_sum) {
|
|
|
- ret = btrfs_lookup_bio_sums_dio(root, inode, dip, bio,
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * We have loaded all the csum data we need when we submit
|
|
|
+ * the first bio, so skip it.
|
|
|
+ */
|
|
|
+ if (dip->logical_offset != file_offset)
|
|
|
+ goto map;
|
|
|
+
|
|
|
+ /* Load all csum data at once. */
|
|
|
+ ret = btrfs_lookup_bio_sums_dio(root, inode, dip->orig_bio,
|
|
|
file_offset);
|
|
|
if (ret)
|
|
|
goto err;
|
|
|
}
|
|
|
-
|
|
|
map:
|
|
|
ret = btrfs_map_bio(root, rw, bio, 0, async_submit);
|
|
|
err:
|
|
@@ -7448,7 +7459,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
|
|
|
u64 submit_len = 0;
|
|
|
u64 map_length;
|
|
|
int nr_pages = 0;
|
|
|
- int ret = 0;
|
|
|
+ int ret;
|
|
|
int async_submit = 0;
|
|
|
|
|
|
map_length = orig_bio->bi_iter.bi_size;
|
|
@@ -7552,11 +7563,10 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
|
|
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
|
|
struct btrfs_dio_private *dip;
|
|
|
struct bio *io_bio;
|
|
|
+ struct btrfs_io_bio *btrfs_bio;
|
|
|
int skip_sum;
|
|
|
- int sum_len;
|
|
|
int write = rw & REQ_WRITE;
|
|
|
int ret = 0;
|
|
|
- u16 csum_size;
|
|
|
|
|
|
skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
|
|
|
|
|
@@ -7566,16 +7576,7 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
|
|
|
goto free_ordered;
|
|
|
}
|
|
|
|
|
|
- if (!skip_sum && !write) {
|
|
|
- csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
|
|
|
- sum_len = dio_bio->bi_iter.bi_size >>
|
|
|
- inode->i_sb->s_blocksize_bits;
|
|
|
- sum_len *= csum_size;
|
|
|
- } else {
|
|
|
- sum_len = 0;
|
|
|
- }
|
|
|
-
|
|
|
- dip = kmalloc(sizeof(*dip) + sum_len, GFP_NOFS);
|
|
|
+ dip = kmalloc(sizeof(*dip), GFP_NOFS);
|
|
|
if (!dip) {
|
|
|
ret = -ENOMEM;
|
|
|
goto free_io_bio;
|
|
@@ -7601,6 +7602,9 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
|
|
|
if (!ret)
|
|
|
return;
|
|
|
|
|
|
+ btrfs_bio = btrfs_io_bio(io_bio);
|
|
|
+ if (btrfs_bio->end_io)
|
|
|
+ btrfs_bio->end_io(btrfs_bio, ret);
|
|
|
free_io_bio:
|
|
|
bio_put(io_bio);
|
|
|
|