aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@fusionio.com>2013-05-17 18:30:14 -0400
committerChris Mason <chris.mason@fusionio.com>2013-05-17 21:52:52 -0400
commit9be3395bcd4ad4af76476ac38152b4cafa6b6159 (patch)
treea43b9ce18f66482abf055d87b3ceec02a84477e7 /fs/btrfs/inode.c
parent667e7d94a1683661cff5fe9a0fa0d7f8fdd2c007 (diff)
Btrfs: use a btrfs bioset instead of abusing bio internals
Btrfs has been pointer tagging bi_private and using bi_bdev to store the stripe index and mirror number of failed IOs. As bios bubble back up through the call chain, we use these to decide if and how to retry our IOs. They are also used to count IO failures on a per device basis. Recently a bio tracepoint was added lead to crashes because we were abusing bi_bdev. This commit adds a btrfs bioset, and creates explicit fields for the mirror number and stripe index. The plan is to extend this structure for all of the fields currently in struct btrfs_bio, which will mean one less kmalloc in our IO path. Signed-off-by: Chris Mason <chris.mason@fusionio.com> Reported-by: Tejun Heo <tj@kernel.org>
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,