diff options
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 1 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 13 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 14 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 38 |
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, | |||
3719 | int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | 3719 | int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, |
3720 | struct bio *bio, u32 *dst); | 3720 | struct bio *bio, u32 *dst); |
3721 | int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, | 3721 | int 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); | ||
3724 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 3723 | int 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 | ||
2622 | struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask) | 2622 | struct 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 */ |
2629 | struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs) | 2638 | struct 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 | ||
301 | int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, | 301 | int 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 | ||
317 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | 307 | int 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 | |||
7431 | map: | 7442 | map: |
7432 | ret = btrfs_map_bio(root, rw, bio, 0, async_submit); | 7443 | ret = btrfs_map_bio(root, rw, bio, 0, async_submit); |
7433 | err: | 7444 | err: |
@@ -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); | ||
7604 | free_io_bio: | 7608 | free_io_bio: |
7605 | bio_put(io_bio); | 7609 | bio_put(io_bio); |
7606 | 7610 | ||