aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bio.c
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2008-06-30 14:04:41 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-07-03 07:21:13 -0400
commit7ba1ba12eeef0aa7113beb16410ef8b7c748e18b (patch)
tree4629aabe88bf095d58eabd2f451207695bb35b08 /fs/bio.c
parent51d654e1d885607a6edd02b337105fa5c28b6d33 (diff)
block: Block layer data integrity support
Some block devices support verifying the integrity of requests by way of checksums or other protection information that is submitted along with the I/O. This patch implements support for generating and verifying integrity metadata, as well as correctly merging, splitting and cloning bios and requests that have this extra information attached. See Documentation/block/data-integrity.txt for more information. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/fs/bio.c b/fs/bio.c
index 7a6598abc967..7761c84c7032 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -50,6 +50,11 @@ static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
50 */ 50 */
51struct bio_set *fs_bio_set; 51struct bio_set *fs_bio_set;
52 52
53unsigned int bvec_nr_vecs(unsigned short idx)
54{
55 return bvec_slabs[idx].nr_vecs;
56}
57
53struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) 58struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
54{ 59{
55 struct bio_vec *bvl; 60 struct bio_vec *bvl;
@@ -91,6 +96,9 @@ void bio_free(struct bio *bio, struct bio_set *bio_set)
91 mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); 96 mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]);
92 } 97 }
93 98
99 if (bio_integrity(bio))
100 bio_integrity_free(bio, bio_set);
101
94 mempool_free(bio, bio_set->bio_pool); 102 mempool_free(bio, bio_set->bio_pool);
95} 103}
96 104
@@ -249,9 +257,19 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
249{ 257{
250 struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set); 258 struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set);
251 259
252 if (b) { 260 if (!b)
253 b->bi_destructor = bio_fs_destructor; 261 return NULL;
254 __bio_clone(b, bio); 262
263 b->bi_destructor = bio_fs_destructor;
264 __bio_clone(b, bio);
265
266 if (bio_integrity(bio)) {
267 int ret;
268
269 ret = bio_integrity_clone(b, bio, fs_bio_set);
270
271 if (ret < 0)
272 return NULL;
255 } 273 }
256 274
257 return b; 275 return b;
@@ -1223,6 +1241,9 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
1223 bp->bio1.bi_private = bi; 1241 bp->bio1.bi_private = bi;
1224 bp->bio2.bi_private = pool; 1242 bp->bio2.bi_private = pool;
1225 1243
1244 if (bio_integrity(bi))
1245 bio_integrity_split(bi, bp, first_sectors);
1246
1226 return bp; 1247 return bp;
1227} 1248}
1228 1249
@@ -1264,6 +1285,7 @@ void bioset_free(struct bio_set *bs)
1264 if (bs->bio_pool) 1285 if (bs->bio_pool)
1265 mempool_destroy(bs->bio_pool); 1286 mempool_destroy(bs->bio_pool);
1266 1287
1288 bioset_integrity_free(bs);
1267 biovec_free_pools(bs); 1289 biovec_free_pools(bs);
1268 1290
1269 kfree(bs); 1291 kfree(bs);
@@ -1280,6 +1302,9 @@ struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size)
1280 if (!bs->bio_pool) 1302 if (!bs->bio_pool)
1281 goto bad; 1303 goto bad;
1282 1304
1305 if (bioset_integrity_create(bs, bio_pool_size))
1306 goto bad;
1307
1283 if (!biovec_create_pools(bs, bvec_pool_size)) 1308 if (!biovec_create_pools(bs, bvec_pool_size))
1284 return bs; 1309 return bs;
1285 1310
@@ -1306,6 +1331,7 @@ static int __init init_bio(void)
1306{ 1331{
1307 bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC); 1332 bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
1308 1333
1334 bio_integrity_init_slab();
1309 biovec_init_slabs(); 1335 biovec_init_slabs();
1310 1336
1311 fs_bio_set = bioset_create(BIO_POOL_SIZE, 2); 1337 fs_bio_set = bioset_create(BIO_POOL_SIZE, 2);