aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-io.c6
-rw-r--r--drivers/md/dm.c6
-rw-r--r--fs/bio.c32
-rw-r--r--include/linux/bio.h2
4 files changed, 34 insertions, 12 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 45754bb6a799..9de000131a8a 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -239,6 +239,11 @@ static void vm_dp_init(struct dpages *dp, void *data)
239 dp->context_ptr = data; 239 dp->context_ptr = data;
240} 240}
241 241
242static void dm_bio_destructor(struct bio *bio)
243{
244 bio_free(bio, _bios);
245}
246
242/*----------------------------------------------------------------- 247/*-----------------------------------------------------------------
243 * IO routines that accept a list of pages. 248 * IO routines that accept a list of pages.
244 *---------------------------------------------------------------*/ 249 *---------------------------------------------------------------*/
@@ -263,6 +268,7 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
263 bio->bi_bdev = where->bdev; 268 bio->bi_bdev = where->bdev;
264 bio->bi_end_io = endio; 269 bio->bi_end_io = endio;
265 bio->bi_private = io; 270 bio->bi_private = io;
271 bio->bi_destructor = dm_bio_destructor;
266 bio_set_region(bio, region); 272 bio_set_region(bio, region);
267 273
268 /* 274 /*
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index d487d9deb98e..930b9fc27953 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -399,6 +399,11 @@ struct clone_info {
399 unsigned short idx; 399 unsigned short idx;
400}; 400};
401 401
402static void dm_bio_destructor(struct bio *bio)
403{
404 bio_free(bio, dm_set);
405}
406
402/* 407/*
403 * Creates a little bio that is just does part of a bvec. 408 * Creates a little bio that is just does part of a bvec.
404 */ 409 */
@@ -410,6 +415,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
410 struct bio_vec *bv = bio->bi_io_vec + idx; 415 struct bio_vec *bv = bio->bi_io_vec + idx;
411 416
412 clone = bio_alloc_bioset(GFP_NOIO, 1, dm_set); 417 clone = bio_alloc_bioset(GFP_NOIO, 1, dm_set);
418 clone->bi_destructor = dm_bio_destructor;
413 *clone->bi_io_vec = *bv; 419 *clone->bi_io_vec = *bv;
414 420
415 clone->bi_sector = sector; 421 clone->bi_sector = sector;
diff --git a/fs/bio.c b/fs/bio.c
index 1f2d4649b188..bf3ec9d2b54c 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -104,18 +104,22 @@ static inline struct bio_vec *bvec_alloc_bs(unsigned int __nocast gfp_mask, int
104 return bvl; 104 return bvl;
105} 105}
106 106
107/* 107void bio_free(struct bio *bio, struct bio_set *bio_set)
108 * default destructor for a bio allocated with bio_alloc_bioset()
109 */
110static void bio_destructor(struct bio *bio)
111{ 108{
112 const int pool_idx = BIO_POOL_IDX(bio); 109 const int pool_idx = BIO_POOL_IDX(bio);
113 struct bio_set *bs = bio->bi_set;
114 110
115 BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS); 111 BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
116 112
117 mempool_free(bio->bi_io_vec, bs->bvec_pools[pool_idx]); 113 mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]);
118 mempool_free(bio, bs->bio_pool); 114 mempool_free(bio, bio_set->bio_pool);
115}
116
117/*
118 * default destructor for a bio allocated with bio_alloc_bioset()
119 */
120static void bio_fs_destructor(struct bio *bio)
121{
122 bio_free(bio, fs_bio_set);
119} 123}
120 124
121inline void bio_init(struct bio *bio) 125inline void bio_init(struct bio *bio)
@@ -171,8 +175,6 @@ struct bio *bio_alloc_bioset(unsigned int __nocast gfp_mask, int nr_iovecs, stru
171 bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; 175 bio->bi_max_vecs = bvec_slabs[idx].nr_vecs;
172 } 176 }
173 bio->bi_io_vec = bvl; 177 bio->bi_io_vec = bvl;
174 bio->bi_destructor = bio_destructor;
175 bio->bi_set = bs;
176 } 178 }
177out: 179out:
178 return bio; 180 return bio;
@@ -180,7 +182,12 @@ out:
180 182
181struct bio *bio_alloc(unsigned int __nocast gfp_mask, int nr_iovecs) 183struct bio *bio_alloc(unsigned int __nocast gfp_mask, int nr_iovecs)
182{ 184{
183 return bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set); 185 struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
186
187 if (bio)
188 bio->bi_destructor = bio_fs_destructor;
189
190 return bio;
184} 191}
185 192
186void zero_fill_bio(struct bio *bio) 193void zero_fill_bio(struct bio *bio)
@@ -273,8 +280,10 @@ struct bio *bio_clone(struct bio *bio, unsigned int __nocast gfp_mask)
273{ 280{
274 struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set); 281 struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set);
275 282
276 if (b) 283 if (b) {
284 b->bi_destructor = bio_fs_destructor;
277 __bio_clone(b, bio); 285 __bio_clone(b, bio);
286 }
278 287
279 return b; 288 return b;
280} 289}
@@ -1075,6 +1084,7 @@ subsys_initcall(init_bio);
1075 1084
1076EXPORT_SYMBOL(bio_alloc); 1085EXPORT_SYMBOL(bio_alloc);
1077EXPORT_SYMBOL(bio_put); 1086EXPORT_SYMBOL(bio_put);
1087EXPORT_SYMBOL(bio_free);
1078EXPORT_SYMBOL(bio_endio); 1088EXPORT_SYMBOL(bio_endio);
1079EXPORT_SYMBOL(bio_init); 1089EXPORT_SYMBOL(bio_init);
1080EXPORT_SYMBOL(__bio_clone); 1090EXPORT_SYMBOL(__bio_clone);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 36ef29fa0d8b..69e047989f1c 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -111,7 +111,6 @@ struct bio {
111 void *bi_private; 111 void *bi_private;
112 112
113 bio_destructor_t *bi_destructor; /* destructor */ 113 bio_destructor_t *bi_destructor; /* destructor */
114 struct bio_set *bi_set; /* memory pools set */
115}; 114};
116 115
117/* 116/*
@@ -280,6 +279,7 @@ extern void bioset_free(struct bio_set *);
280extern struct bio *bio_alloc(unsigned int __nocast, int); 279extern struct bio *bio_alloc(unsigned int __nocast, int);
281extern struct bio *bio_alloc_bioset(unsigned int __nocast, int, struct bio_set *); 280extern struct bio *bio_alloc_bioset(unsigned int __nocast, int, struct bio_set *);
282extern void bio_put(struct bio *); 281extern void bio_put(struct bio *);
282extern void bio_free(struct bio *, struct bio_set *);
283 283
284extern void bio_endio(struct bio *, unsigned int, int); 284extern void bio_endio(struct bio *, unsigned int, int);
285struct request_queue; 285struct request_queue;