mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
block: Add bioset_init()/bioset_exit()
Similarly to mempool_init()/mempool_exit(), take a pointer indirection out of allocation/freeing by allowing biosets to be embedded in other structs. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
8aa6ba2f6e
commit
917a38c71a
93
block/bio.c
93
block/bio.c
@ -1856,21 +1856,83 @@ int biovec_init_pool(mempool_t *pool, int pool_entries)
|
||||
return mempool_init_slab_pool(pool, pool_entries, bp->slab);
|
||||
}
|
||||
|
||||
void bioset_free(struct bio_set *bs)
|
||||
/*
|
||||
* bioset_exit - exit a bioset initialized with bioset_init()
|
||||
*
|
||||
* May be called on a zeroed but uninitialized bioset (i.e. allocated with
|
||||
* kzalloc()).
|
||||
*/
|
||||
void bioset_exit(struct bio_set *bs)
|
||||
{
|
||||
if (bs->rescue_workqueue)
|
||||
destroy_workqueue(bs->rescue_workqueue);
|
||||
bs->rescue_workqueue = NULL;
|
||||
|
||||
mempool_exit(&bs->bio_pool);
|
||||
mempool_exit(&bs->bvec_pool);
|
||||
|
||||
bioset_integrity_free(bs);
|
||||
bio_put_slab(bs);
|
||||
if (bs->bio_slab)
|
||||
bio_put_slab(bs);
|
||||
bs->bio_slab = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(bioset_exit);
|
||||
|
||||
void bioset_free(struct bio_set *bs)
|
||||
{
|
||||
bioset_exit(bs);
|
||||
kfree(bs);
|
||||
}
|
||||
EXPORT_SYMBOL(bioset_free);
|
||||
|
||||
/**
|
||||
* bioset_init - Initialize a bio_set
|
||||
* @pool_size: Number of bio and bio_vecs to cache in the mempool
|
||||
* @front_pad: Number of bytes to allocate in front of the returned bio
|
||||
* @flags: Flags to modify behavior, currently %BIOSET_NEED_BVECS
|
||||
* and %BIOSET_NEED_RESCUER
|
||||
*
|
||||
* Similar to bioset_create(), but initializes a passed-in bioset instead of
|
||||
* separately allocating it.
|
||||
*/
|
||||
int bioset_init(struct bio_set *bs,
|
||||
unsigned int pool_size,
|
||||
unsigned int front_pad,
|
||||
int flags)
|
||||
{
|
||||
unsigned int back_pad = BIO_INLINE_VECS * sizeof(struct bio_vec);
|
||||
|
||||
bs->front_pad = front_pad;
|
||||
|
||||
spin_lock_init(&bs->rescue_lock);
|
||||
bio_list_init(&bs->rescue_list);
|
||||
INIT_WORK(&bs->rescue_work, bio_alloc_rescue);
|
||||
|
||||
bs->bio_slab = bio_find_or_create_slab(front_pad + back_pad);
|
||||
if (!bs->bio_slab)
|
||||
return -ENOMEM;
|
||||
|
||||
if (mempool_init_slab_pool(&bs->bio_pool, pool_size, bs->bio_slab))
|
||||
goto bad;
|
||||
|
||||
if ((flags & BIOSET_NEED_BVECS) &&
|
||||
biovec_init_pool(&bs->bvec_pool, pool_size))
|
||||
goto bad;
|
||||
|
||||
if (!(flags & BIOSET_NEED_RESCUER))
|
||||
return 0;
|
||||
|
||||
bs->rescue_workqueue = alloc_workqueue("bioset", WQ_MEM_RECLAIM, 0);
|
||||
if (!bs->rescue_workqueue)
|
||||
goto bad;
|
||||
|
||||
return 0;
|
||||
bad:
|
||||
bioset_exit(bs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
EXPORT_SYMBOL(bioset_init);
|
||||
|
||||
/**
|
||||
* bioset_create - Create a bio_set
|
||||
* @pool_size: Number of bio and bio_vecs to cache in the mempool
|
||||
@ -1895,43 +1957,18 @@ struct bio_set *bioset_create(unsigned int pool_size,
|
||||
unsigned int front_pad,
|
||||
int flags)
|
||||
{
|
||||
unsigned int back_pad = BIO_INLINE_VECS * sizeof(struct bio_vec);
|
||||
struct bio_set *bs;
|
||||
|
||||
bs = kzalloc(sizeof(*bs), GFP_KERNEL);
|
||||
if (!bs)
|
||||
return NULL;
|
||||
|
||||
bs->front_pad = front_pad;
|
||||
|
||||
spin_lock_init(&bs->rescue_lock);
|
||||
bio_list_init(&bs->rescue_list);
|
||||
INIT_WORK(&bs->rescue_work, bio_alloc_rescue);
|
||||
|
||||
bs->bio_slab = bio_find_or_create_slab(front_pad + back_pad);
|
||||
if (!bs->bio_slab) {
|
||||
if (bioset_init(bs, pool_size, front_pad, flags)) {
|
||||
kfree(bs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mempool_init_slab_pool(&bs->bio_pool, pool_size, bs->bio_slab))
|
||||
goto bad;
|
||||
|
||||
if ((flags & BIOSET_NEED_BVECS) &&
|
||||
biovec_init_pool(&bs->bvec_pool, pool_size))
|
||||
goto bad;
|
||||
|
||||
if (!(flags & BIOSET_NEED_RESCUER))
|
||||
return bs;
|
||||
|
||||
bs->rescue_workqueue = alloc_workqueue("bioset", WQ_MEM_RECLAIM, 0);
|
||||
if (!bs->rescue_workqueue)
|
||||
goto bad;
|
||||
|
||||
return bs;
|
||||
bad:
|
||||
bioset_free(bs);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(bioset_create);
|
||||
|
||||
|
@ -406,6 +406,8 @@ static inline struct bio *bio_next_split(struct bio *bio, int sectors,
|
||||
return bio_split(bio, sectors, gfp, bs);
|
||||
}
|
||||
|
||||
extern int bioset_init(struct bio_set *, unsigned int, unsigned int, int flags);
|
||||
extern void bioset_exit(struct bio_set *);
|
||||
extern struct bio_set *bioset_create(unsigned int, unsigned int, int flags);
|
||||
enum {
|
||||
BIOSET_NEED_BVECS = BIT(0),
|
||||
|
Loading…
Reference in New Issue
Block a user