aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-09-12 06:43:54 -0400
committerChris Mason <clm@fb.com>2014-09-17 16:38:50 -0400
commit23ea8e5a07673127d05cb5cf6f9914d7a53e0847 (patch)
tree58199f4b68c72a1a6c4d0be4cf6ab917ecdcb070 /fs/btrfs
parentc3929c3624e1764855e5a452728aec201b18b42a (diff)
Btrfs: load checksum data once when submitting a direct read io
The current code would load checksum data for several times when we split a whole direct read io because of the limit of the raid stripe, it would make us search the csum tree for several times. In fact, it just wasted time, and made the contention of the csum tree root be more serious. This patch improves this problem by loading the data at once. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs')
-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