Blame view
drivers/md/dm-flakey.c
12 KB
3407ef526 dm: add flakey ta... |
1 2 |
/* * Copyright (C) 2003 Sistina Software (UK) Limited. |
a3998799f dm flakey: add co... |
3 |
* Copyright (C) 2004, 2010-2011 Red Hat, Inc. All rights reserved. |
3407ef526 dm: add flakey ta... |
4 5 6 7 8 9 10 11 12 13 14 15 16 |
* * This file is released under the GPL. */ #include <linux/device-mapper.h> #include <linux/module.h> #include <linux/init.h> #include <linux/blkdev.h> #include <linux/bio.h> #include <linux/slab.h> #define DM_MSG_PREFIX "flakey" |
a3998799f dm flakey: add co... |
17 |
#define all_corrupt_bio_flags_match(bio, fc) \ |
1eff9d322 block: rename bio... |
18 |
(((bio)->bi_opf & (fc)->corrupt_bio_flags) == (fc)->corrupt_bio_flags) |
a3998799f dm flakey: add co... |
19 |
|
3407ef526 dm: add flakey ta... |
20 21 22 23 24 25 26 27 28 29 |
/* * Flakey: Used for testing only, simulates intermittent, * catastrophic device failure. */ struct flakey_c { struct dm_dev *dev; unsigned long start_time; sector_t start; unsigned up_interval; unsigned down_interval; |
b26f5e3d7 dm flakey: add dr... |
30 |
unsigned long flags; |
a3998799f dm flakey: add co... |
31 32 33 34 |
unsigned corrupt_bio_byte; unsigned corrupt_bio_rw; unsigned corrupt_bio_value; unsigned corrupt_bio_flags; |
3407ef526 dm: add flakey ta... |
35 |
}; |
b26f5e3d7 dm flakey: add dr... |
36 |
enum feature_flag_bits { |
ef548c551 dm flakey: introd... |
37 38 |
DROP_WRITES, ERROR_WRITES |
b26f5e3d7 dm flakey: add dr... |
39 |
}; |
c7cfdf597 dm flakey: dont u... |
40 41 42 |
struct per_bio_data { bool bio_submitted; }; |
b26f5e3d7 dm flakey: add dr... |
43 44 |
static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, struct dm_target *ti) |
dfd068b01 dm flakey: suppor... |
45 46 47 48 |
{ int r; unsigned argc; const char *arg_name; |
5916a22b8 dm: constify argu... |
49 |
static const struct dm_arg _args[] = { |
a3998799f dm flakey: add co... |
50 51 52 53 |
{0, 6, "Invalid number of feature args"}, {1, UINT_MAX, "Invalid corrupt bio byte"}, {0, 255, "Invalid corrupt value to write into bio byte (0-255)"}, {0, UINT_MAX, "Invalid corrupt bio flags mask"}, |
dfd068b01 dm flakey: suppor... |
54 55 56 57 58 59 60 61 |
}; /* No feature arguments supplied. */ if (!as->argc) return 0; r = dm_read_arg_group(_args, as, &argc, &ti->error); if (r) |
a3998799f dm flakey: add co... |
62 |
return r; |
dfd068b01 dm flakey: suppor... |
63 |
|
a3998799f dm flakey: add co... |
64 |
while (argc) { |
dfd068b01 dm flakey: suppor... |
65 66 |
arg_name = dm_shift_arg(as); argc--; |
7690e2530 dm flakey: check ... |
67 68 69 70 |
if (!arg_name) { ti->error = "Insufficient feature arguments"; return -EINVAL; } |
b26f5e3d7 dm flakey: add dr... |
71 72 73 74 75 76 77 |
/* * drop_writes */ if (!strcasecmp(arg_name, "drop_writes")) { if (test_and_set_bit(DROP_WRITES, &fc->flags)) { ti->error = "Feature drop_writes duplicated"; return -EINVAL; |
ef548c551 dm flakey: introd... |
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
} else if (test_bit(ERROR_WRITES, &fc->flags)) { ti->error = "Feature drop_writes conflicts with feature error_writes"; return -EINVAL; } continue; } /* * error_writes */ if (!strcasecmp(arg_name, "error_writes")) { if (test_and_set_bit(ERROR_WRITES, &fc->flags)) { ti->error = "Feature error_writes duplicated"; return -EINVAL; } else if (test_bit(DROP_WRITES, &fc->flags)) { ti->error = "Feature error_writes conflicts with feature drop_writes"; return -EINVAL; |
b26f5e3d7 dm flakey: add dr... |
97 98 99 100 |
} continue; } |
a3998799f dm flakey: add co... |
101 102 103 104 |
/* * corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags> */ if (!strcasecmp(arg_name, "corrupt_bio_byte")) { |
68e58a294 dm: flakey fix co... |
105 |
if (!argc) { |
a3998799f dm flakey: add co... |
106 |
ti->error = "Feature corrupt_bio_byte requires parameters"; |
68e58a294 dm: flakey fix co... |
107 108 |
return -EINVAL; } |
a3998799f dm flakey: add co... |
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
r = dm_read_arg(_args + 1, as, &fc->corrupt_bio_byte, &ti->error); if (r) return r; argc--; /* * Direction r or w? */ arg_name = dm_shift_arg(as); if (!strcasecmp(arg_name, "w")) fc->corrupt_bio_rw = WRITE; else if (!strcasecmp(arg_name, "r")) fc->corrupt_bio_rw = READ; else { ti->error = "Invalid corrupt bio direction (r or w)"; return -EINVAL; } argc--; /* * Value of byte (0-255) to write in place of correct one. */ r = dm_read_arg(_args + 2, as, &fc->corrupt_bio_value, &ti->error); if (r) return r; argc--; /* * Only corrupt bios with these flags set. */ r = dm_read_arg(_args + 3, as, &fc->corrupt_bio_flags, &ti->error); if (r) return r; argc--; continue; } |
dfd068b01 dm flakey: suppor... |
147 |
ti->error = "Unrecognised flakey feature requested"; |
a3998799f dm flakey: add co... |
148 |
return -EINVAL; |
dfd068b01 dm flakey: suppor... |
149 |
} |
a3998799f dm flakey: add co... |
150 151 152 |
if (test_bit(DROP_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) { ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set"; return -EINVAL; |
ef548c551 dm flakey: introd... |
153 154 155 156 |
} else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) { ti->error = "error_writes is incompatible with corrupt_bio_byte with the WRITE flag set"; return -EINVAL; |
a3998799f dm flakey: add co... |
157 158 159 |
} return 0; |
dfd068b01 dm flakey: suppor... |
160 |
} |
3407ef526 dm: add flakey ta... |
161 |
/* |
dfd068b01 dm flakey: suppor... |
162 163 |
* Construct a flakey mapping: * <dev_path> <offset> <up interval> <down interval> [<#feature args> [<arg>]*] |
b26f5e3d7 dm flakey: add dr... |
164 165 166 |
* * Feature args: * [drop_writes] |
a3998799f dm flakey: add co... |
167 168 169 170 171 |
* [corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags>] * * Nth_byte starts from 1 for the first byte. * Direction is r for READ or w for WRITE. * bio_flags is ignored if 0. |
3407ef526 dm: add flakey ta... |
172 173 174 |
*/ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) { |
5916a22b8 dm: constify argu... |
175 |
static const struct dm_arg _args[] = { |
dfd068b01 dm flakey: suppor... |
176 177 178 179 180 |
{0, UINT_MAX, "Invalid up interval"}, {0, UINT_MAX, "Invalid down interval"}, }; int r; |
3407ef526 dm: add flakey ta... |
181 |
struct flakey_c *fc; |
dfd068b01 dm flakey: suppor... |
182 183 184 |
unsigned long long tmpll; struct dm_arg_set as; const char *devname; |
31998ef19 dm: reject traili... |
185 |
char dummy; |
3407ef526 dm: add flakey ta... |
186 |
|
dfd068b01 dm flakey: suppor... |
187 188 189 190 191 |
as.argc = argc; as.argv = argv; if (argc < 4) { ti->error = "Invalid argument count"; |
3407ef526 dm: add flakey ta... |
192 193 |
return -EINVAL; } |
b26f5e3d7 dm flakey: add dr... |
194 |
fc = kzalloc(sizeof(*fc), GFP_KERNEL); |
3407ef526 dm: add flakey ta... |
195 |
if (!fc) { |
75e3a0f55 dm flakey: correc... |
196 |
ti->error = "Cannot allocate context"; |
3407ef526 dm: add flakey ta... |
197 198 199 |
return -ENOMEM; } fc->start_time = jiffies; |
dfd068b01 dm flakey: suppor... |
200 |
devname = dm_shift_arg(&as); |
e80d1c805 dm: do not overri... |
201 |
r = -EINVAL; |
ef87bfc24 dm: Check for dev... |
202 |
if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) { |
dfd068b01 dm flakey: suppor... |
203 |
ti->error = "Invalid device sector"; |
3407ef526 dm: add flakey ta... |
204 205 |
goto bad; } |
dfd068b01 dm flakey: suppor... |
206 |
fc->start = tmpll; |
3407ef526 dm: add flakey ta... |
207 |
|
dfd068b01 dm flakey: suppor... |
208 209 |
r = dm_read_arg(_args, &as, &fc->up_interval, &ti->error); if (r) |
3407ef526 dm: add flakey ta... |
210 |
goto bad; |
3407ef526 dm: add flakey ta... |
211 |
|
dfd068b01 dm flakey: suppor... |
212 213 |
r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error); if (r) |
3407ef526 dm: add flakey ta... |
214 |
goto bad; |
3407ef526 dm: add flakey ta... |
215 216 |
if (!(fc->up_interval + fc->down_interval)) { |
dfd068b01 dm flakey: suppor... |
217 |
ti->error = "Total (up + down) interval is zero"; |
bff7e067e dm flakey: return... |
218 |
r = -EINVAL; |
3407ef526 dm: add flakey ta... |
219 220 221 222 |
goto bad; } if (fc->up_interval + fc->down_interval < fc->up_interval) { |
dfd068b01 dm flakey: suppor... |
223 |
ti->error = "Interval overflow"; |
bff7e067e dm flakey: return... |
224 |
r = -EINVAL; |
3407ef526 dm: add flakey ta... |
225 226 |
goto bad; } |
b26f5e3d7 dm flakey: add dr... |
227 |
r = parse_features(&as, fc, ti); |
dfd068b01 dm flakey: suppor... |
228 229 |
if (r) goto bad; |
e80d1c805 dm: do not overri... |
230 231 |
r = dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev); if (r) { |
dfd068b01 dm flakey: suppor... |
232 |
ti->error = "Device lookup failed"; |
3407ef526 dm: add flakey ta... |
233 234 |
goto bad; } |
55a62eef8 dm: rename reques... |
235 236 |
ti->num_flush_bios = 1; ti->num_discard_bios = 1; |
30187e1d4 dm: rename target... |
237 |
ti->per_io_data_size = sizeof(struct per_bio_data); |
3407ef526 dm: add flakey ta... |
238 239 240 241 242 |
ti->private = fc; return 0; bad: kfree(fc); |
e80d1c805 dm: do not overri... |
243 |
return r; |
3407ef526 dm: add flakey ta... |
244 245 246 247 248 249 250 251 252 253 254 255 256 |
} static void flakey_dtr(struct dm_target *ti) { struct flakey_c *fc = ti->private; dm_put_device(ti, fc->dev); kfree(fc); } static sector_t flakey_map_sector(struct dm_target *ti, sector_t bi_sector) { struct flakey_c *fc = ti->private; |
30e4171bf dm flakey: use dm... |
257 |
return fc->start + dm_target_offset(ti, bi_sector); |
3407ef526 dm: add flakey ta... |
258 259 260 261 262 |
} static void flakey_map_bio(struct dm_target *ti, struct bio *bio) { struct flakey_c *fc = ti->private; |
74d46992e block: replace bi... |
263 |
bio_set_dev(bio, fc->dev->bdev); |
2e2d6f7e4 dm: add zone open... |
264 |
if (bio_sectors(bio) || op_is_zone_mgmt(bio_op(bio))) |
4f024f379 block: Abstract o... |
265 266 |
bio->bi_iter.bi_sector = flakey_map_sector(ti, bio->bi_iter.bi_sector); |
3407ef526 dm: add flakey ta... |
267 |
} |
a3998799f dm flakey: add co... |
268 269 |
static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc) { |
a00f5276e dm flakey: Proper... |
270 271 272 273 274 275 276 |
unsigned int corrupt_bio_byte = fc->corrupt_bio_byte - 1; struct bvec_iter iter; struct bio_vec bvec; if (!bio_has_data(bio)) return; |
a3998799f dm flakey: add co... |
277 278 |
/* |
a00f5276e dm flakey: Proper... |
279 280 |
* Overwrite the Nth byte of the bio's data, on whichever page * it falls. |
a3998799f dm flakey: add co... |
281 |
*/ |
a00f5276e dm flakey: Proper... |
282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
bio_for_each_segment(bvec, bio, iter) { if (bio_iter_len(bio, iter) > corrupt_bio_byte) { char *segment = (page_address(bio_iter_page(bio, iter)) + bio_iter_offset(bio, iter)); segment[corrupt_bio_byte] = fc->corrupt_bio_value; DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " "(rw=%c bi_opf=%u bi_sector=%llu size=%u) ", bio, fc->corrupt_bio_value, fc->corrupt_bio_byte, (bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf, (unsigned long long)bio->bi_iter.bi_sector, bio->bi_iter.bi_size); break; } corrupt_bio_byte -= bio_iter_len(bio, iter); |
a3998799f dm flakey: add co... |
296 297 |
} } |
7de3ee57d dm: remove map_info |
298 |
static int flakey_map(struct dm_target *ti, struct bio *bio) |
3407ef526 dm: add flakey ta... |
299 300 301 |
{ struct flakey_c *fc = ti->private; unsigned elapsed; |
c7cfdf597 dm flakey: dont u... |
302 303 |
struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); pb->bio_submitted = false; |
3407ef526 dm: add flakey ta... |
304 |
|
2e2d6f7e4 dm: add zone open... |
305 |
if (op_is_zone_mgmt(bio_op(bio))) |
124c44546 dm flakey: add su... |
306 |
goto map_bio; |
3407ef526 dm: add flakey ta... |
307 308 |
/* Are we alive ? */ elapsed = (jiffies - fc->start_time) / HZ; |
b26f5e3d7 dm flakey: add dr... |
309 |
if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) { |
a3998799f dm flakey: add co... |
310 311 312 |
/* * Flag this bio as submitted while down. */ |
c7cfdf597 dm flakey: dont u... |
313 |
pb->bio_submitted = true; |
a3998799f dm flakey: add co... |
314 315 |
/* |
ef548c551 dm flakey: introd... |
316 |
* Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set. |
299f6230b dm flakey: fix re... |
317 |
* Otherwise, flakey_end_io() will decide if the reads should be modified. |
a3998799f dm flakey: add co... |
318 |
*/ |
99f3c90d0 dm flakey: error ... |
319 |
if (bio_data_dir(bio) == READ) { |
ef548c551 dm flakey: introd... |
320 321 |
if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags)) |
846785e6a dm: don't return ... |
322 |
return DM_MAPIO_KILL; |
299f6230b dm flakey: fix re... |
323 |
goto map_bio; |
99f3c90d0 dm flakey: error ... |
324 |
} |
b26f5e3d7 dm flakey: add dr... |
325 326 |
/* |
ef548c551 dm flakey: introd... |
327 |
* Drop or error writes? |
b26f5e3d7 dm flakey: add dr... |
328 329 |
*/ if (test_bit(DROP_WRITES, &fc->flags)) { |
4246a0b63 block: add a bi_e... |
330 |
bio_endio(bio); |
a3998799f dm flakey: add co... |
331 332 |
return DM_MAPIO_SUBMITTED; } |
ef548c551 dm flakey: introd... |
333 334 335 336 |
else if (test_bit(ERROR_WRITES, &fc->flags)) { bio_io_error(bio); return DM_MAPIO_SUBMITTED; } |
a3998799f dm flakey: add co... |
337 338 339 340 341 342 343 |
/* * Corrupt matching writes. */ if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == WRITE)) { if (all_corrupt_bio_flags_match(bio, fc)) corrupt_bio_data(bio, fc); |
b26f5e3d7 dm flakey: add dr... |
344 345 346 347 |
goto map_bio; } /* |
a3998799f dm flakey: add co... |
348 |
* By default, error all I/O. |
b26f5e3d7 dm flakey: add dr... |
349 |
*/ |
846785e6a dm: don't return ... |
350 |
return DM_MAPIO_KILL; |
b26f5e3d7 dm flakey: add dr... |
351 |
} |
3407ef526 dm: add flakey ta... |
352 |
|
b26f5e3d7 dm flakey: add dr... |
353 |
map_bio: |
3407ef526 dm: add flakey ta... |
354 355 356 357 |
flakey_map_bio(ti, bio); return DM_MAPIO_REMAPPED; } |
4e4cbee93 block: switch bio... |
358 |
static int flakey_end_io(struct dm_target *ti, struct bio *bio, |
124c44546 dm flakey: add su... |
359 |
blk_status_t *error) |
a3998799f dm flakey: add co... |
360 361 |
{ struct flakey_c *fc = ti->private; |
c7cfdf597 dm flakey: dont u... |
362 |
struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); |
a3998799f dm flakey: add co... |
363 |
|
2e2d6f7e4 dm: add zone open... |
364 |
if (op_is_zone_mgmt(bio_op(bio))) |
124c44546 dm flakey: add su... |
365 |
return DM_ENDIO_DONE; |
1be569098 dm: change ->end_... |
366 |
if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { |
299f6230b dm flakey: fix re... |
367 368 369 370 371 |
if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && all_corrupt_bio_flags_match(bio, fc)) { /* * Corrupt successful matching READs while in down state. */ |
99f3c90d0 dm flakey: error ... |
372 |
corrupt_bio_data(bio, fc); |
299f6230b dm flakey: fix re... |
373 |
|
ef548c551 dm flakey: introd... |
374 375 |
} else if (!test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags)) { |
299f6230b dm flakey: fix re... |
376 377 |
/* * Error read during the down_interval if drop_writes |
ef548c551 dm flakey: introd... |
378 |
* and error_writes were not configured. |
299f6230b dm flakey: fix re... |
379 |
*/ |
4e4cbee93 block: switch bio... |
380 |
*error = BLK_STS_IOERR; |
299f6230b dm flakey: fix re... |
381 |
} |
99f3c90d0 dm flakey: error ... |
382 |
} |
a3998799f dm flakey: add co... |
383 |
|
1be569098 dm: change ->end_... |
384 |
return DM_ENDIO_DONE; |
a3998799f dm flakey: add co... |
385 |
} |
fd7c092e7 dm: fix truncated... |
386 387 |
static void flakey_status(struct dm_target *ti, status_type_t type, unsigned status_flags, char *result, unsigned maxlen) |
3407ef526 dm: add flakey ta... |
388 |
{ |
b26f5e3d7 dm flakey: add dr... |
389 |
unsigned sz = 0; |
3407ef526 dm: add flakey ta... |
390 |
struct flakey_c *fc = ti->private; |
ef548c551 dm flakey: introd... |
391 |
unsigned drop_writes, error_writes; |
3407ef526 dm: add flakey ta... |
392 393 394 395 396 397 398 |
switch (type) { case STATUSTYPE_INFO: result[0] = '\0'; break; case STATUSTYPE_TABLE: |
b26f5e3d7 dm flakey: add dr... |
399 400 401 402 403 |
DMEMIT("%s %llu %u %u ", fc->dev->name, (unsigned long long)fc->start, fc->up_interval, fc->down_interval); drop_writes = test_bit(DROP_WRITES, &fc->flags); |
ef548c551 dm flakey: introd... |
404 405 |
error_writes = test_bit(ERROR_WRITES, &fc->flags); DMEMIT("%u ", drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5); |
a3998799f dm flakey: add co... |
406 |
|
b26f5e3d7 dm flakey: add dr... |
407 408 |
if (drop_writes) DMEMIT("drop_writes "); |
ef548c551 dm flakey: introd... |
409 410 |
else if (error_writes) DMEMIT("error_writes "); |
a3998799f dm flakey: add co... |
411 412 413 414 415 416 |
if (fc->corrupt_bio_byte) DMEMIT("corrupt_bio_byte %u %c %u %u ", fc->corrupt_bio_byte, (fc->corrupt_bio_rw == WRITE) ? 'w' : 'r', fc->corrupt_bio_value, fc->corrupt_bio_flags); |
3407ef526 dm: add flakey ta... |
417 418 |
break; } |
3407ef526 dm: add flakey ta... |
419 |
} |
5bd5e8d89 dm: remove fmode_... |
420 |
static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev) |
3407ef526 dm: add flakey ta... |
421 422 |
{ struct flakey_c *fc = ti->private; |
e56f81e0b dm: refactor ioct... |
423 424 |
*bdev = fc->dev->bdev; |
3407ef526 dm: add flakey ta... |
425 |
|
ec8013bed dm: do not forwar... |
426 427 428 429 |
/* * Only pass ioctls through if the device sizes match exactly. */ if (fc->start || |
e56f81e0b dm: refactor ioct... |
430 431 432 |
ti->len != i_size_read((*bdev)->bd_inode) >> SECTOR_SHIFT) return 1; return 0; |
3407ef526 dm: add flakey ta... |
433 |
} |
e76239a37 block: add a repo... |
434 |
#ifdef CONFIG_BLK_DEV_ZONED |
d41003513 block: rework zon... |
435 436 |
static int flakey_report_zones(struct dm_target *ti, struct dm_report_zones_args *args, unsigned int nr_zones) |
e76239a37 block: add a repo... |
437 438 |
{ struct flakey_c *fc = ti->private; |
d41003513 block: rework zon... |
439 |
sector_t sector = flakey_map_sector(ti, args->next_sector); |
e76239a37 block: add a repo... |
440 |
|
d41003513 block: rework zon... |
441 442 443 |
args->start = fc->start; return blkdev_report_zones(fc->dev->bdev, sector, nr_zones, dm_report_zones_cb, args); |
e76239a37 block: add a repo... |
444 445 |
} #endif |
3407ef526 dm: add flakey ta... |
446 447 448 449 450 451 452 453 454 |
static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { struct flakey_c *fc = ti->private; return fn(ti, fc->dev, fc->start, ti->len, data); } static struct target_type flakey_target = { .name = "flakey", |
124c44546 dm flakey: add su... |
455 |
.version = {1, 5, 0}, |
118aa47c7 dm linear: fix li... |
456 |
#ifdef CONFIG_BLK_DEV_ZONED |
124c44546 dm flakey: add su... |
457 |
.features = DM_TARGET_ZONED_HM, |
e76239a37 block: add a repo... |
458 |
.report_zones = flakey_report_zones, |
118aa47c7 dm linear: fix li... |
459 |
#endif |
3407ef526 dm: add flakey ta... |
460 461 462 463 |
.module = THIS_MODULE, .ctr = flakey_ctr, .dtr = flakey_dtr, .map = flakey_map, |
a3998799f dm flakey: add co... |
464 |
.end_io = flakey_end_io, |
3407ef526 dm: add flakey ta... |
465 |
.status = flakey_status, |
e56f81e0b dm: refactor ioct... |
466 |
.prepare_ioctl = flakey_prepare_ioctl, |
3407ef526 dm: add flakey ta... |
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
.iterate_devices = flakey_iterate_devices, }; static int __init dm_flakey_init(void) { int r = dm_register_target(&flakey_target); if (r < 0) DMERR("register failed %d", r); return r; } static void __exit dm_flakey_exit(void) { dm_unregister_target(&flakey_target); } /* Module hooks */ module_init(dm_flakey_init); module_exit(dm_flakey_exit); MODULE_DESCRIPTION(DM_NAME " flakey target"); MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); MODULE_LICENSE("GPL"); |