Lines Matching +full:use +full:- +full:advanced +full:- +full:sector +full:- +full:protection
1 // SPDX-License-Identifier: GPL-2.0
3 * t10_pi.c - Functions for generating and verifying T10 Protection
7 #include <linux/t10-pi.h>
8 #include <linux/blk-integrity.h>
9 #include <linux/crc-t10dif.h>
33 * Type 1 and Type 2 protection use the same format: 16 bit guard tag,
40 u8 offset = bi->pi_offset; in t10_pi_generate()
43 for (i = 0 ; i < iter->data_size ; i += iter->interval) { in t10_pi_generate()
44 struct t10_pi_tuple *pi = iter->prot_buf + offset; in t10_pi_generate()
46 pi->guard_tag = t10_pi_csum(0, iter->data_buf, iter->interval, in t10_pi_generate()
47 bi->csum_type); in t10_pi_generate()
49 pi->guard_tag = t10_pi_csum(pi->guard_tag, in t10_pi_generate()
50 iter->prot_buf, offset, bi->csum_type); in t10_pi_generate()
51 pi->app_tag = 0; in t10_pi_generate()
53 if (bi->flags & BLK_INTEGRITY_REF_TAG) in t10_pi_generate()
54 pi->ref_tag = cpu_to_be32(lower_32_bits(iter->seed)); in t10_pi_generate()
56 pi->ref_tag = 0; in t10_pi_generate()
58 iter->data_buf += iter->interval; in t10_pi_generate()
59 iter->prot_buf += bi->tuple_size; in t10_pi_generate()
60 iter->seed++; in t10_pi_generate()
67 u8 offset = bi->pi_offset; in t10_pi_verify()
70 for (i = 0 ; i < iter->data_size ; i += iter->interval) { in t10_pi_verify()
71 struct t10_pi_tuple *pi = iter->prot_buf + offset; in t10_pi_verify()
74 if (bi->flags & BLK_INTEGRITY_REF_TAG) { in t10_pi_verify()
75 if (pi->app_tag == T10_PI_APP_ESCAPE) in t10_pi_verify()
78 if (be32_to_cpu(pi->ref_tag) != in t10_pi_verify()
79 lower_32_bits(iter->seed)) { in t10_pi_verify()
81 "(rcvd %u)\n", iter->disk_name, in t10_pi_verify()
83 iter->seed, be32_to_cpu(pi->ref_tag)); in t10_pi_verify()
87 if (pi->app_tag == T10_PI_APP_ESCAPE && in t10_pi_verify()
88 pi->ref_tag == T10_PI_REF_ESCAPE) in t10_pi_verify()
92 csum = t10_pi_csum(0, iter->data_buf, iter->interval, in t10_pi_verify()
93 bi->csum_type); in t10_pi_verify()
95 csum = t10_pi_csum(csum, iter->prot_buf, offset, in t10_pi_verify()
96 bi->csum_type); in t10_pi_verify()
98 if (pi->guard_tag != csum) { in t10_pi_verify()
99 pr_err("%s: guard tag error at sector %llu " \ in t10_pi_verify()
100 "(rcvd %04x, want %04x)\n", iter->disk_name, in t10_pi_verify()
101 (unsigned long long)iter->seed, in t10_pi_verify()
102 be16_to_cpu(pi->guard_tag), be16_to_cpu(csum)); in t10_pi_verify()
107 iter->data_buf += iter->interval; in t10_pi_verify()
108 iter->prot_buf += bi->tuple_size; in t10_pi_verify()
109 iter->seed++; in t10_pi_verify()
116 * t10_pi_type1_prepare - prepare PI prior submitting request to device
119 * For Type 1/Type 2, the virtual start sector is the one that was
121 * partitioning, MD/DM cloning, etc. the actual physical start sector is
122 * likely to be different. Remap protection information to match the
127 struct blk_integrity *bi = &rq->q->limits.integrity; in t10_pi_type1_prepare()
128 const int tuple_sz = bi->tuple_size; in t10_pi_type1_prepare()
130 u8 offset = bi->pi_offset; in t10_pi_type1_prepare()
140 if (bip->bip_flags & BIP_MAPPED_INTEGRITY) in t10_pi_type1_prepare()
151 if (be32_to_cpu(pi->ref_tag) == virt) in t10_pi_type1_prepare()
152 pi->ref_tag = cpu_to_be32(ref_tag); in t10_pi_type1_prepare()
160 bip->bip_flags |= BIP_MAPPED_INTEGRITY; in t10_pi_type1_prepare()
165 * t10_pi_type1_complete - prepare PI prior returning request to the blk layer
169 * For Type 1/Type 2, the virtual start sector is the one that was
171 * partitioning, MD/DM cloning, etc. the actual physical start sector is
172 * likely to be different. Since the physical start sector was submitted
178 struct blk_integrity *bi = &rq->q->limits.integrity; in t10_pi_type1_complete()
179 unsigned intervals = nr_bytes >> bi->interval_exp; in t10_pi_type1_complete()
180 const int tuple_sz = bi->tuple_size; in t10_pi_type1_complete()
182 u8 offset = bi->pi_offset; in t10_pi_type1_complete()
199 if (be32_to_cpu(pi->ref_tag) == ref_tag) in t10_pi_type1_complete()
200 pi->ref_tag = cpu_to_be32(virt); in t10_pi_type1_complete()
203 intervals--; in t10_pi_type1_complete()
219 u8 offset = bi->pi_offset; in ext_pi_crc64_generate()
222 for (i = 0 ; i < iter->data_size ; i += iter->interval) { in ext_pi_crc64_generate()
223 struct crc64_pi_tuple *pi = iter->prot_buf + offset; in ext_pi_crc64_generate()
225 pi->guard_tag = ext_pi_crc64(0, iter->data_buf, iter->interval); in ext_pi_crc64_generate()
227 pi->guard_tag = ext_pi_crc64(be64_to_cpu(pi->guard_tag), in ext_pi_crc64_generate()
228 iter->prot_buf, offset); in ext_pi_crc64_generate()
229 pi->app_tag = 0; in ext_pi_crc64_generate()
231 if (bi->flags & BLK_INTEGRITY_REF_TAG) in ext_pi_crc64_generate()
232 put_unaligned_be48(iter->seed, pi->ref_tag); in ext_pi_crc64_generate()
234 put_unaligned_be48(0ULL, pi->ref_tag); in ext_pi_crc64_generate()
236 iter->data_buf += iter->interval; in ext_pi_crc64_generate()
237 iter->prot_buf += bi->tuple_size; in ext_pi_crc64_generate()
238 iter->seed++; in ext_pi_crc64_generate()
252 u8 offset = bi->pi_offset; in ext_pi_crc64_verify()
255 for (i = 0; i < iter->data_size; i += iter->interval) { in ext_pi_crc64_verify()
256 struct crc64_pi_tuple *pi = iter->prot_buf + offset; in ext_pi_crc64_verify()
260 if (bi->flags & BLK_INTEGRITY_REF_TAG) { in ext_pi_crc64_verify()
261 if (pi->app_tag == T10_PI_APP_ESCAPE) in ext_pi_crc64_verify()
264 ref = get_unaligned_be48(pi->ref_tag); in ext_pi_crc64_verify()
265 seed = lower_48_bits(iter->seed); in ext_pi_crc64_verify()
268 iter->disk_name, seed, ref); in ext_pi_crc64_verify()
272 if (pi->app_tag == T10_PI_APP_ESCAPE && in ext_pi_crc64_verify()
273 ext_pi_ref_escape(pi->ref_tag)) in ext_pi_crc64_verify()
277 csum = ext_pi_crc64(0, iter->data_buf, iter->interval); in ext_pi_crc64_verify()
279 csum = ext_pi_crc64(be64_to_cpu(csum), iter->prot_buf, in ext_pi_crc64_verify()
282 if (pi->guard_tag != csum) { in ext_pi_crc64_verify()
283 pr_err("%s: guard tag error at sector %llu " \ in ext_pi_crc64_verify()
285 iter->disk_name, (unsigned long long)iter->seed, in ext_pi_crc64_verify()
286 be64_to_cpu(pi->guard_tag), be64_to_cpu(csum)); in ext_pi_crc64_verify()
291 iter->data_buf += iter->interval; in ext_pi_crc64_verify()
292 iter->prot_buf += bi->tuple_size; in ext_pi_crc64_verify()
293 iter->seed++; in ext_pi_crc64_verify()
301 struct blk_integrity *bi = &rq->q->limits.integrity; in ext_pi_type1_prepare()
302 const int tuple_sz = bi->tuple_size; in ext_pi_type1_prepare()
304 u8 offset = bi->pi_offset; in ext_pi_type1_prepare()
314 if (bip->bip_flags & BIP_MAPPED_INTEGRITY) in ext_pi_type1_prepare()
324 u64 ref = get_unaligned_be48(pi->ref_tag); in ext_pi_type1_prepare()
327 put_unaligned_be48(ref_tag, pi->ref_tag); in ext_pi_type1_prepare()
335 bip->bip_flags |= BIP_MAPPED_INTEGRITY; in ext_pi_type1_prepare()
341 struct blk_integrity *bi = &rq->q->limits.integrity; in ext_pi_type1_complete()
342 unsigned intervals = nr_bytes >> bi->interval_exp; in ext_pi_type1_complete()
343 const int tuple_sz = bi->tuple_size; in ext_pi_type1_complete()
345 u8 offset = bi->pi_offset; in ext_pi_type1_complete()
361 u64 ref = get_unaligned_be48(pi->ref_tag); in ext_pi_type1_complete()
364 put_unaligned_be48(virt, pi->ref_tag); in ext_pi_type1_complete()
367 intervals--; in ext_pi_type1_complete()
377 struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); in blk_integrity_generate()
383 iter.disk_name = bio->bi_bdev->bd_disk->disk_name; in blk_integrity_generate()
384 iter.interval = 1 << bi->interval_exp; in blk_integrity_generate()
385 iter.seed = bio->bi_iter.bi_sector; in blk_integrity_generate()
386 iter.prot_buf = bvec_virt(bip->bip_vec); in blk_integrity_generate()
392 switch (bi->csum_type) { in blk_integrity_generate()
409 struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); in blk_integrity_verify()
416 * At the moment verify is called bi_iter has been advanced during split in blk_integrity_verify()
417 * and completion, so use the copy created during submission here. in blk_integrity_verify()
419 iter.disk_name = bio->bi_bdev->bd_disk->disk_name; in blk_integrity_verify()
420 iter.interval = 1 << bi->interval_exp; in blk_integrity_verify()
421 iter.seed = bip->bio_iter.bi_sector; in blk_integrity_verify()
422 iter.prot_buf = bvec_virt(bip->bip_vec); in blk_integrity_verify()
423 __bio_for_each_segment(bv, bio, bviter, bip->bio_iter) { in blk_integrity_verify()
429 switch (bi->csum_type) { in blk_integrity_verify()
443 bio->bi_status = ret; in blk_integrity_verify()
451 struct blk_integrity *bi = &rq->q->limits.integrity; in blk_integrity_prepare()
453 if (!(bi->flags & BLK_INTEGRITY_REF_TAG)) in blk_integrity_prepare()
456 if (bi->csum_type == BLK_INTEGRITY_CSUM_CRC64) in blk_integrity_prepare()
464 struct blk_integrity *bi = &rq->q->limits.integrity; in blk_integrity_complete()
466 if (!(bi->flags & BLK_INTEGRITY_REF_TAG)) in blk_integrity_complete()
469 if (bi->csum_type == BLK_INTEGRITY_CSUM_CRC64) in blk_integrity_complete()