aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1669c3b4be2f..d59dddfb1f96 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6927,7 +6927,11 @@ struct btrfs_dio_private {
6927 /* IO errors */ 6927 /* IO errors */
6928 int errors; 6928 int errors;
6929 6929
6930 /* orig_bio is our btrfs_io_bio */
6930 struct bio *orig_bio; 6931 struct bio *orig_bio;
6932
6933 /* dio_bio came from fs/direct-io.c */
6934 struct bio *dio_bio;
6931}; 6935};
6932 6936
6933static void btrfs_endio_direct_read(struct bio *bio, int err) 6937static void btrfs_endio_direct_read(struct bio *bio, int err)
@@ -6937,6 +6941,7 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
6937 struct bio_vec *bvec = bio->bi_io_vec; 6941 struct bio_vec *bvec = bio->bi_io_vec;
6938 struct inode *inode = dip->inode; 6942 struct inode *inode = dip->inode;
6939 struct btrfs_root *root = BTRFS_I(inode)->root; 6943 struct btrfs_root *root = BTRFS_I(inode)->root;
6944 struct bio *dio_bio;
6940 u64 start; 6945 u64 start;
6941 6946
6942 start = dip->logical_offset; 6947 start = dip->logical_offset;
@@ -6976,14 +6981,15 @@ failed:
6976 6981
6977 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, 6982 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
6978 dip->logical_offset + dip->bytes - 1); 6983 dip->logical_offset + dip->bytes - 1);
6979 bio->bi_private = dip->private; 6984 dio_bio = dip->dio_bio;
6980 6985
6981 kfree(dip); 6986 kfree(dip);
6982 6987
6983 /* If we had a csum failure make sure to clear the uptodate flag */ 6988 /* If we had a csum failure make sure to clear the uptodate flag */
6984 if (err) 6989 if (err)
6985 clear_bit(BIO_UPTODATE, &bio->bi_flags); 6990 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
6986 dio_end_io(bio, err); 6991 dio_end_io(dio_bio, err);
6992 bio_put(bio);
6987} 6993}
6988 6994
6989static void btrfs_endio_direct_write(struct bio *bio, int err) 6995static void btrfs_endio_direct_write(struct bio *bio, int err)
@@ -6994,6 +7000,7 @@ static void btrfs_endio_direct_write(struct bio *bio, int err)
6994 struct btrfs_ordered_extent *ordered = NULL; 7000 struct btrfs_ordered_extent *ordered = NULL;
6995 u64 ordered_offset = dip->logical_offset; 7001 u64 ordered_offset = dip->logical_offset;
6996 u64 ordered_bytes = dip->bytes; 7002 u64 ordered_bytes = dip->bytes;
7003 struct bio *dio_bio;
6997 int ret; 7004 int ret;
6998 7005
6999 if (err) 7006 if (err)
@@ -7021,14 +7028,15 @@ out_test:
7021 goto again; 7028 goto again;
7022 } 7029 }
7023out_done: 7030out_done:
7024 bio->bi_private = dip->private; 7031 dio_bio = dip->dio_bio;
7025 7032
7026 kfree(dip); 7033 kfree(dip);
7027 7034
7028 /* If we had an error make sure to clear the uptodate flag */ 7035 /* If we had an error make sure to clear the uptodate flag */
7029 if (err) 7036 if (err)
7030 clear_bit(BIO_UPTODATE, &bio->bi_flags); 7037 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
7031 dio_end_io(bio, err); 7038 dio_end_io(dio_bio, err);
7039 bio_put(bio);
7032} 7040}
7033 7041
7034static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, 7042static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw,
@@ -7064,10 +7072,10 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
7064 if (!atomic_dec_and_test(&dip->pending_bios)) 7072 if (!atomic_dec_and_test(&dip->pending_bios))
7065 goto out; 7073 goto out;
7066 7074
7067 if (dip->errors) 7075 if (dip->errors) {
7068 bio_io_error(dip->orig_bio); 7076 bio_io_error(dip->orig_bio);
7069 else { 7077 } else {
7070 set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags); 7078 set_bit(BIO_UPTODATE, &dip->dio_bio->bi_flags);
7071 bio_endio(dip->orig_bio, 0); 7079 bio_endio(dip->orig_bio, 0);
7072 } 7080 }
7073out: 7081out:
@@ -7242,25 +7250,34 @@ out_err:
7242 return 0; 7250 return 0;
7243} 7251}
7244 7252
7245static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, 7253static void btrfs_submit_direct(int rw, struct bio *dio_bio,
7246 loff_t file_offset) 7254 struct inode *inode, loff_t file_offset)
7247{ 7255{
7248 struct btrfs_root *root = BTRFS_I(inode)->root; 7256 struct btrfs_root *root = BTRFS_I(inode)->root;
7249 struct btrfs_dio_private *dip; 7257 struct btrfs_dio_private *dip;
7250 struct bio_vec *bvec = bio->bi_io_vec; 7258 struct bio_vec *bvec = dio_bio->bi_io_vec;
7259 struct bio *io_bio;
7251 int skip_sum; 7260 int skip_sum;
7252 int write = rw & REQ_WRITE; 7261 int write = rw & REQ_WRITE;
7253 int ret = 0; 7262 int ret = 0;
7254 7263
7255 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 7264 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
7256 7265
7266 io_bio = btrfs_bio_clone(dio_bio, GFP_NOFS);
7267
7268 if (!io_bio) {
7269 ret = -ENOMEM;
7270 goto free_ordered;
7271 }
7272
7257 dip = kmalloc(sizeof(*dip), GFP_NOFS); 7273 dip = kmalloc(sizeof(*dip), GFP_NOFS);
7258 if (!dip) { 7274 if (!dip) {
7259 ret = -ENOMEM; 7275 ret = -ENOMEM;
7260 goto free_ordered; 7276 goto free_io_bio;
7261 } 7277 }
7262 7278
7263 dip->private = bio->bi_private; 7279 dip->private = dio_bio->bi_private;
7280 io_bio->bi_private = dio_bio->bi_private;
7264 dip->inode = inode; 7281 dip->inode = inode;
7265 dip->logical_offset = file_offset; 7282 dip->logical_offset = file_offset;
7266 7283
@@ -7268,22 +7285,27 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
7268 do { 7285 do {
7269 dip->bytes += bvec->bv_len; 7286 dip->bytes += bvec->bv_len;
7270 bvec++; 7287 bvec++;
7271 } while (bvec <= (bio->bi_io_vec + bio->bi_vcnt - 1)); 7288 } while (bvec <= (dio_bio->bi_io_vec + dio_bio->bi_vcnt - 1));
7272 7289
7273 dip->disk_bytenr = (u64)bio->bi_sector << 9; 7290 dip->disk_bytenr = (u64)dio_bio->bi_sector << 9;
7274 bio->bi_private = dip; 7291 io_bio->bi_private = dip;
7275 dip->errors = 0; 7292 dip->errors = 0;
7276 dip->orig_bio = bio; 7293 dip->orig_bio = io_bio;
7294 dip->dio_bio = dio_bio;
7277 atomic_set(&dip->pending_bios, 0); 7295 atomic_set(&dip->pending_bios, 0);
7278 7296
7279 if (write) 7297 if (write)
7280 bio->bi_end_io = btrfs_endio_direct_write; 7298 io_bio->bi_end_io = btrfs_endio_direct_write;
7281 else 7299 else
7282 bio->bi_end_io = btrfs_endio_direct_read; 7300 io_bio->bi_end_io = btrfs_endio_direct_read;
7283 7301
7284 ret = btrfs_submit_direct_hook(rw, dip, skip_sum); 7302 ret = btrfs_submit_direct_hook(rw, dip, skip_sum);
7285 if (!ret) 7303 if (!ret)
7286 return; 7304 return;
7305
7306free_io_bio:
7307 bio_put(io_bio);
7308
7287free_ordered: 7309free_ordered:
7288 /* 7310 /*
7289 * If this is a write, we need to clean up the reserved space and kill 7311 * If this is a write, we need to clean up the reserved space and kill
@@ -7299,7 +7321,7 @@ free_ordered:
7299 btrfs_put_ordered_extent(ordered); 7321 btrfs_put_ordered_extent(ordered);
7300 btrfs_put_ordered_extent(ordered); 7322 btrfs_put_ordered_extent(ordered);
7301 } 7323 }
7302 bio_endio(bio, ret); 7324 bio_endio(dio_bio, ret);
7303} 7325}
7304 7326
7305static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, 7327static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb,