2 * blk-integrity.c - Block layer data integrity extensions
4 * Copyright (C) 2007, 2008 Oracle Corporation
5 * Written by: Martin K. Petersen <martin.petersen@oracle.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
23 #include <linux/blkdev.h>
24 #include <linux/backing-dev.h>
25 #include <linux/mempool.h>
26 #include <linux/bio.h>
27 #include <linux/scatterlist.h>
28 #include <linux/export.h>
29 #include <linux/slab.h>
33 static struct kmem_cache
*integrity_cachep
;
35 static const char *bi_unsupported_name
= "unsupported";
38 * blk_rq_count_integrity_sg - Count number of integrity scatterlist elements
40 * @bio: bio with integrity metadata attached
42 * Description: Returns the number of elements required in a
43 * scatterlist corresponding to the integrity metadata in a bio.
45 int blk_rq_count_integrity_sg(struct request_queue
*q
, struct bio
*bio
)
47 struct bio_vec iv
, ivprv
= { NULL
};
48 unsigned int segments
= 0;
49 unsigned int seg_size
= 0;
50 struct bvec_iter iter
;
53 bio_for_each_integrity_vec(iv
, bio
, iter
) {
56 if (!BIOVEC_PHYS_MERGEABLE(&ivprv
, &iv
))
59 if (!BIOVEC_SEG_BOUNDARY(q
, &ivprv
, &iv
))
62 if (seg_size
+ iv
.bv_len
> queue_max_segment_size(q
))
65 seg_size
+= iv
.bv_len
;
78 EXPORT_SYMBOL(blk_rq_count_integrity_sg
);
81 * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
83 * @bio: bio with integrity metadata attached
84 * @sglist: target scatterlist
86 * Description: Map the integrity vectors in request into a
87 * scatterlist. The scatterlist must be big enough to hold all
88 * elements. I.e. sized using blk_rq_count_integrity_sg().
90 int blk_rq_map_integrity_sg(struct request_queue
*q
, struct bio
*bio
,
91 struct scatterlist
*sglist
)
93 struct bio_vec iv
, ivprv
= { NULL
};
94 struct scatterlist
*sg
= NULL
;
95 unsigned int segments
= 0;
96 struct bvec_iter iter
;
99 bio_for_each_integrity_vec(iv
, bio
, iter
) {
102 if (!BIOVEC_PHYS_MERGEABLE(&ivprv
, &iv
))
105 if (!BIOVEC_SEG_BOUNDARY(q
, &ivprv
, &iv
))
108 if (sg
->length
+ iv
.bv_len
> queue_max_segment_size(q
))
111 sg
->length
+= iv
.bv_len
;
121 sg_set_page(sg
, iv
.bv_page
, iv
.bv_len
, iv
.bv_offset
);
134 EXPORT_SYMBOL(blk_rq_map_integrity_sg
);
137 * blk_integrity_compare - Compare integrity profile of two disks
138 * @gd1: Disk to compare
139 * @gd2: Disk to compare
141 * Description: Meta-devices like DM and MD need to verify that all
142 * sub-devices use the same integrity format before advertising to
143 * upper layers that they can send/receive integrity metadata. This
144 * function can be used to check whether two gendisk devices have
145 * compatible integrity formats.
147 int blk_integrity_compare(struct gendisk
*gd1
, struct gendisk
*gd2
)
149 struct blk_integrity
*b1
= gd1
->integrity
;
150 struct blk_integrity
*b2
= gd2
->integrity
;
158 if (b1
->interval
!= b2
->interval
) {
159 pr_err("%s: %s/%s protection interval %u != %u\n",
160 __func__
, gd1
->disk_name
, gd2
->disk_name
,
161 b1
->interval
, b2
->interval
);
165 if (b1
->tuple_size
!= b2
->tuple_size
) {
166 printk(KERN_ERR
"%s: %s/%s tuple sz %u != %u\n", __func__
,
167 gd1
->disk_name
, gd2
->disk_name
,
168 b1
->tuple_size
, b2
->tuple_size
);
172 if (b1
->tag_size
&& b2
->tag_size
&& (b1
->tag_size
!= b2
->tag_size
)) {
173 printk(KERN_ERR
"%s: %s/%s tag sz %u != %u\n", __func__
,
174 gd1
->disk_name
, gd2
->disk_name
,
175 b1
->tag_size
, b2
->tag_size
);
179 if (strcmp(b1
->name
, b2
->name
)) {
180 printk(KERN_ERR
"%s: %s/%s type %s != %s\n", __func__
,
181 gd1
->disk_name
, gd2
->disk_name
,
188 EXPORT_SYMBOL(blk_integrity_compare
);
190 bool blk_integrity_merge_rq(struct request_queue
*q
, struct request
*req
,
191 struct request
*next
)
193 if (blk_integrity_rq(req
) == 0 && blk_integrity_rq(next
) == 0)
196 if (blk_integrity_rq(req
) == 0 || blk_integrity_rq(next
) == 0)
199 if (bio_integrity(req
->bio
)->bip_flags
!=
200 bio_integrity(next
->bio
)->bip_flags
)
203 if (req
->nr_integrity_segments
+ next
->nr_integrity_segments
>
204 q
->limits
.max_integrity_segments
)
207 if (integrity_req_gap_back_merge(req
, next
->bio
))
212 EXPORT_SYMBOL(blk_integrity_merge_rq
);
214 bool blk_integrity_merge_bio(struct request_queue
*q
, struct request
*req
,
217 int nr_integrity_segs
;
218 struct bio
*next
= bio
->bi_next
;
220 if (blk_integrity_rq(req
) == 0 && bio_integrity(bio
) == NULL
)
223 if (blk_integrity_rq(req
) == 0 || bio_integrity(bio
) == NULL
)
226 if (bio_integrity(req
->bio
)->bip_flags
!= bio_integrity(bio
)->bip_flags
)
230 nr_integrity_segs
= blk_rq_count_integrity_sg(q
, bio
);
233 if (req
->nr_integrity_segments
+ nr_integrity_segs
>
234 q
->limits
.max_integrity_segments
)
237 req
->nr_integrity_segments
+= nr_integrity_segs
;
241 EXPORT_SYMBOL(blk_integrity_merge_bio
);
243 struct integrity_sysfs_entry
{
244 struct attribute attr
;
245 ssize_t (*show
)(struct blk_integrity
*, char *);
246 ssize_t (*store
)(struct blk_integrity
*, const char *, size_t);
249 static ssize_t
integrity_attr_show(struct kobject
*kobj
, struct attribute
*attr
,
252 struct blk_integrity
*bi
=
253 container_of(kobj
, struct blk_integrity
, kobj
);
254 struct integrity_sysfs_entry
*entry
=
255 container_of(attr
, struct integrity_sysfs_entry
, attr
);
257 return entry
->show(bi
, page
);
260 static ssize_t
integrity_attr_store(struct kobject
*kobj
,
261 struct attribute
*attr
, const char *page
,
264 struct blk_integrity
*bi
=
265 container_of(kobj
, struct blk_integrity
, kobj
);
266 struct integrity_sysfs_entry
*entry
=
267 container_of(attr
, struct integrity_sysfs_entry
, attr
);
271 ret
= entry
->store(bi
, page
, count
);
276 static ssize_t
integrity_format_show(struct blk_integrity
*bi
, char *page
)
278 if (bi
!= NULL
&& bi
->name
!= NULL
)
279 return sprintf(page
, "%s\n", bi
->name
);
281 return sprintf(page
, "none\n");
284 static ssize_t
integrity_tag_size_show(struct blk_integrity
*bi
, char *page
)
287 return sprintf(page
, "%u\n", bi
->tag_size
);
289 return sprintf(page
, "0\n");
292 static ssize_t
integrity_verify_store(struct blk_integrity
*bi
,
293 const char *page
, size_t count
)
295 char *p
= (char *) page
;
296 unsigned long val
= simple_strtoul(p
, &p
, 10);
299 bi
->flags
|= BLK_INTEGRITY_VERIFY
;
301 bi
->flags
&= ~BLK_INTEGRITY_VERIFY
;
306 static ssize_t
integrity_verify_show(struct blk_integrity
*bi
, char *page
)
308 return sprintf(page
, "%d\n", (bi
->flags
& BLK_INTEGRITY_VERIFY
) != 0);
311 static ssize_t
integrity_generate_store(struct blk_integrity
*bi
,
312 const char *page
, size_t count
)
314 char *p
= (char *) page
;
315 unsigned long val
= simple_strtoul(p
, &p
, 10);
318 bi
->flags
|= BLK_INTEGRITY_GENERATE
;
320 bi
->flags
&= ~BLK_INTEGRITY_GENERATE
;
325 static ssize_t
integrity_generate_show(struct blk_integrity
*bi
, char *page
)
327 return sprintf(page
, "%d\n", (bi
->flags
& BLK_INTEGRITY_GENERATE
) != 0);
330 static ssize_t
integrity_device_show(struct blk_integrity
*bi
, char *page
)
332 return sprintf(page
, "%u\n",
333 (bi
->flags
& BLK_INTEGRITY_DEVICE_CAPABLE
) != 0);
336 static struct integrity_sysfs_entry integrity_format_entry
= {
337 .attr
= { .name
= "format", .mode
= S_IRUGO
},
338 .show
= integrity_format_show
,
341 static struct integrity_sysfs_entry integrity_tag_size_entry
= {
342 .attr
= { .name
= "tag_size", .mode
= S_IRUGO
},
343 .show
= integrity_tag_size_show
,
346 static struct integrity_sysfs_entry integrity_verify_entry
= {
347 .attr
= { .name
= "read_verify", .mode
= S_IRUGO
| S_IWUSR
},
348 .show
= integrity_verify_show
,
349 .store
= integrity_verify_store
,
352 static struct integrity_sysfs_entry integrity_generate_entry
= {
353 .attr
= { .name
= "write_generate", .mode
= S_IRUGO
| S_IWUSR
},
354 .show
= integrity_generate_show
,
355 .store
= integrity_generate_store
,
358 static struct integrity_sysfs_entry integrity_device_entry
= {
359 .attr
= { .name
= "device_is_integrity_capable", .mode
= S_IRUGO
},
360 .show
= integrity_device_show
,
363 static struct attribute
*integrity_attrs
[] = {
364 &integrity_format_entry
.attr
,
365 &integrity_tag_size_entry
.attr
,
366 &integrity_verify_entry
.attr
,
367 &integrity_generate_entry
.attr
,
368 &integrity_device_entry
.attr
,
372 static const struct sysfs_ops integrity_ops
= {
373 .show
= &integrity_attr_show
,
374 .store
= &integrity_attr_store
,
377 static int __init
blk_dev_integrity_init(void)
379 integrity_cachep
= kmem_cache_create("blkdev_integrity",
380 sizeof(struct blk_integrity
),
381 0, SLAB_PANIC
, NULL
);
384 subsys_initcall(blk_dev_integrity_init
);
386 static void blk_integrity_release(struct kobject
*kobj
)
388 struct blk_integrity
*bi
=
389 container_of(kobj
, struct blk_integrity
, kobj
);
391 kmem_cache_free(integrity_cachep
, bi
);
394 static struct kobj_type integrity_ktype
= {
395 .default_attrs
= integrity_attrs
,
396 .sysfs_ops
= &integrity_ops
,
397 .release
= blk_integrity_release
,
400 bool blk_integrity_is_initialized(struct gendisk
*disk
)
402 struct blk_integrity
*bi
= blk_get_integrity(disk
);
404 return (bi
&& bi
->name
&& strcmp(bi
->name
, bi_unsupported_name
) != 0);
406 EXPORT_SYMBOL(blk_integrity_is_initialized
);
409 * blk_integrity_register - Register a gendisk as being integrity-capable
410 * @disk: struct gendisk pointer to make integrity-aware
411 * @template: optional integrity profile to register
413 * Description: When a device needs to advertise itself as being able
414 * to send/receive integrity metadata it must use this function to
415 * register the capability with the block layer. The template is a
416 * blk_integrity struct with values appropriate for the underlying
417 * hardware. If template is NULL the new profile is allocated but
418 * not filled out. See Documentation/block/data-integrity.txt.
420 int blk_integrity_register(struct gendisk
*disk
, struct blk_integrity
*template)
422 struct blk_integrity
*bi
;
424 BUG_ON(disk
== NULL
);
426 if (disk
->integrity
== NULL
) {
427 bi
= kmem_cache_alloc(integrity_cachep
,
428 GFP_KERNEL
| __GFP_ZERO
);
432 if (kobject_init_and_add(&bi
->kobj
, &integrity_ktype
,
433 &disk_to_dev(disk
)->kobj
,
434 "%s", "integrity")) {
435 kmem_cache_free(integrity_cachep
, bi
);
439 kobject_uevent(&bi
->kobj
, KOBJ_ADD
);
441 bi
->flags
|= BLK_INTEGRITY_VERIFY
| BLK_INTEGRITY_GENERATE
;
442 bi
->interval
= queue_logical_block_size(disk
->queue
);
443 disk
->integrity
= bi
;
445 bi
= disk
->integrity
;
447 /* Use the provided profile as template */
448 if (template != NULL
) {
449 bi
->name
= template->name
;
450 bi
->generate_fn
= template->generate_fn
;
451 bi
->verify_fn
= template->verify_fn
;
452 bi
->tuple_size
= template->tuple_size
;
453 bi
->tag_size
= template->tag_size
;
454 bi
->flags
|= template->flags
;
456 bi
->name
= bi_unsupported_name
;
458 disk
->queue
->backing_dev_info
.capabilities
|= BDI_CAP_STABLE_WRITES
;
462 EXPORT_SYMBOL(blk_integrity_register
);
465 * blk_integrity_unregister - Remove block integrity profile
466 * @disk: disk whose integrity profile to deallocate
468 * Description: This function frees all memory used by the block
469 * integrity profile. To be called at device teardown.
471 void blk_integrity_unregister(struct gendisk
*disk
)
473 struct blk_integrity
*bi
;
475 if (!disk
|| !disk
->integrity
)
478 disk
->queue
->backing_dev_info
.capabilities
&= ~BDI_CAP_STABLE_WRITES
;
480 bi
= disk
->integrity
;
482 kobject_uevent(&bi
->kobj
, KOBJ_REMOVE
);
483 kobject_del(&bi
->kobj
);
484 kobject_put(&bi
->kobj
);
485 disk
->integrity
= NULL
;
487 EXPORT_SYMBOL(blk_integrity_unregister
);