aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/btrfs/check-integrity.c2
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/extent_io.c49
-rw-r--r--fs/btrfs/extent_io.h2
-rw-r--r--fs/btrfs/inode.c64
-rw-r--r--fs/btrfs/raid56.c2
-rw-r--r--fs/btrfs/scrub.c10
-rw-r--r--fs/btrfs/volumes.c41
-rw-r--r--fs/btrfs/volumes.h20
9 files changed, 120 insertions, 72 deletions
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index 18af6f48781a..1431a6965017 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -1700,7 +1700,7 @@ static int btrfsic_read_block(struct btrfsic_state *state,
1700 unsigned int j; 1700 unsigned int j;
1701 DECLARE_COMPLETION_ONSTACK(complete); 1701 DECLARE_COMPLETION_ONSTACK(complete);
1702 1702
1703 bio = bio_alloc(GFP_NOFS, num_pages - i); 1703 bio = btrfs_io_bio_alloc(GFP_NOFS, num_pages - i);
1704 if (!bio) { 1704 if (!bio) {
1705 printk(KERN_INFO 1705 printk(KERN_INFO
1706 "btrfsic: bio_alloc() for %u pages failed!\n", 1706 "btrfsic: bio_alloc() for %u pages failed!\n",
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4e9ebe1f1827..ca0ea9928210 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3128,7 +3128,7 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
3128 * caller 3128 * caller
3129 */ 3129 */
3130 device->flush_bio = NULL; 3130 device->flush_bio = NULL;
3131 bio = bio_alloc(GFP_NOFS, 0); 3131 bio = btrfs_io_bio_alloc(GFP_NOFS, 0);
3132 if (!bio) 3132 if (!bio)
3133 return -ENOMEM; 3133 return -ENOMEM;
3134 3134
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index d2ac518f90e4..fe1d6c3424a5 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -23,6 +23,7 @@
23 23
24static struct kmem_cache *extent_state_cache; 24static struct kmem_cache *extent_state_cache;
25static struct kmem_cache *extent_buffer_cache; 25static struct kmem_cache *extent_buffer_cache;
26static struct bio_set *btrfs_bioset;
26 27
27#ifdef CONFIG_BTRFS_DEBUG 28#ifdef CONFIG_BTRFS_DEBUG
28static LIST_HEAD(buffers); 29static LIST_HEAD(buffers);
@@ -125,10 +126,20 @@ int __init extent_io_init(void)
125 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL); 126 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
126 if (!extent_buffer_cache) 127 if (!extent_buffer_cache)
127 goto free_state_cache; 128 goto free_state_cache;
129
130 btrfs_bioset = bioset_create(BIO_POOL_SIZE,
131 offsetof(struct btrfs_io_bio, bio));
132 if (!btrfs_bioset)
133 goto free_buffer_cache;
128 return 0; 134 return 0;
129 135
136free_buffer_cache:
137 kmem_cache_destroy(extent_buffer_cache);
138 extent_buffer_cache = NULL;
139
130free_state_cache: 140free_state_cache:
131 kmem_cache_destroy(extent_state_cache); 141 kmem_cache_destroy(extent_state_cache);
142 extent_state_cache = NULL;
132 return -ENOMEM; 143 return -ENOMEM;
133} 144}
134 145
@@ -145,6 +156,8 @@ void extent_io_exit(void)
145 kmem_cache_destroy(extent_state_cache); 156 kmem_cache_destroy(extent_state_cache);
146 if (extent_buffer_cache) 157 if (extent_buffer_cache)
147 kmem_cache_destroy(extent_buffer_cache); 158 kmem_cache_destroy(extent_buffer_cache);
159 if (btrfs_bioset)
160 bioset_free(btrfs_bioset);
148} 161}
149 162
150void extent_io_tree_init(struct extent_io_tree *tree, 163void extent_io_tree_init(struct extent_io_tree *tree,
@@ -2046,7 +2059,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
2046 if (btrfs_is_parity_mirror(map_tree, logical, length, mirror_num)) 2059 if (btrfs_is_parity_mirror(map_tree, logical, length, mirror_num))
2047 return 0; 2060 return 0;
2048 2061
2049 bio = bio_alloc(GFP_NOFS, 1); 2062 bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
2050 if (!bio) 2063 if (!bio)
2051 return -EIO; 2064 return -EIO;
2052 bio->bi_private = &compl; 2065 bio->bi_private = &compl;
@@ -2336,7 +2349,7 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
2336 return -EIO; 2349 return -EIO;
2337 } 2350 }
2338 2351
2339 bio = bio_alloc(GFP_NOFS, 1); 2352 bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
2340 if (!bio) { 2353 if (!bio) {
2341 free_io_failure(inode, failrec, 0); 2354 free_io_failure(inode, failrec, 0);
2342 return -EIO; 2355 return -EIO;
@@ -2457,10 +2470,11 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2457 struct page *page = bvec->bv_page; 2470 struct page *page = bvec->bv_page;
2458 struct extent_state *cached = NULL; 2471 struct extent_state *cached = NULL;
2459 struct extent_state *state; 2472 struct extent_state *state;
2473 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
2460 2474
2461 pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, " 2475 pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
2462 "mirror=%ld\n", (u64)bio->bi_sector, err, 2476 "mirror=%lu\n", (u64)bio->bi_sector, err,
2463 (long int)bio->bi_bdev); 2477 io_bio->mirror_num);
2464 tree = &BTRFS_I(page->mapping->host)->io_tree; 2478 tree = &BTRFS_I(page->mapping->host)->io_tree;
2465 2479
2466 start = page_offset(page) + bvec->bv_offset; 2480 start = page_offset(page) + bvec->bv_offset;
@@ -2485,7 +2499,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2485 } 2499 }
2486 spin_unlock(&tree->lock); 2500 spin_unlock(&tree->lock);
2487 2501
2488 mirror = (int)(unsigned long)bio->bi_bdev; 2502 mirror = io_bio->mirror_num;
2489 if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { 2503 if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {
2490 ret = tree->ops->readpage_end_io_hook(page, start, end, 2504 ret = tree->ops->readpage_end_io_hook(page, start, end,
2491 state, mirror); 2505 state, mirror);
@@ -2550,17 +2564,23 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2550 bio_put(bio); 2564 bio_put(bio);
2551} 2565}
2552 2566
2567/*
2568 * this allocates from the btrfs_bioset. We're returning a bio right now
2569 * but you can call btrfs_io_bio for the appropriate container_of magic
2570 */
2553struct bio * 2571struct bio *
2554btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, 2572btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
2555 gfp_t gfp_flags) 2573 gfp_t gfp_flags)
2556{ 2574{
2557 struct bio *bio; 2575 struct bio *bio;
2558 2576
2559 bio = bio_alloc(gfp_flags, nr_vecs); 2577 bio = bio_alloc_bioset(gfp_flags, nr_vecs, btrfs_bioset);
2560 2578
2561 if (bio == NULL && (current->flags & PF_MEMALLOC)) { 2579 if (bio == NULL && (current->flags & PF_MEMALLOC)) {
2562 while (!bio && (nr_vecs /= 2)) 2580 while (!bio && (nr_vecs /= 2)) {
2563 bio = bio_alloc(gfp_flags, nr_vecs); 2581 bio = bio_alloc_bioset(gfp_flags,
2582 nr_vecs, btrfs_bioset);
2583 }
2564 } 2584 }
2565 2585
2566 if (bio) { 2586 if (bio) {
@@ -2571,6 +2591,19 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
2571 return bio; 2591 return bio;
2572} 2592}
2573 2593
2594struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask)
2595{
2596 return bio_clone_bioset(bio, gfp_mask, btrfs_bioset);
2597}
2598
2599
2600/* this also allocates from the btrfs_bioset */
2601struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
2602{
2603 return bio_alloc_bioset(gfp_mask, nr_iovecs, btrfs_bioset);
2604}
2605
2606
2574static int __must_check submit_one_bio(int rw, struct bio *bio, 2607static int __must_check submit_one_bio(int rw, struct bio *bio,
2575 int mirror_num, unsigned long bio_flags) 2608 int mirror_num, unsigned long bio_flags)
2576{ 2609{