aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/btrfs_inode.h1
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/extent_io.c13
-rw-r--r--fs/btrfs/file-item.c14
-rw-r--r--fs/btrfs/inode.c38
5 files changed, 35 insertions, 34 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index fd879418fd42..8bea70e02a3d 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -263,7 +263,6 @@ struct btrfs_dio_private {
263 263
264 /* dio_bio came from fs/direct-io.c */ 264 /* dio_bio came from fs/direct-io.c */
265 struct bio *dio_bio; 265 struct bio *dio_bio;
266 u8 csum[0];
267}; 266};
268 267
269/* 268/*
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 6db3d4bac6fd..0f3e4f7e454a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3719,8 +3719,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
3719int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, 3719int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
3720 struct bio *bio, u32 *dst); 3720 struct bio *bio, u32 *dst);
3721int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, 3721int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
3722 struct btrfs_dio_private *dip, struct bio *bio, 3722 struct bio *bio, u64 logical_offset);
3723 u64 logical_offset);
3724int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, 3723int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
3725 struct btrfs_root *root, 3724 struct btrfs_root *root,
3726 u64 objectid, u64 pos, 3725 u64 objectid, u64 pos,
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index d5e71d4646dd..d2f8f39e11fd 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2621,9 +2621,18 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
2621 2621
2622struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask) 2622struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask)
2623{ 2623{
2624 return bio_clone_bioset(bio, gfp_mask, btrfs_bioset); 2624 struct btrfs_io_bio *btrfs_bio;
2625} 2625 struct bio *new;
2626 2626
2627 new = bio_clone_bioset(bio, gfp_mask, btrfs_bioset);
2628 if (new) {
2629 btrfs_bio = btrfs_io_bio(new);
2630 btrfs_bio->csum = NULL;
2631 btrfs_bio->csum_allocated = NULL;
2632 btrfs_bio->end_io = NULL;
2633 }
2634 return new;
2635}
2627 2636
2628/* this also allocates from the btrfs_bioset */ 2637/* this also allocates from the btrfs_bioset */
2629struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs) 2638struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 6e6262eca8b7..783a94355efd 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -299,19 +299,9 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
299} 299}
300 300
301int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, 301int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
302 struct btrfs_dio_private *dip, struct bio *bio, 302 struct bio *bio, u64 offset)
303 u64 offset)
304{ 303{
305 int len = (bio->bi_iter.bi_sector << 9) - dip->disk_bytenr; 304 return __btrfs_lookup_bio_sums(root, inode, bio, offset, NULL, 1);
306 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
307 int ret;
308
309 len >>= inode->i_sb->s_blocksize_bits;
310 len *= csum_size;
311
312 ret = __btrfs_lookup_bio_sums(root, inode, bio, offset,
313 (u32 *)(dip->csum + len), 1);
314 return ret;
315} 305}
316 306
317int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, 307int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 75c6de26405c..fca944211bf0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7240,7 +7240,8 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
7240 struct inode *inode = dip->inode; 7240 struct inode *inode = dip->inode;
7241 struct btrfs_root *root = BTRFS_I(inode)->root; 7241 struct btrfs_root *root = BTRFS_I(inode)->root;
7242 struct bio *dio_bio; 7242 struct bio *dio_bio;
7243 u32 *csums = (u32 *)dip->csum; 7243 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
7244 u32 *csums = (u32 *)io_bio->csum;
7244 u64 start; 7245 u64 start;
7245 int i; 7246 int i;
7246 7247
@@ -7282,6 +7283,9 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
7282 if (err) 7283 if (err)
7283 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags); 7284 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
7284 dio_end_io(dio_bio, err); 7285 dio_end_io(dio_bio, err);
7286
7287 if (io_bio->end_io)
7288 io_bio->end_io(io_bio, err);
7285 bio_put(bio); 7289 bio_put(bio);
7286} 7290}
7287 7291
@@ -7421,13 +7425,20 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
7421 ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1); 7425 ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1);
7422 if (ret) 7426 if (ret)
7423 goto err; 7427 goto err;
7424 } else if (!skip_sum) { 7428 } else {
7425 ret = btrfs_lookup_bio_sums_dio(root, inode, dip, bio, 7429 /*
7430 * We have loaded all the csum data we need when we submit
7431 * the first bio, so skip it.
7432 */
7433 if (dip->logical_offset != file_offset)
7434 goto map;
7435
7436 /* Load all csum data at once. */
7437 ret = btrfs_lookup_bio_sums_dio(root, inode, dip->orig_bio,
7426 file_offset); 7438 file_offset);
7427 if (ret) 7439 if (ret)
7428 goto err; 7440 goto err;
7429 } 7441 }
7430
7431map: 7442map:
7432 ret = btrfs_map_bio(root, rw, bio, 0, async_submit); 7443 ret = btrfs_map_bio(root, rw, bio, 0, async_submit);
7433err: 7444err:
@@ -7448,7 +7459,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
7448 u64 submit_len = 0; 7459 u64 submit_len = 0;
7449 u64 map_length; 7460 u64 map_length;
7450 int nr_pages = 0; 7461 int nr_pages = 0;
7451 int ret = 0; 7462 int ret;
7452 int async_submit = 0; 7463 int async_submit = 0;
7453 7464
7454 map_length = orig_bio->bi_iter.bi_size; 7465 map_length = orig_bio->bi_iter.bi_size;
@@ -7552,11 +7563,10 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
7552 struct btrfs_root *root = BTRFS_I(inode)->root; 7563 struct btrfs_root *root = BTRFS_I(inode)->root;
7553 struct btrfs_dio_private *dip; 7564 struct btrfs_dio_private *dip;
7554 struct bio *io_bio; 7565 struct bio *io_bio;
7566 struct btrfs_io_bio *btrfs_bio;
7555 int skip_sum; 7567 int skip_sum;
7556 int sum_len;
7557 int write = rw & REQ_WRITE; 7568 int write = rw & REQ_WRITE;
7558 int ret = 0; 7569 int ret = 0;
7559 u16 csum_size;
7560 7570
7561 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 7571 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
7562 7572
@@ -7566,16 +7576,7 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
7566 goto free_ordered; 7576 goto free_ordered;
7567 } 7577 }
7568 7578
7569 if (!skip_sum && !write) { 7579 dip = kmalloc(sizeof(*dip), GFP_NOFS);
7570 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
7571 sum_len = dio_bio->bi_iter.bi_size >>
7572 inode->i_sb->s_blocksize_bits;
7573 sum_len *= csum_size;
7574 } else {
7575 sum_len = 0;
7576 }
7577
7578 dip = kmalloc(sizeof(*dip) + sum_len, GFP_NOFS);
7579 if (!dip) { 7580 if (!dip) {
7580 ret = -ENOMEM; 7581 ret = -ENOMEM;
7581 goto free_io_bio; 7582 goto free_io_bio;
@@ -7601,6 +7602,9 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
7601 if (!ret) 7602 if (!ret)
7602 return; 7603 return;
7603 7604
7605 btrfs_bio = btrfs_io_bio(io_bio);
7606 if (btrfs_bio->end_io)
7607 btrfs_bio->end_io(btrfs_bio, ret);
7604free_io_bio: 7608free_io_bio:
7605 bio_put(io_bio); 7609 bio_put(io_bio);
7606 7610