diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/inode.c | 24 |
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 | ||
5958 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | 5958 | static 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); | 5996 | map: |
5997 | ret = btrfs_map_bio(root, rw, bio, 0, async_submit); | ||
5986 | err: | 5998 | err: |
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 | ||
6079 | submit: | 6093 | submit: |
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 | ||