diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2014-09-26 19:20:01 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-09-27 11:14:51 -0400 |
commit | 1859308853b19c4daf4afaab910d3d52ac1ec2ff (patch) | |
tree | 3b5a3ffcb96d88320cb609883f436b33b094ac58 /drivers/scsi | |
parent | 5a2aa873059fec8b6385071d9c0802893a9b2f41 (diff) |
block: Clean up the code used to generate and verify integrity metadata
Instead of the "operate" parameter we pass in a seed value and a pointer
to a function that can be used to process the integrity metadata. The
generation function is changed to have a return value to fit into this
scheme.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sd_dif.c | 106 |
1 files changed, 56 insertions, 50 deletions
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c index 1600270a46e5..801c41851a01 100644 --- a/drivers/scsi/sd_dif.c +++ b/drivers/scsi/sd_dif.c | |||
@@ -53,42 +53,44 @@ static __u16 sd_dif_ip_fn(void *data, unsigned int len) | |||
53 | * Type 1 and Type 2 protection use the same format: 16 bit guard tag, | 53 | * Type 1 and Type 2 protection use the same format: 16 bit guard tag, |
54 | * 16 bit app tag, 32 bit reference tag. | 54 | * 16 bit app tag, 32 bit reference tag. |
55 | */ | 55 | */ |
56 | static void sd_dif_type1_generate(struct blk_integrity_exchg *bix, csum_fn *fn) | 56 | static void sd_dif_type1_generate(struct blk_integrity_iter *iter, csum_fn *fn) |
57 | { | 57 | { |
58 | void *buf = bix->data_buf; | 58 | void *buf = iter->data_buf; |
59 | struct sd_dif_tuple *sdt = bix->prot_buf; | 59 | struct sd_dif_tuple *sdt = iter->prot_buf; |
60 | sector_t seed = bix->seed; | 60 | sector_t seed = iter->seed; |
61 | unsigned int i; | 61 | unsigned int i; |
62 | 62 | ||
63 | for (i = 0 ; i < bix->data_size ; i += bix->interval, sdt++) { | 63 | for (i = 0 ; i < iter->data_size ; i += iter->interval, sdt++) { |
64 | sdt->guard_tag = fn(buf, bix->interval); | 64 | sdt->guard_tag = fn(buf, iter->interval); |
65 | sdt->ref_tag = cpu_to_be32(seed & 0xffffffff); | 65 | sdt->ref_tag = cpu_to_be32(seed & 0xffffffff); |
66 | sdt->app_tag = 0; | 66 | sdt->app_tag = 0; |
67 | 67 | ||
68 | buf += bix->interval; | 68 | buf += iter->interval; |
69 | seed++; | 69 | seed++; |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | static void sd_dif_type1_generate_crc(struct blk_integrity_exchg *bix) | 73 | static int sd_dif_type1_generate_crc(struct blk_integrity_iter *iter) |
74 | { | 74 | { |
75 | sd_dif_type1_generate(bix, sd_dif_crc_fn); | 75 | sd_dif_type1_generate(iter, sd_dif_crc_fn); |
76 | return 0; | ||
76 | } | 77 | } |
77 | 78 | ||
78 | static void sd_dif_type1_generate_ip(struct blk_integrity_exchg *bix) | 79 | static int sd_dif_type1_generate_ip(struct blk_integrity_iter *iter) |
79 | { | 80 | { |
80 | sd_dif_type1_generate(bix, sd_dif_ip_fn); | 81 | sd_dif_type1_generate(iter, sd_dif_ip_fn); |
82 | return 0; | ||
81 | } | 83 | } |
82 | 84 | ||
83 | static int sd_dif_type1_verify(struct blk_integrity_exchg *bix, csum_fn *fn) | 85 | static int sd_dif_type1_verify(struct blk_integrity_iter *iter, csum_fn *fn) |
84 | { | 86 | { |
85 | void *buf = bix->data_buf; | 87 | void *buf = iter->data_buf; |
86 | struct sd_dif_tuple *sdt = bix->prot_buf; | 88 | struct sd_dif_tuple *sdt = iter->prot_buf; |
87 | sector_t seed = bix->seed; | 89 | sector_t seed = iter->seed; |
88 | unsigned int i; | 90 | unsigned int i; |
89 | __u16 csum; | 91 | __u16 csum; |
90 | 92 | ||
91 | for (i = 0 ; i < bix->data_size ; i += bix->interval, sdt++) { | 93 | for (i = 0 ; i < iter->data_size ; i += iter->interval, sdt++) { |
92 | /* Unwritten sectors */ | 94 | /* Unwritten sectors */ |
93 | if (sdt->app_tag == 0xffff) | 95 | if (sdt->app_tag == 0xffff) |
94 | return 0; | 96 | return 0; |
@@ -96,36 +98,36 @@ static int sd_dif_type1_verify(struct blk_integrity_exchg *bix, csum_fn *fn) | |||
96 | if (be32_to_cpu(sdt->ref_tag) != (seed & 0xffffffff)) { | 98 | if (be32_to_cpu(sdt->ref_tag) != (seed & 0xffffffff)) { |
97 | printk(KERN_ERR | 99 | printk(KERN_ERR |
98 | "%s: ref tag error on sector %lu (rcvd %u)\n", | 100 | "%s: ref tag error on sector %lu (rcvd %u)\n", |
99 | bix->disk_name, (unsigned long)seed, | 101 | iter->disk_name, (unsigned long)seed, |
100 | be32_to_cpu(sdt->ref_tag)); | 102 | be32_to_cpu(sdt->ref_tag)); |
101 | return -EIO; | 103 | return -EIO; |
102 | } | 104 | } |
103 | 105 | ||
104 | csum = fn(buf, bix->interval); | 106 | csum = fn(buf, iter->interval); |
105 | 107 | ||
106 | if (sdt->guard_tag != csum) { | 108 | if (sdt->guard_tag != csum) { |
107 | printk(KERN_ERR "%s: guard tag error on sector %lu " \ | 109 | printk(KERN_ERR "%s: guard tag error on sector %lu " \ |
108 | "(rcvd %04x, data %04x)\n", bix->disk_name, | 110 | "(rcvd %04x, data %04x)\n", iter->disk_name, |
109 | (unsigned long)seed, | 111 | (unsigned long)seed, |
110 | be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); | 112 | be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); |
111 | return -EIO; | 113 | return -EIO; |
112 | } | 114 | } |
113 | 115 | ||
114 | buf += bix->interval; | 116 | buf += iter->interval; |
115 | seed++; | 117 | seed++; |
116 | } | 118 | } |
117 | 119 | ||
118 | return 0; | 120 | return 0; |
119 | } | 121 | } |
120 | 122 | ||
121 | static int sd_dif_type1_verify_crc(struct blk_integrity_exchg *bix) | 123 | static int sd_dif_type1_verify_crc(struct blk_integrity_iter *iter) |
122 | { | 124 | { |
123 | return sd_dif_type1_verify(bix, sd_dif_crc_fn); | 125 | return sd_dif_type1_verify(iter, sd_dif_crc_fn); |
124 | } | 126 | } |
125 | 127 | ||
126 | static int sd_dif_type1_verify_ip(struct blk_integrity_exchg *bix) | 128 | static int sd_dif_type1_verify_ip(struct blk_integrity_iter *iter) |
127 | { | 129 | { |
128 | return sd_dif_type1_verify(bix, sd_dif_ip_fn); | 130 | return sd_dif_type1_verify(iter, sd_dif_ip_fn); |
129 | } | 131 | } |
130 | 132 | ||
131 | static struct blk_integrity dif_type1_integrity_crc = { | 133 | static struct blk_integrity dif_type1_integrity_crc = { |
@@ -149,69 +151,71 @@ static struct blk_integrity dif_type1_integrity_ip = { | |||
149 | * Type 3 protection has a 16-bit guard tag and 16 + 32 bits of opaque | 151 | * Type 3 protection has a 16-bit guard tag and 16 + 32 bits of opaque |
150 | * tag space. | 152 | * tag space. |
151 | */ | 153 | */ |
152 | static void sd_dif_type3_generate(struct blk_integrity_exchg *bix, csum_fn *fn) | 154 | static void sd_dif_type3_generate(struct blk_integrity_iter *iter, csum_fn *fn) |
153 | { | 155 | { |
154 | void *buf = bix->data_buf; | 156 | void *buf = iter->data_buf; |
155 | struct sd_dif_tuple *sdt = bix->prot_buf; | 157 | struct sd_dif_tuple *sdt = iter->prot_buf; |
156 | unsigned int i; | 158 | unsigned int i; |
157 | 159 | ||
158 | for (i = 0 ; i < bix->data_size ; i += bix->interval, sdt++) { | 160 | for (i = 0 ; i < iter->data_size ; i += iter->interval, sdt++) { |
159 | sdt->guard_tag = fn(buf, bix->interval); | 161 | sdt->guard_tag = fn(buf, iter->interval); |
160 | sdt->ref_tag = 0; | 162 | sdt->ref_tag = 0; |
161 | sdt->app_tag = 0; | 163 | sdt->app_tag = 0; |
162 | 164 | ||
163 | buf += bix->interval; | 165 | buf += iter->interval; |
164 | } | 166 | } |
165 | } | 167 | } |
166 | 168 | ||
167 | static void sd_dif_type3_generate_crc(struct blk_integrity_exchg *bix) | 169 | static int sd_dif_type3_generate_crc(struct blk_integrity_iter *iter) |
168 | { | 170 | { |
169 | sd_dif_type3_generate(bix, sd_dif_crc_fn); | 171 | sd_dif_type3_generate(iter, sd_dif_crc_fn); |
172 | return 0; | ||
170 | } | 173 | } |
171 | 174 | ||
172 | static void sd_dif_type3_generate_ip(struct blk_integrity_exchg *bix) | 175 | static int sd_dif_type3_generate_ip(struct blk_integrity_iter *iter) |
173 | { | 176 | { |
174 | sd_dif_type3_generate(bix, sd_dif_ip_fn); | 177 | sd_dif_type3_generate(iter, sd_dif_ip_fn); |
178 | return 0; | ||
175 | } | 179 | } |
176 | 180 | ||
177 | static int sd_dif_type3_verify(struct blk_integrity_exchg *bix, csum_fn *fn) | 181 | static int sd_dif_type3_verify(struct blk_integrity_iter *iter, csum_fn *fn) |
178 | { | 182 | { |
179 | void *buf = bix->data_buf; | 183 | void *buf = iter->data_buf; |
180 | struct sd_dif_tuple *sdt = bix->prot_buf; | 184 | struct sd_dif_tuple *sdt = iter->prot_buf; |
181 | sector_t seed = bix->seed; | 185 | sector_t seed = iter->seed; |
182 | unsigned int i; | 186 | unsigned int i; |
183 | __u16 csum; | 187 | __u16 csum; |
184 | 188 | ||
185 | for (i = 0 ; i < bix->data_size ; i += bix->interval, sdt++) { | 189 | for (i = 0 ; i < iter->data_size ; i += iter->interval, sdt++) { |
186 | /* Unwritten sectors */ | 190 | /* Unwritten sectors */ |
187 | if (sdt->app_tag == 0xffff && sdt->ref_tag == 0xffffffff) | 191 | if (sdt->app_tag == 0xffff && sdt->ref_tag == 0xffffffff) |
188 | return 0; | 192 | return 0; |
189 | 193 | ||
190 | csum = fn(buf, bix->interval); | 194 | csum = fn(buf, iter->interval); |
191 | 195 | ||
192 | if (sdt->guard_tag != csum) { | 196 | if (sdt->guard_tag != csum) { |
193 | printk(KERN_ERR "%s: guard tag error on sector %lu " \ | 197 | printk(KERN_ERR "%s: guard tag error on sector %lu " \ |
194 | "(rcvd %04x, data %04x)\n", bix->disk_name, | 198 | "(rcvd %04x, data %04x)\n", iter->disk_name, |
195 | (unsigned long)seed, | 199 | (unsigned long)seed, |
196 | be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); | 200 | be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); |
197 | return -EIO; | 201 | return -EIO; |
198 | } | 202 | } |
199 | 203 | ||
200 | buf += bix->interval; | 204 | buf += iter->interval; |
201 | seed++; | 205 | seed++; |
202 | } | 206 | } |
203 | 207 | ||
204 | return 0; | 208 | return 0; |
205 | } | 209 | } |
206 | 210 | ||
207 | static int sd_dif_type3_verify_crc(struct blk_integrity_exchg *bix) | 211 | static int sd_dif_type3_verify_crc(struct blk_integrity_iter *iter) |
208 | { | 212 | { |
209 | return sd_dif_type3_verify(bix, sd_dif_crc_fn); | 213 | return sd_dif_type3_verify(iter, sd_dif_crc_fn); |
210 | } | 214 | } |
211 | 215 | ||
212 | static int sd_dif_type3_verify_ip(struct blk_integrity_exchg *bix) | 216 | static int sd_dif_type3_verify_ip(struct blk_integrity_iter *iter) |
213 | { | 217 | { |
214 | return sd_dif_type3_verify(bix, sd_dif_ip_fn); | 218 | return sd_dif_type3_verify(iter, sd_dif_ip_fn); |
215 | } | 219 | } |
216 | 220 | ||
217 | static struct blk_integrity dif_type3_integrity_crc = { | 221 | static struct blk_integrity dif_type3_integrity_crc = { |
@@ -310,6 +314,7 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector, | |||
310 | phys = hw_sector & 0xffffffff; | 314 | phys = hw_sector & 0xffffffff; |
311 | 315 | ||
312 | __rq_for_each_bio(bio, rq) { | 316 | __rq_for_each_bio(bio, rq) { |
317 | struct bio_integrity_payload *bip = bio_integrity(bio); | ||
313 | struct bio_vec iv; | 318 | struct bio_vec iv; |
314 | struct bvec_iter iter; | 319 | struct bvec_iter iter; |
315 | unsigned int j; | 320 | unsigned int j; |
@@ -318,9 +323,9 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector, | |||
318 | if (bio_flagged(bio, BIO_MAPPED_INTEGRITY)) | 323 | if (bio_flagged(bio, BIO_MAPPED_INTEGRITY)) |
319 | break; | 324 | break; |
320 | 325 | ||
321 | virt = bio_integrity(bio)->bip_iter.bi_sector & 0xffffffff; | 326 | virt = bip_get_seed(bip) & 0xffffffff; |
322 | 327 | ||
323 | bip_for_each_vec(iv, bio_integrity(bio), iter) { | 328 | bip_for_each_vec(iv, bip, iter) { |
324 | sdt = kmap_atomic(iv.bv_page) | 329 | sdt = kmap_atomic(iv.bv_page) |
325 | + iv.bv_offset; | 330 | + iv.bv_offset; |
326 | 331 | ||
@@ -366,12 +371,13 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes) | |||
366 | phys >>= 3; | 371 | phys >>= 3; |
367 | 372 | ||
368 | __rq_for_each_bio(bio, scmd->request) { | 373 | __rq_for_each_bio(bio, scmd->request) { |
374 | struct bio_integrity_payload *bip = bio_integrity(bio); | ||
369 | struct bio_vec iv; | 375 | struct bio_vec iv; |
370 | struct bvec_iter iter; | 376 | struct bvec_iter iter; |
371 | 377 | ||
372 | virt = bio_integrity(bio)->bip_iter.bi_sector & 0xffffffff; | 378 | virt = bip_get_seed(bip) & 0xffffffff; |
373 | 379 | ||
374 | bip_for_each_vec(iv, bio_integrity(bio), iter) { | 380 | bip_for_each_vec(iv, bip, iter) { |
375 | sdt = kmap_atomic(iv.bv_page) | 381 | sdt = kmap_atomic(iv.bv_page) |
376 | + iv.bv_offset; | 382 | + iv.bv_offset; |
377 | 383 | ||