mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-16 01:04:08 +08:00
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>
This commit is contained in:
parent
8e5cfb55d3
commit
6e9606d2a2
@ -1926,7 +1926,7 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
|
|||||||
*/
|
*/
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actual_bytes)
|
if (actual_bytes)
|
||||||
|
@ -2058,7 +2058,7 @@ int repair_io_failure(struct inode *inode, u64 start, u64 length, u64 logical,
|
|||||||
sector = bbio->stripes[mirror_num-1].physical >> 9;
|
sector = bbio->stripes[mirror_num-1].physical >> 9;
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
dev = bbio->stripes[mirror_num-1].dev;
|
dev = bbio->stripes[mirror_num-1].dev;
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
if (!dev || !dev->bdev || !dev->writeable) {
|
if (!dev || !dev->bdev || !dev->writeable) {
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -58,15 +58,6 @@
|
|||||||
*/
|
*/
|
||||||
#define RBIO_CACHE_READY_BIT 3
|
#define RBIO_CACHE_READY_BIT 3
|
||||||
|
|
||||||
/*
|
|
||||||
* bbio and raid_map is managed by the caller, so we shouldn't free
|
|
||||||
* them here. And besides that, all rbios with this flag should not
|
|
||||||
* be cached, because we need raid_map to check the rbios' stripe
|
|
||||||
* is the same or not, but it is very likely that the caller has
|
|
||||||
* free raid_map, so don't cache those rbios.
|
|
||||||
*/
|
|
||||||
#define RBIO_HOLD_BBIO_MAP_BIT 4
|
|
||||||
|
|
||||||
#define RBIO_CACHE_SIZE 1024
|
#define RBIO_CACHE_SIZE 1024
|
||||||
|
|
||||||
enum btrfs_rbio_ops {
|
enum btrfs_rbio_ops {
|
||||||
@ -834,19 +825,6 @@ done_nolock:
|
|||||||
remove_rbio_from_cache(rbio);
|
remove_rbio_from_cache(rbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
__free_bbio(struct btrfs_bio *bbio, int need)
|
|
||||||
{
|
|
||||||
if (need)
|
|
||||||
kfree(bbio);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void free_bbio(struct btrfs_raid_bio *rbio)
|
|
||||||
{
|
|
||||||
__free_bbio(rbio->bbio,
|
|
||||||
!test_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __free_raid_bio(struct btrfs_raid_bio *rbio)
|
static void __free_raid_bio(struct btrfs_raid_bio *rbio)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -866,8 +844,7 @@ static void __free_raid_bio(struct btrfs_raid_bio *rbio)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_bbio(rbio);
|
btrfs_put_bbio(rbio->bbio);
|
||||||
|
|
||||||
kfree(rbio);
|
kfree(rbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1774,7 +1751,7 @@ int raid56_parity_write(struct btrfs_root *root, struct bio *bio,
|
|||||||
|
|
||||||
rbio = alloc_rbio(root, bbio, stripe_len);
|
rbio = alloc_rbio(root, bbio, stripe_len);
|
||||||
if (IS_ERR(rbio)) {
|
if (IS_ERR(rbio)) {
|
||||||
__free_bbio(bbio, 1);
|
btrfs_put_bbio(bbio);
|
||||||
return PTR_ERR(rbio);
|
return PTR_ERR(rbio);
|
||||||
}
|
}
|
||||||
bio_list_add(&rbio->bio_list, bio);
|
bio_list_add(&rbio->bio_list, bio);
|
||||||
@ -1990,8 +1967,7 @@ cleanup:
|
|||||||
|
|
||||||
cleanup_io:
|
cleanup_io:
|
||||||
if (rbio->operation == BTRFS_RBIO_READ_REBUILD) {
|
if (rbio->operation == BTRFS_RBIO_READ_REBUILD) {
|
||||||
if (err == 0 &&
|
if (err == 0)
|
||||||
!test_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags))
|
|
||||||
cache_rbio_pages(rbio);
|
cache_rbio_pages(rbio);
|
||||||
else
|
else
|
||||||
clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
|
clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
|
||||||
@ -2153,7 +2129,8 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio,
|
|||||||
|
|
||||||
rbio = alloc_rbio(root, bbio, stripe_len);
|
rbio = alloc_rbio(root, bbio, stripe_len);
|
||||||
if (IS_ERR(rbio)) {
|
if (IS_ERR(rbio)) {
|
||||||
__free_bbio(bbio, generic_io);
|
if (generic_io)
|
||||||
|
btrfs_put_bbio(bbio);
|
||||||
return PTR_ERR(rbio);
|
return PTR_ERR(rbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2164,7 +2141,8 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio,
|
|||||||
rbio->faila = find_logical_bio_stripe(rbio, bio);
|
rbio->faila = find_logical_bio_stripe(rbio, bio);
|
||||||
if (rbio->faila == -1) {
|
if (rbio->faila == -1) {
|
||||||
BUG();
|
BUG();
|
||||||
__free_bbio(bbio, generic_io);
|
if (generic_io)
|
||||||
|
btrfs_put_bbio(bbio);
|
||||||
kfree(rbio);
|
kfree(rbio);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -2173,7 +2151,7 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio,
|
|||||||
btrfs_bio_counter_inc_noblocked(root->fs_info);
|
btrfs_bio_counter_inc_noblocked(root->fs_info);
|
||||||
rbio->generic_bio_cnt = 1;
|
rbio->generic_bio_cnt = 1;
|
||||||
} else {
|
} else {
|
||||||
set_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags);
|
btrfs_get_bbio(bbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -461,7 +461,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
|
|||||||
spin_unlock(&fs_info->reada_lock);
|
spin_unlock(&fs_info->reada_lock);
|
||||||
btrfs_dev_replace_unlock(&fs_info->dev_replace);
|
btrfs_dev_replace_unlock(&fs_info->dev_replace);
|
||||||
|
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
return re;
|
return re;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -486,7 +486,7 @@ error:
|
|||||||
kref_put(&zone->refcnt, reada_zone_release);
|
kref_put(&zone->refcnt, reada_zone_release);
|
||||||
spin_unlock(&fs_info->reada_lock);
|
spin_unlock(&fs_info->reada_lock);
|
||||||
}
|
}
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
kfree(re);
|
kfree(re);
|
||||||
return re_exist;
|
return re_exist;
|
||||||
}
|
}
|
||||||
|
@ -855,7 +855,7 @@ static inline void scrub_get_recover(struct scrub_recover *recover)
|
|||||||
static inline void scrub_put_recover(struct scrub_recover *recover)
|
static inline void scrub_put_recover(struct scrub_recover *recover)
|
||||||
{
|
{
|
||||||
if (atomic_dec_and_test(&recover->refs)) {
|
if (atomic_dec_and_test(&recover->refs)) {
|
||||||
kfree(recover->bbio);
|
btrfs_put_bbio(recover->bbio);
|
||||||
kfree(recover);
|
kfree(recover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1373,13 +1373,13 @@ static int scrub_setup_recheck_block(struct scrub_ctx *sctx,
|
|||||||
ret = btrfs_map_sblock(fs_info, REQ_GET_READ_MIRRORS, logical,
|
ret = btrfs_map_sblock(fs_info, REQ_GET_READ_MIRRORS, logical,
|
||||||
&mapped_length, &bbio, 0, 1);
|
&mapped_length, &bbio, 0, 1);
|
||||||
if (ret || !bbio || mapped_length < sublen) {
|
if (ret || !bbio || mapped_length < sublen) {
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
recover = kzalloc(sizeof(struct scrub_recover), GFP_NOFS);
|
recover = kzalloc(sizeof(struct scrub_recover), GFP_NOFS);
|
||||||
if (!recover) {
|
if (!recover) {
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2748,7 +2748,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
|
|||||||
rbio_out:
|
rbio_out:
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
bbio_out:
|
bbio_out:
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap,
|
bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap,
|
||||||
sparity->nsectors);
|
sparity->nsectors);
|
||||||
spin_lock(&sctx->stat_lock);
|
spin_lock(&sctx->stat_lock);
|
||||||
@ -3879,14 +3879,14 @@ static void scrub_remap_extent(struct btrfs_fs_info *fs_info,
|
|||||||
&mapped_length, &bbio, 0);
|
&mapped_length, &bbio, 0);
|
||||||
if (ret || !bbio || mapped_length < extent_len ||
|
if (ret || !bbio || mapped_length < extent_len ||
|
||||||
!bbio->stripes[0].dev->bdev) {
|
!bbio->stripes[0].dev->bdev) {
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*extent_physical = bbio->stripes[0].physical;
|
*extent_physical = bbio->stripes[0].physical;
|
||||||
*extent_mirror_num = bbio->mirror_num;
|
*extent_mirror_num = bbio->mirror_num;
|
||||||
*extent_dev = bbio->stripes[0].dev;
|
*extent_dev = bbio->stripes[0].dev;
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scrub_setup_wr_ctx(struct scrub_ctx *sctx,
|
static int scrub_setup_wr_ctx(struct scrub_ctx *sctx,
|
||||||
|
@ -4901,6 +4901,37 @@ static void sort_parity_stripes(struct btrfs_bio *bbio, int num_stripes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct btrfs_bio *alloc_btrfs_bio(int total_stripes, int real_stripes)
|
||||||
|
{
|
||||||
|
struct btrfs_bio *bbio = kzalloc(
|
||||||
|
sizeof(struct btrfs_bio) +
|
||||||
|
sizeof(struct btrfs_bio_stripe) * (total_stripes) +
|
||||||
|
sizeof(int) * (real_stripes) +
|
||||||
|
sizeof(u64) * (real_stripes),
|
||||||
|
GFP_NOFS);
|
||||||
|
if (!bbio)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
atomic_set(&bbio->error, 0);
|
||||||
|
atomic_set(&bbio->refs, 1);
|
||||||
|
|
||||||
|
return bbio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void btrfs_get_bbio(struct btrfs_bio *bbio)
|
||||||
|
{
|
||||||
|
WARN_ON(!atomic_read(&bbio->refs));
|
||||||
|
atomic_inc(&bbio->refs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btrfs_put_bbio(struct btrfs_bio *bbio)
|
||||||
|
{
|
||||||
|
if (!bbio)
|
||||||
|
return;
|
||||||
|
if (atomic_dec_and_test(&bbio->refs))
|
||||||
|
kfree(bbio);
|
||||||
|
}
|
||||||
|
|
||||||
static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
||||||
u64 logical, u64 *length,
|
u64 logical, u64 *length,
|
||||||
struct btrfs_bio **bbio_ret,
|
struct btrfs_bio **bbio_ret,
|
||||||
@ -5052,7 +5083,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|||||||
* is not left of the left cursor
|
* is not left of the left cursor
|
||||||
*/
|
*/
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
kfree(tmp_bbio);
|
btrfs_put_bbio(tmp_bbio);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5087,11 +5118,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|||||||
} else {
|
} else {
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
kfree(tmp_bbio);
|
btrfs_put_bbio(tmp_bbio);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(tmp_bbio);
|
btrfs_put_bbio(tmp_bbio);
|
||||||
} else if (mirror_num > map->num_stripes) {
|
} else if (mirror_num > map->num_stripes) {
|
||||||
mirror_num = 0;
|
mirror_num = 0;
|
||||||
}
|
}
|
||||||
@ -5213,13 +5244,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|||||||
tgtdev_indexes = num_stripes;
|
tgtdev_indexes = num_stripes;
|
||||||
}
|
}
|
||||||
|
|
||||||
bbio = kzalloc(btrfs_bio_size(num_alloc_stripes, tgtdev_indexes),
|
bbio = alloc_btrfs_bio(num_alloc_stripes, tgtdev_indexes);
|
||||||
GFP_NOFS);
|
|
||||||
if (!bbio) {
|
if (!bbio) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
atomic_set(&bbio->error, 0);
|
|
||||||
if (dev_replace_is_ongoing)
|
if (dev_replace_is_ongoing)
|
||||||
bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes);
|
bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes);
|
||||||
|
|
||||||
@ -5558,7 +5587,7 @@ static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int e
|
|||||||
bio_endio_nodec(bio, err);
|
bio_endio_nodec(bio, err);
|
||||||
else
|
else
|
||||||
bio_endio(bio, err);
|
bio_endio(bio, err);
|
||||||
kfree(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfs_end_bio(struct bio *bio, int err)
|
static void btrfs_end_bio(struct bio *bio, int err)
|
||||||
|
@ -295,6 +295,7 @@ typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err);
|
|||||||
#define BTRFS_BIO_ORIG_BIO_SUBMITTED (1 << 0)
|
#define BTRFS_BIO_ORIG_BIO_SUBMITTED (1 << 0)
|
||||||
|
|
||||||
struct btrfs_bio {
|
struct btrfs_bio {
|
||||||
|
atomic_t refs;
|
||||||
atomic_t stripes_pending;
|
atomic_t stripes_pending;
|
||||||
struct btrfs_fs_info *fs_info;
|
struct btrfs_fs_info *fs_info;
|
||||||
bio_end_io_t *end_io;
|
bio_end_io_t *end_io;
|
||||||
@ -394,13 +395,8 @@ struct btrfs_balance_control {
|
|||||||
|
|
||||||
int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start,
|
int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start,
|
||||||
u64 end, u64 *length);
|
u64 end, u64 *length);
|
||||||
|
void btrfs_get_bbio(struct btrfs_bio *bbio);
|
||||||
#define btrfs_bio_size(total_stripes, real_stripes) \
|
void btrfs_put_bbio(struct btrfs_bio *bbio);
|
||||||
(sizeof(struct btrfs_bio) + \
|
|
||||||
(sizeof(struct btrfs_bio_stripe) * (total_stripes)) + \
|
|
||||||
(sizeof(int) * (real_stripes)) + \
|
|
||||||
(sizeof(u64) * (real_stripes)))
|
|
||||||
|
|
||||||
int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
||||||
u64 logical, u64 *length,
|
u64 logical, u64 *length,
|
||||||
struct btrfs_bio **bbio_ret, int mirror_num);
|
struct btrfs_bio **bbio_ret, int mirror_num);
|
||||||
|
Loading…
Reference in New Issue
Block a user