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
)
209 EXPORT_SYMBOL(blk_integrity_merge_rq
);
211 bool blk_integrity_merge_bio(struct request_queue
*q
, struct request
*req
,
214 int nr_integrity_segs
;
215 struct bio
*next
= bio
->bi_next
;
217 if (blk_integrity_rq(req
) == 0 && bio_integrity(bio
) == NULL
)
220 if (blk_integrity_rq(req
) == 0 || bio_integrity(bio
) == NULL
)
223 if (bio_integrity(req
->bio
)->bip_flags
!= bio_integrity(bio
)->bip_flags
)
227 nr_integrity_segs
= blk_rq_count_integrity_sg(q
, bio
);
230 if (req
->nr_integrity_segments
+ nr_integrity_segs
>
231 q
->limits
.max_integrity_segments
)
234 req
->nr_integrity_segments
+= nr_integrity_segs
;
238 EXPORT_SYMBOL(blk_integrity_merge_bio
);
240 struct integrity_sysfs_entry
{
241 struct attribute attr
;
242 ssize_t (*show
)(struct blk_integrity
*, char *);
243 ssize_t (*store
)(struct blk_integrity
*, const char *, size_t);
246 static ssize_t
integrity_attr_show(struct kobject
*kobj
, struct attribute
*attr
,
249 struct blk_integrity
*bi
=
250 container_of(kobj
, struct blk_integrity
, kobj
);
251 struct integrity_sysfs_entry
*entry
=
252 container_of(attr
, struct integrity_sysfs_entry
, attr
);
254 return entry
->show(bi
, page
);
257 static ssize_t
integrity_attr_store(struct kobject
*kobj
,
258 struct attribute
*attr
, const char *page
,
261 struct blk_integrity
*bi
=
262 container_of(kobj
, struct blk_integrity
, kobj
);
263 struct integrity_sysfs_entry
*entry
=
264 container_of(attr
, struct integrity_sysfs_entry
, attr
);
268 ret
= entry
->store(bi
, page
, count
);
273 static ssize_t
integrity_format_show(struct blk_integrity
*bi
, char *page
)
275 if (bi
!= NULL
&& bi
->name
!= NULL
)
276 return sprintf(page
, "%s\n", bi
->name
);
278 return sprintf(page
, "none\n");
281 static ssize_t
integrity_tag_size_show(struct blk_integrity
*bi
, char *page
)
284 return sprintf(page
, "%u\n", bi
->tag_size
);
286 return sprintf(page
, "0\n");
289 static ssize_t
integrity_verify_store(struct blk_integrity
*bi
,
290 const char *page
, size_t count
)
292 char *p
= (char *) page
;
293 unsigned long val
= simple_strtoul(p
, &p
, 10);
296 bi
->flags
|= BLK_INTEGRITY_VERIFY
;
298 bi
->flags
&= ~BLK_INTEGRITY_VERIFY
;
303 static ssize_t
integrity_verify_show(struct blk_integrity
*bi
, char *page
)
305 return sprintf(page
, "%d\n", (bi
->flags
& BLK_INTEGRITY_VERIFY
) != 0);
308 static ssize_t
integrity_generate_store(struct blk_integrity
*bi
,
309 const char *page
, size_t count
)
311 char *p
= (char *) page
;
312 unsigned long val
= simple_strtoul(p
, &p
, 10);
315 bi
->flags
|= BLK_INTEGRITY_GENERATE
;
317 bi
->flags
&= ~BLK_INTEGRITY_GENERATE
;
322 static ssize_t
integrity_generate_show(struct blk_integrity
*bi
, char *page
)
324 return sprintf(page
, "%d\n", (bi
->flags
& BLK_INTEGRITY_GENERATE
) != 0);
327 static ssize_t
integrity_device_show(struct blk_integrity
*bi
, char *page
)
329 return sprintf(page
, "%u\n",
330 (bi
->flags
& BLK_INTEGRITY_DEVICE_CAPABLE
) != 0);
333 static struct integrity_sysfs_entry integrity_format_entry
= {
334 .attr
= { .name
= "format", .mode
= S_IRUGO
},
335 .show
= integrity_format_show
,
338 static struct integrity_sysfs_entry integrity_tag_size_entry
= {
339 .attr
= { .name
= "tag_size", .mode
= S_IRUGO
},
340 .show
= integrity_tag_size_show
,
343 static struct integrity_sysfs_entry integrity_verify_entry
= {
344 .attr
= { .name
= "read_verify", .mode
= S_IRUGO
| S_IWUSR
},
345 .show
= integrity_verify_show
,
346 .store
= integrity_verify_store
,
349 static struct integrity_sysfs_entry integrity_generate_entry
= {
350 .attr
= { .name
= "write_generate", .mode
= S_IRUGO
| S_IWUSR
},
351 .show
= integrity_generate_show
,
352 .store
= integrity_generate_store
,
355 static struct integrity_sysfs_entry integrity_device_entry
= {
356 .attr
= { .name
= "device_is_integrity_capable", .mode
= S_IRUGO
},
357 .show
= integrity_device_show
,
360 static struct attribute
*integrity_attrs
[] = {
361 &integrity_format_entry
.attr
,
362 &integrity_tag_size_entry
.attr
,
363 &integrity_verify_entry
.attr
,
364 &integrity_generate_entry
.attr
,
365 &integrity_device_entry
.attr
,
369 static const struct sysfs_ops integrity_ops
= {
370 .show
= &integrity_attr_show
,
371 .store
= &integrity_attr_store
,
374 static int __init
blk_dev_integrity_init(void)
376 integrity_cachep
= kmem_cache_create("blkdev_integrity",
377 sizeof(struct blk_integrity
),
378 0, SLAB_PANIC
, NULL
);
381 subsys_initcall(blk_dev_integrity_init
);
383 static void blk_integrity_release(struct kobject
*kobj
)
385 struct blk_integrity
*bi
=
386 container_of(kobj
, struct blk_integrity
, kobj
);
388 kmem_cache_free(integrity_cachep
, bi
);
391 static struct kobj_type integrity_ktype
= {
392 .default_attrs
= integrity_attrs
,
393 .sysfs_ops
= &integrity_ops
,
394 .release
= blk_integrity_release
,
397 bool blk_integrity_is_initialized(struct gendisk
*disk
)
399 struct blk_integrity
*bi
= blk_get_integrity(disk
);
401 return (bi
&& bi
->name
&& strcmp(bi
->name
, bi_unsupported_name
) != 0);
403 EXPORT_SYMBOL(blk_integrity_is_initialized
);
406 * blk_integrity_register - Register a gendisk as being integrity-capable
407 * @disk: struct gendisk pointer to make integrity-aware
408 * @template: optional integrity profile to register
410 * Description: When a device needs to advertise itself as being able
411 * to send/receive integrity metadata it must use this function to
412 * register the capability with the block layer. The template is a
413 * blk_integrity struct with values appropriate for the underlying
414 * hardware. If template is NULL the new profile is allocated but
415 * not filled out. See Documentation/block/data-integrity.txt.
417 int blk_integrity_register(struct gendisk
*disk
, struct blk_integrity
*template)
419 struct blk_integrity
*bi
;
421 BUG_ON(disk
== NULL
);
423 if (disk
->integrity
== NULL
) {
424 bi
= kmem_cache_alloc(integrity_cachep
,
425 GFP_KERNEL
| __GFP_ZERO
);
429 if (kobject_init_and_add(&bi
->kobj
, &integrity_ktype
,
430 &disk_to_dev(disk
)->kobj
,
431 "%s", "integrity")) {
432 kmem_cache_free(integrity_cachep
, bi
);
436 kobject_uevent(&bi
->kobj
, KOBJ_ADD
);
438 bi
->flags
|= BLK_INTEGRITY_VERIFY
| BLK_INTEGRITY_GENERATE
;
439 bi
->interval
= queue_logical_block_size(disk
->queue
);
440 disk
->integrity
= bi
;
442 bi
= disk
->integrity
;
444 /* Use the provided profile as template */
445 if (template != NULL
) {
446 bi
->name
= template->name
;
447 bi
->generate_fn
= template->generate_fn
;
448 bi
->verify_fn
= template->verify_fn
;
449 bi
->tuple_size
= template->tuple_size
;
450 bi
->tag_size
= template->tag_size
;
451 bi
->flags
|= template->flags
;
453 bi
->name
= bi_unsupported_name
;
455 disk
->queue
->backing_dev_info
.capabilities
|= BDI_CAP_STABLE_WRITES
;
459 EXPORT_SYMBOL(blk_integrity_register
);
462 * blk_integrity_unregister - Remove block integrity profile
463 * @disk: disk whose integrity profile to deallocate
465 * Description: This function frees all memory used by the block
466 * integrity profile. To be called at device teardown.
468 void blk_integrity_unregister(struct gendisk
*disk
)
470 struct blk_integrity
*bi
;
472 if (!disk
|| !disk
->integrity
)
475 disk
->queue
->backing_dev_info
.capabilities
&= ~BDI_CAP_STABLE_WRITES
;
477 bi
= disk
->integrity
;
479 kobject_uevent(&bi
->kobj
, KOBJ_REMOVE
);
480 kobject_del(&bi
->kobj
);
481 kobject_put(&bi
->kobj
);
482 disk
->integrity
= NULL
;
484 EXPORT_SYMBOL(blk_integrity_unregister
);