diff options
author | Zhao Lei <zhaolei@cn.fujitsu.com> | 2015-01-20 02:11:34 -0500 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-01-21 21:06:48 -0500 |
commit | 6e9606d2a2dce098c1739fb3cd82a1c34fd73d3a (patch) | |
tree | eeeb1c991d4971cdbfda675bbbb4b37b0c6f5ebb | |
parent | 8e5cfb55d3f7dc764cd7f4c966d4c2687eaf7569 (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.c | 2 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 2 | ||||
-rw-r--r-- | fs/btrfs/raid56.c | 38 | ||||
-rw-r--r-- | fs/btrfs/reada.c | 4 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 12 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 43 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 10 |
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 | ||
72 | enum btrfs_rbio_ops { | 63 | enum 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 | ||
837 | static inline void | ||
838 | __free_bbio(struct btrfs_bio *bbio, int need) | ||
839 | { | ||
840 | if (need) | ||
841 | kfree(bbio); | ||
842 | } | ||
843 | |||
844 | static 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 | |||
850 | static void __free_raid_bio(struct btrfs_raid_bio *rbio) | 828 | static 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 | ||
1991 | cleanup_io: | 1968 | cleanup_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 | ||
467 | error: | 467 | error: |
@@ -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) | |||
855 | static inline void scrub_put_recover(struct scrub_recover *recover) | 855 | static 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) | |||
2748 | rbio_out: | 2748 | rbio_out: |
2749 | bio_put(bio); | 2749 | bio_put(bio); |
2750 | bbio_out: | 2750 | bbio_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 | ||
3892 | static int scrub_setup_wr_ctx(struct scrub_ctx *sctx, | 3892 | static 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 | ||
4904 | static 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 | |||
4921 | void btrfs_get_bbio(struct btrfs_bio *bbio) | ||
4922 | { | ||
4923 | WARN_ON(!atomic_read(&bbio->refs)); | ||
4924 | atomic_inc(&bbio->refs); | ||
4925 | } | ||
4926 | |||
4927 | void 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 | |||
4904 | static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | 4935 | static 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 | ||
5564 | static void btrfs_end_bio(struct bio *bio, int err) | 5593 | static 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 | ||
297 | struct btrfs_bio { | 297 | struct 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 | ||
395 | int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start, | 396 | int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start, |
396 | u64 end, u64 *length); | 397 | u64 end, u64 *length); |
397 | 398 | void btrfs_get_bbio(struct btrfs_bio *bbio); | |
398 | #define btrfs_bio_size(total_stripes, real_stripes) \ | 399 | void 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 | |||
404 | int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | 400 | int 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); |