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 /fs/btrfs/volumes.c | |
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>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 43 |
1 files changed, 36 insertions, 7 deletions
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) |