aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhao Lei <zhaolei@cn.fujitsu.com>2015-01-20 02:11:34 -0500
committerChris Mason <clm@fb.com>2015-01-21 21:06:48 -0500
commit6e9606d2a2dce098c1739fb3cd82a1c34fd73d3a (patch)
treeeeeb1c991d4971cdbfda675bbbb4b37b0c6f5ebb
parent8e5cfb55d3f7dc764cd7f4c966d4c2687eaf7569 (diff)
Btrfs: add ref_count and free function for btrfs_bio
1: ref_count is simple than current RBIO_HOLD_BBIO_MAP_BIT flag to keep btrfs_bio's memory in raid56 recovery implement. 2: free function for bbio will make code clean and flexible, plus forced data type checking in compile. Changelog v1->v2: Rename following by David Sterba's suggestion: put_btrfs_bio() -> btrfs_put_bio() get_btrfs_bio() -> btrfs_get_bio() bbio->ref_count -> bbio->refs Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/btrfs/extent_io.c2
-rw-r--r--fs/btrfs/raid56.c38
-rw-r--r--fs/btrfs/reada.c4
-rw-r--r--fs/btrfs/scrub.c12
-rw-r--r--fs/btrfs/volumes.c43
-rw-r--r--fs/btrfs/volumes.h10
7 files changed, 57 insertions, 54 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3af53f8313af..1d361ac9abc9 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1926,7 +1926,7 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
1926 */ 1926 */
1927 ret = 0; 1927 ret = 0;
1928 } 1928 }
1929 kfree(bbio); 1929 btrfs_put_bbio(bbio);
1930 } 1930 }
1931 1931
1932 if (actual_bytes) 1932 if (actual_bytes)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 65bd285ef361..dab8af4450e1 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2058,7 +2058,7 @@ int repair_io_failure(struct inode *inode, u64 start, u64 length, u64 logical,
2058 sector = bbio->stripes[mirror_num-1].physical >> 9; 2058 sector = bbio->stripes[mirror_num-1].physical >> 9;
2059 bio->bi_iter.bi_sector = sector; 2059 bio->bi_iter.bi_sector = sector;
2060 dev = bbio->stripes[mirror_num-1].dev; 2060 dev = bbio->stripes[mirror_num-1].dev;
2061 kfree(bbio); 2061 btrfs_put_bbio(bbio);
2062 if (!dev || !dev->bdev || !dev->writeable) { 2062 if (!dev || !dev->bdev || !dev->writeable) {
2063 bio_put(bio); 2063 bio_put(bio);
2064 return -EIO; 2064 return -EIO;
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index e301d3302edf..cbc416204452 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -58,15 +58,6 @@
58 */ 58 */
59#define RBIO_CACHE_READY_BIT 3 59#define RBIO_CACHE_READY_BIT 3
60 60
61/*
62 * bbio and raid_map is managed by the caller, so we shouldn't free
63 * them here. And besides that, all rbios with this flag should not
64 * be cached, because we need raid_map to check the rbios' stripe
65 * is the same or not, but it is very likely that the caller has
66 * free raid_map, so don't cache those rbios.
67 */
68#define RBIO_HOLD_BBIO_MAP_BIT 4
69
70#define RBIO_CACHE_SIZE 1024 61#define RBIO_CACHE_SIZE 1024
71 62
72enum btrfs_rbio_ops { 63enum btrfs_rbio_ops {
@@ -834,19 +825,6 @@ done_nolock:
834 remove_rbio_from_cache(rbio); 825 remove_rbio_from_cache(rbio);
835} 826}
836 827
837static inline void
838__free_bbio(struct btrfs_bio *bbio, int need)
839{
840 if (need)
841 kfree(bbio);
842}
843
844static inline void free_bbio(struct btrfs_raid_bio *rbio)
845{
846 __free_bbio(rbio->bbio,
847 !test_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags));
848}
849
850static void __free_raid_bio(struct btrfs_raid_bio *rbio) 828static void __free_raid_bio(struct btrfs_raid_bio *rbio)
851{ 829{
852 int i; 830 int i;
@@ -866,8 +844,7 @@ static void __free_raid_bio(struct btrfs_raid_bio *rbio)
866 } 844 }
867 } 845 }
868 846
869 free_bbio(rbio); 847 btrfs_put_bbio(rbio->bbio);
870
871 kfree(rbio); 848 kfree(rbio);
872} 849}
873 850
@@ -1774,7 +1751,7 @@ int raid56_parity_write(struct btrfs_root *root, struct bio *bio,
1774 1751
1775 rbio = alloc_rbio(root, bbio, stripe_len); 1752 rbio = alloc_rbio(root, bbio, stripe_len);
1776 if (IS_ERR(rbio)) { 1753 if (IS_ERR(rbio)) {
1777 __free_bbio(bbio, 1); 1754 btrfs_put_bbio(bbio);
1778 return PTR_ERR(rbio); 1755 return PTR_ERR(rbio);
1779 } 1756 }
1780 bio_list_add(&rbio->bio_list, bio); 1757 bio_list_add(&rbio->bio_list, bio);
@@ -1990,8 +1967,7 @@ cleanup:
1990 1967
1991cleanup_io: 1968cleanup_io:
1992 if (rbio->operation == BTRFS_RBIO_READ_REBUILD) { 1969 if (rbio->operation == BTRFS_RBIO_READ_REBUILD) {
1993 if (err == 0 && 1970 if (err == 0)
1994 !test_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags))
1995 cache_rbio_pages(rbio); 1971 cache_rbio_pages(rbio);
1996 else 1972 else
1997 clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags); 1973 clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
@@ -2153,7 +2129,8 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio,
2153 2129
2154 rbio = alloc_rbio(root, bbio, stripe_len); 2130 rbio = alloc_rbio(root, bbio, stripe_len);
2155 if (IS_ERR(rbio)) { 2131 if (IS_ERR(rbio)) {
2156 __free_bbio(bbio, generic_io); 2132 if (generic_io)
2133 btrfs_put_bbio(bbio);
2157 return PTR_ERR(rbio); 2134 return PTR_ERR(rbio);
2158 } 2135 }
2159 2136
@@ -2164,7 +2141,8 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio,
2164 rbio->faila = find_logical_bio_stripe(rbio, bio); 2141 rbio->faila = find_logical_bio_stripe(rbio, bio);
2165 if (rbio->faila == -1) { 2142 if (rbio->faila == -1) {
2166 BUG(); 2143 BUG();
2167 __free_bbio(bbio, generic_io); 2144 if (generic_io)
2145 btrfs_put_bbio(bbio);
2168 kfree(rbio); 2146 kfree(rbio);
2169 return -EIO; 2147 return -EIO;
2170 } 2148 }
@@ -2173,7 +2151,7 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio,
2173 btrfs_bio_counter_inc_noblocked(root->fs_info); 2151 btrfs_bio_counter_inc_noblocked(root->fs_info);
2174 rbio->generic_bio_cnt = 1; 2152 rbio->generic_bio_cnt = 1;
2175 } else { 2153 } else {
2176 set_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags); 2154 btrfs_get_bbio(bbio);
2177 } 2155 }
2178 2156
2179 /* 2157 /*
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
index 4d3d4e5287c5..0e7beea92b4c 100644
--- a/fs/btrfs/reada.c
+++ b/fs/btrfs/reada.c
@@ -461,7 +461,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
461 spin_unlock(&fs_info->reada_lock); 461 spin_unlock(&fs_info->reada_lock);
462 btrfs_dev_replace_unlock(&fs_info->dev_replace); 462 btrfs_dev_replace_unlock(&fs_info->dev_replace);
463 463
464 kfree(bbio); 464 btrfs_put_bbio(bbio);
465 return re; 465 return re;
466 466
467error: 467error:
@@ -486,7 +486,7 @@ error:
486 kref_put(&zone->refcnt, reada_zone_release); 486 kref_put(&zone->refcnt, reada_zone_release);
487 spin_unlock(&fs_info->reada_lock); 487 spin_unlock(&fs_info->reada_lock);
488 } 488 }
489 kfree(bbio); 489 btrfs_put_bbio(bbio);
490 kfree(re); 490 kfree(re);
491 return re_exist; 491 return re_exist;
492} 492}
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 9d07c981ec82..1388e7127eea 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -855,7 +855,7 @@ static inline void scrub_get_recover(struct scrub_recover *recover)
855static inline void scrub_put_recover(struct scrub_recover *recover) 855static inline void scrub_put_recover(struct scrub_recover *recover)
856{ 856{
857 if (atomic_dec_and_test(&recover->refs)) { 857 if (atomic_dec_and_test(&recover->refs)) {
858 kfree(recover->bbio); 858 btrfs_put_bbio(recover->bbio);
859 kfree(recover); 859 kfree(recover);
860 } 860 }
861} 861}
@@ -1373,13 +1373,13 @@ static int scrub_setup_recheck_block(struct scrub_ctx *sctx,
1373 ret = btrfs_map_sblock(fs_info, REQ_GET_READ_MIRRORS, logical, 1373 ret = btrfs_map_sblock(fs_info, REQ_GET_READ_MIRRORS, logical,
1374 &mapped_length, &bbio, 0, 1); 1374 &mapped_length, &bbio, 0, 1);
1375 if (ret || !bbio || mapped_length < sublen) { 1375 if (ret || !bbio || mapped_length < sublen) {
1376 kfree(bbio); 1376 btrfs_put_bbio(bbio);
1377 return -EIO; 1377 return -EIO;
1378 } 1378 }
1379 1379
1380 recover = kzalloc(sizeof(struct scrub_recover), GFP_NOFS); 1380 recover = kzalloc(sizeof(struct scrub_recover), GFP_NOFS);
1381 if (!recover) { 1381 if (!recover) {
1382 kfree(bbio); 1382 btrfs_put_bbio(bbio);
1383 return -ENOMEM; 1383 return -ENOMEM;
1384 } 1384 }
1385 1385
@@ -2748,7 +2748,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
2748rbio_out: 2748rbio_out:
2749 bio_put(bio); 2749 bio_put(bio);
2750bbio_out: 2750bbio_out:
2751 kfree(bbio); 2751 btrfs_put_bbio(bbio);
2752 bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap, 2752 bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap,
2753 sparity->nsectors); 2753 sparity->nsectors);
2754 spin_lock(&sctx->stat_lock); 2754 spin_lock(&sctx->stat_lock);
@@ -3879,14 +3879,14 @@ static void scrub_remap_extent(struct btrfs_fs_info *fs_info,
3879 &mapped_length, &bbio, 0); 3879 &mapped_length, &bbio, 0);
3880 if (ret || !bbio || mapped_length < extent_len || 3880 if (ret || !bbio || mapped_length < extent_len ||
3881 !bbio->stripes[0].dev->bdev) { 3881 !bbio->stripes[0].dev->bdev) {
3882 kfree(bbio); 3882 btrfs_put_bbio(bbio);
3883 return; 3883 return;
3884 } 3884 }
3885 3885
3886 *extent_physical = bbio->stripes[0].physical; 3886 *extent_physical = bbio->stripes[0].physical;
3887 *extent_mirror_num = bbio->mirror_num; 3887 *extent_mirror_num = bbio->mirror_num;
3888 *extent_dev = bbio->stripes[0].dev; 3888 *extent_dev = bbio->stripes[0].dev;
3889 kfree(bbio); 3889 btrfs_put_bbio(bbio);
3890} 3890}
3891 3891
3892static int scrub_setup_wr_ctx(struct scrub_ctx *sctx, 3892static int scrub_setup_wr_ctx(struct scrub_ctx *sctx,
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c0f1d524c371..0843bcd6304c 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4901,6 +4901,37 @@ static void sort_parity_stripes(struct btrfs_bio *bbio, int num_stripes)
4901 } 4901 }
4902} 4902}
4903 4903
4904static struct btrfs_bio *alloc_btrfs_bio(int total_stripes, int real_stripes)
4905{
4906 struct btrfs_bio *bbio = kzalloc(
4907 sizeof(struct btrfs_bio) +
4908 sizeof(struct btrfs_bio_stripe) * (total_stripes) +
4909 sizeof(int) * (real_stripes) +
4910 sizeof(u64) * (real_stripes),
4911 GFP_NOFS);
4912 if (!bbio)
4913 return NULL;
4914
4915 atomic_set(&bbio->error, 0);
4916 atomic_set(&bbio->refs, 1);
4917
4918 return bbio;
4919}
4920
4921void btrfs_get_bbio(struct btrfs_bio *bbio)
4922{
4923 WARN_ON(!atomic_read(&bbio->refs));
4924 atomic_inc(&bbio->refs);
4925}
4926
4927void btrfs_put_bbio(struct btrfs_bio *bbio)
4928{
4929 if (!bbio)
4930 return;
4931 if (atomic_dec_and_test(&bbio->refs))
4932 kfree(bbio);
4933}
4934
4904static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, 4935static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4905 u64 logical, u64 *length, 4936 u64 logical, u64 *length,
4906 struct btrfs_bio **bbio_ret, 4937 struct btrfs_bio **bbio_ret,
@@ -5052,7 +5083,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5052 * is not left of the left cursor 5083 * is not left of the left cursor
5053 */ 5084 */
5054 ret = -EIO; 5085 ret = -EIO;
5055 kfree(tmp_bbio); 5086 btrfs_put_bbio(tmp_bbio);
5056 goto out; 5087 goto out;
5057 } 5088 }
5058 5089
@@ -5087,11 +5118,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5087 } else { 5118 } else {
5088 WARN_ON(1); 5119 WARN_ON(1);
5089 ret = -EIO; 5120 ret = -EIO;
5090 kfree(tmp_bbio); 5121 btrfs_put_bbio(tmp_bbio);
5091 goto out; 5122 goto out;
5092 } 5123 }
5093 5124
5094 kfree(tmp_bbio); 5125 btrfs_put_bbio(tmp_bbio);
5095 } else if (mirror_num > map->num_stripes) { 5126 } else if (mirror_num > map->num_stripes) {
5096 mirror_num = 0; 5127 mirror_num = 0;
5097 } 5128 }
@@ -5213,13 +5244,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5213 tgtdev_indexes = num_stripes; 5244 tgtdev_indexes = num_stripes;
5214 } 5245 }
5215 5246
5216 bbio = kzalloc(btrfs_bio_size(num_alloc_stripes, tgtdev_indexes), 5247 bbio = alloc_btrfs_bio(num_alloc_stripes, tgtdev_indexes);
5217 GFP_NOFS);
5218 if (!bbio) { 5248 if (!bbio) {
5219 ret = -ENOMEM; 5249 ret = -ENOMEM;
5220 goto out; 5250 goto out;
5221 } 5251 }
5222 atomic_set(&bbio->error, 0);
5223 if (dev_replace_is_ongoing) 5252 if (dev_replace_is_ongoing)
5224 bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes); 5253 bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes);
5225 5254
@@ -5558,7 +5587,7 @@ static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int e
5558 bio_endio_nodec(bio, err); 5587 bio_endio_nodec(bio, err);
5559 else 5588 else
5560 bio_endio(bio, err); 5589 bio_endio(bio, err);
5561 kfree(bbio); 5590 btrfs_put_bbio(bbio);
5562} 5591}
5563 5592
5564static void btrfs_end_bio(struct bio *bio, int err) 5593static void btrfs_end_bio(struct bio *bio, int err)
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index fb0e8c3f296e..4313e8ff91e5 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -295,6 +295,7 @@ typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err);
295#define BTRFS_BIO_ORIG_BIO_SUBMITTED (1 << 0) 295#define BTRFS_BIO_ORIG_BIO_SUBMITTED (1 << 0)
296 296
297struct btrfs_bio { 297struct btrfs_bio {
298 atomic_t refs;
298 atomic_t stripes_pending; 299 atomic_t stripes_pending;
299 struct btrfs_fs_info *fs_info; 300 struct btrfs_fs_info *fs_info;
300 bio_end_io_t *end_io; 301 bio_end_io_t *end_io;
@@ -394,13 +395,8 @@ struct btrfs_balance_control {
394 395
395int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start, 396int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start,
396 u64 end, u64 *length); 397 u64 end, u64 *length);
397 398void btrfs_get_bbio(struct btrfs_bio *bbio);
398#define btrfs_bio_size(total_stripes, real_stripes) \ 399void btrfs_put_bbio(struct btrfs_bio *bbio);
399 (sizeof(struct btrfs_bio) + \
400 (sizeof(struct btrfs_bio_stripe) * (total_stripes)) + \
401 (sizeof(int) * (real_stripes)) + \
402 (sizeof(u64) * (real_stripes)))
403
404int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, 400int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
405 u64 logical, u64 *length, 401 u64 logical, u64 *length,
406 struct btrfs_bio **bbio_ret, int mirror_num); 402 struct btrfs_bio **bbio_ret, int mirror_num);