aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 149c77fd1eb5..2bb76c6157a4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5957,7 +5957,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,
5957 5957
5958static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, 5958static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
5959 int rw, u64 file_offset, int skip_sum, 5959 int rw, u64 file_offset, int skip_sum,
5960 u32 *csums) 5960 u32 *csums, int async_submit)
5961{ 5961{
5962 int write = rw & REQ_WRITE; 5962 int write = rw & REQ_WRITE;
5963 struct btrfs_root *root = BTRFS_I(inode)->root; 5963 struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -5968,13 +5968,24 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
5968 if (ret) 5968 if (ret)
5969 goto err; 5969 goto err;
5970 5970
5971 if (write && !skip_sum) { 5971 if (skip_sum)
5972 goto map;
5973
5974 if (write && async_submit) {
5972 ret = btrfs_wq_submit_bio(root->fs_info, 5975 ret = btrfs_wq_submit_bio(root->fs_info,
5973 inode, rw, bio, 0, 0, 5976 inode, rw, bio, 0, 0,
5974 file_offset, 5977 file_offset,
5975 __btrfs_submit_bio_start_direct_io, 5978 __btrfs_submit_bio_start_direct_io,
5976 __btrfs_submit_bio_done); 5979 __btrfs_submit_bio_done);
5977 goto err; 5980 goto err;
5981 } else if (write) {
5982 /*
5983 * If we aren't doing async submit, calculate the csum of the
5984 * bio now.
5985 */
5986 ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1);
5987 if (ret)
5988 goto err;
5978 } else if (!skip_sum) { 5989 } else if (!skip_sum) {
5979 ret = btrfs_lookup_bio_sums_dio(root, inode, bio, 5990 ret = btrfs_lookup_bio_sums_dio(root, inode, bio,
5980 file_offset, csums); 5991 file_offset, csums);
@@ -5982,7 +5993,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
5982 goto err; 5993 goto err;
5983 } 5994 }
5984 5995
5985 ret = btrfs_map_bio(root, rw, bio, 0, 1); 5996map:
5997 ret = btrfs_map_bio(root, rw, bio, 0, async_submit);
5986err: 5998err:
5987 bio_put(bio); 5999 bio_put(bio);
5988 return ret; 6000 return ret;
@@ -6004,6 +6016,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
6004 int nr_pages = 0; 6016 int nr_pages = 0;
6005 u32 *csums = dip->csums; 6017 u32 *csums = dip->csums;
6006 int ret = 0; 6018 int ret = 0;
6019 int async_submit = 0;
6007 int write = rw & REQ_WRITE; 6020 int write = rw & REQ_WRITE;
6008 6021
6009 map_length = orig_bio->bi_size; 6022 map_length = orig_bio->bi_size;
@@ -6019,6 +6032,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
6019 goto submit; 6032 goto submit;
6020 } 6033 }
6021 6034
6035 async_submit = 1;
6022 bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); 6036 bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS);
6023 if (!bio) 6037 if (!bio)
6024 return -ENOMEM; 6038 return -ENOMEM;
@@ -6039,7 +6053,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
6039 atomic_inc(&dip->pending_bios); 6053 atomic_inc(&dip->pending_bios);
6040 ret = __btrfs_submit_dio_bio(bio, inode, rw, 6054 ret = __btrfs_submit_dio_bio(bio, inode, rw,
6041 file_offset, skip_sum, 6055 file_offset, skip_sum,
6042 csums); 6056 csums, async_submit);
6043 if (ret) { 6057 if (ret) {
6044 bio_put(bio); 6058 bio_put(bio);
6045 atomic_dec(&dip->pending_bios); 6059 atomic_dec(&dip->pending_bios);
@@ -6078,7 +6092,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
6078 6092
6079submit: 6093submit:
6080 ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, 6094 ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum,
6081 csums); 6095 csums, async_submit);
6082 if (!ret) 6096 if (!ret)
6083 return 0; 6097 return 0;
6084 6098