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 19eef3e852b0..23c596cd1b98 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6931,7 +6931,11 @@ struct btrfs_dio_private {
6931 /* IO errors */ 6931 /* IO errors */
6932 int errors; 6932 int errors;
6933 6933
6934 /* orig_bio is our btrfs_io_bio */
6934 struct bio *orig_bio; 6935 struct bio *orig_bio;
6936
6937 /* dio_bio came from fs/direct-io.c */
6938 struct bio *dio_bio;
6935}; 6939};
6936 6940
6937static void btrfs_endio_direct_read(struct bio *bio, int err) 6941static void btrfs_endio_direct_read(struct bio *bio, int err)
@@ -6941,6 +6945,7 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
6941 struct bio_vec *bvec = bio->bi_io_vec; 6945 struct bio_vec *bvec = bio->bi_io_vec;
6942 struct inode *inode = dip->inode; 6946 struct inode *inode = dip->inode;
6943 struct btrfs_root *root = BTRFS_I(inode)->root; 6947 struct btrfs_root *root = BTRFS_I(inode)->root;
6948 struct bio *dio_bio;
6944 u64 start; 6949 u64 start;
6945 6950
6946 start = dip->logical_offset; 6951 start = dip->logical_offset;
@@ -6980,14 +6985,15 @@ failed:
6980 6985
6981 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, 6986 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
6982 dip->logical_offset + dip->bytes - 1); 6987 dip->logical_offset + dip->bytes - 1);
6983 bio->bi_private = dip->private; 6988 dio_bio = dip->dio_bio;
6984 6989
6985 kfree(dip); 6990 kfree(dip);
6986 6991
6987 /* If we had a csum failure make sure to clear the uptodate flag */ 6992 /* If we had a csum failure make sure to clear the uptodate flag */
6988 if (err) 6993 if (err)
6989 clear_bit(BIO_UPTODATE, &bio->bi_flags); 6994 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
6990 dio_end_io(bio, err); 6995 dio_end_io(dio_bio, err);
6996 bio_put(bio);
6991} 6997}
6992 6998
6993static void btrfs_endio_direct_write(struct bio *bio, int err) 6999static void btrfs_endio_direct_write(struct bio *bio, int err)
@@ -6998,6 +7004,7 @@ static void btrfs_endio_direct_write(struct bio *bio, int err)
6998 struct btrfs_ordered_extent *ordered = NULL; 7004 struct btrfs_ordered_extent *ordered = NULL;
6999 u64 ordered_offset = dip->logical_offset; 7005 u64 ordered_offset = dip->logical_offset;
7000 u64 ordered_bytes = dip->bytes; 7006 u64 ordered_bytes = dip->bytes;
7007 struct bio *dio_bio;
7001 int ret; 7008 int ret;
7002 7009
7003 if (err) 7010 if (err)
@@ -7025,14 +7032,15 @@ out_test:
7025 goto again; 7032 goto again;
7026 } 7033 }
7027out_done: 7034out_done:
7028 bio->bi_private = dip->private; 7035 dio_bio = dip->dio_bio;
7029 7036
7030 kfree(dip); 7037 kfree(dip);
7031 7038
7032 /* If we had an error make sure to clear the uptodate flag */ 7039 /* If we had an error make sure to clear the uptodate flag */
7033 if (err) 7040 if (err)
7034 clear_bit(BIO_UPTODATE, &bio->bi_flags); 7041 clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
7035 dio_end_io(bio, err); 7042 dio_end_io(dio_bio, err);
7043 bio_put(bio);
7036} 7044}
7037 7045
7038static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, 7046static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw,
@@ -7068,10 +7076,10 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
7068 if (!atomic_dec_and_test(&dip->pending_bios)) 7076 if (!atomic_dec_and_test(&dip->pending_bios))
7069 goto out; 7077 goto out;
7070 7078
7071 if (dip->errors) 7079 if (dip->errors) {
7072 bio_io_error(dip->orig_bio); 7080 bio_io_error(dip->orig_bio);
7073 else { 7081 } else {
7074 set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags); 7082 set_bit(BIO_UPTODATE, &dip->dio_bio->bi_flags);
7075 bio_endio(dip->orig_bio, 0); 7083 bio_endio(dip->orig_bio, 0);
7076 } 7084 }
7077out: 7085out:
@@ -7246,25 +7254,34 @@ out_err:
7246 return 0; 7254 return 0;
7247} 7255}
7248 7256
7249static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, 7257static void btrfs_submit_direct(int rw, struct bio *dio_bio,
7250 loff_t file_offset) 7258 struct inode *inode, loff_t file_offset)
7251{ 7259{
7252 struct btrfs_root *root = BTRFS_I(inode)->root; 7260 struct btrfs_root *root = BTRFS_I(inode)->root;
7253 struct btrfs_dio_private *dip; 7261 struct btrfs_dio_private *dip;
7254 struct bio_vec *bvec = bio->bi_io_vec; 7262 struct bio_vec *bvec = dio_bio->bi_io_vec;
7263 struct bio *io_bio;
7255 int skip_sum; 7264 int skip_sum;
7256 int write = rw & REQ_WRITE; 7265 int write = rw & REQ_WRITE;
7257 int ret = 0; 7266 int ret = 0;
7258 7267
7259 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 7268 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
7260 7269
7270 io_bio = btrfs_bio_clone(dio_bio, GFP_NOFS);
7271
7272 if (!io_bio) {
7273 ret = -ENOMEM;
7274 goto free_ordered;
7275 }
7276
7261 dip = kmalloc(sizeof(*dip), GFP_NOFS); 7277 dip = kmalloc(sizeof(*dip), GFP_NOFS);
7262 if (!dip) { 7278 if (!dip) {
7263 ret = -ENOMEM; 7279 ret = -ENOMEM;
7264 goto free_ordered; 7280 goto free_io_bio;
7265 } 7281 }
7266 7282
7267 dip->private = bio->bi_private; 7283 dip->private = dio_bio->bi_private;
7284 io_bio->bi_private = dio_bio->bi_private;
7268 dip->inode = inode; 7285 dip->inode = inode;
7269 dip->logical_offset = file_offset; 7286 dip->logical_offset = file_offset;
7270 7287
@@ -7272,22 +7289,27 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
7272 do { 7289 do {
7273 dip->bytes += bvec->bv_len; 7290 dip->bytes += bvec->bv_len;
7274 bvec++; 7291 bvec++;
7275 } while (bvec <= (bio->bi_io_vec + bio->bi_vcnt - 1)); 7292 } while (bvec <= (dio_bio->bi_io_vec + dio_bio->bi_vcnt - 1));
7276 7293
7277 dip->disk_bytenr = (u64)bio->bi_sector << 9; 7294 dip->disk_bytenr = (u64)dio_bio->bi_sector << 9;
7278 bio->bi_private = dip; 7295 io_bio->bi_private = dip;
7279 dip->errors = 0; 7296 dip->errors = 0;
7280 dip->orig_bio = bio; 7297 dip->orig_bio = io_bio;
7298 dip->dio_bio = dio_bio;
7281 atomic_set(&dip->pending_bios, 0); 7299 atomic_set(&dip->pending_bios, 0);
7282 7300
7283 if (write) 7301 if (write)
7284 bio->bi_end_io = btrfs_endio_direct_write; 7302 io_bio->bi_end_io = btrfs_endio_direct_write;
7285 else 7303 else
7286 bio->bi_end_io = btrfs_endio_direct_read; 7304 io_bio->bi_end_io = btrfs_endio_direct_read;
7287 7305
7288 ret = btrfs_submit_direct_hook(rw, dip, skip_sum); 7306 ret = btrfs_submit_direct_hook(rw, dip, skip_sum);
7289 if (!ret) 7307 if (!ret)
7290 return; 7308 return;
7309
7310free_io_bio:
7311 bio_put(io_bio);
7312
7291free_ordered: 7313free_ordered:
7292 /* 7314 /*
7293 * If this is a write, we need to clean up the reserved space and kill 7315 * If this is a write, we need to clean up the reserved space and kill
@@ -7303,7 +7325,7 @@ free_ordered:
7303 btrfs_put_ordered_extent(ordered); 7325 btrfs_put_ordered_extent(ordered);
7304 btrfs_put_ordered_extent(ordered); 7326 btrfs_put_ordered_extent(ordered);
7305 } 7327 }
7306 bio_endio(bio, ret); 7328 bio_endio(dio_bio, ret);
7307} 7329}
7308 7330
7309static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, 7331static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb,