diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2008-06-30 14:04:41 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-07-03 07:21:13 -0400 |
commit | 7ba1ba12eeef0aa7113beb16410ef8b7c748e18b (patch) | |
tree | 4629aabe88bf095d58eabd2f451207695bb35b08 /fs/bio.c | |
parent | 51d654e1d885607a6edd02b337105fa5c28b6d33 (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.c | 32 |
1 files changed, 29 insertions, 3 deletions
@@ -50,6 +50,11 @@ static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { | |||
50 | */ | 50 | */ |
51 | struct bio_set *fs_bio_set; | 51 | struct bio_set *fs_bio_set; |
52 | 52 | ||
53 | unsigned int bvec_nr_vecs(unsigned short idx) | ||
54 | { | ||
55 | return bvec_slabs[idx].nr_vecs; | ||
56 | } | ||
57 | |||
53 | struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) | 58 | struct 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); |