Blame view

drivers/md/dm-flakey.c 12 KB
3407ef526   Josef Bacik   dm: add flakey ta...
1
2
  /*
   * Copyright (C) 2003 Sistina Software (UK) Limited.
a3998799f   Mike Snitzer   dm flakey: add co...
3
   * Copyright (C) 2004, 2010-2011 Red Hat, Inc. All rights reserved.
3407ef526   Josef Bacik   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   Mike Snitzer   dm flakey: add co...
17
  #define all_corrupt_bio_flags_match(bio, fc)	\
1eff9d322   Jens Axboe   block: rename bio...
18
  	(((bio)->bi_opf & (fc)->corrupt_bio_flags) == (fc)->corrupt_bio_flags)
a3998799f   Mike Snitzer   dm flakey: add co...
19

3407ef526   Josef Bacik   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   Mike Snitzer   dm flakey: add dr...
30
  	unsigned long flags;
a3998799f   Mike Snitzer   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   Josef Bacik   dm: add flakey ta...
35
  };
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
36
  enum feature_flag_bits {
ef548c551   Mike Snitzer   dm flakey: introd...
37
38
  	DROP_WRITES,
  	ERROR_WRITES
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
39
  };
c7cfdf597   Mikulas Patocka   dm flakey: dont u...
40
41
42
  struct per_bio_data {
  	bool bio_submitted;
  };
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
43
44
  static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
  			  struct dm_target *ti)
dfd068b01   Mike Snitzer   dm flakey: suppor...
45
46
47
48
  {
  	int r;
  	unsigned argc;
  	const char *arg_name;
5916a22b8   Eric Biggers   dm: constify argu...
49
  	static const struct dm_arg _args[] = {
a3998799f   Mike Snitzer   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   Mike Snitzer   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   Mike Snitzer   dm flakey: add co...
62
  		return r;
dfd068b01   Mike Snitzer   dm flakey: suppor...
63

a3998799f   Mike Snitzer   dm flakey: add co...
64
  	while (argc) {
dfd068b01   Mike Snitzer   dm flakey: suppor...
65
66
  		arg_name = dm_shift_arg(as);
  		argc--;
7690e2530   Goldwyn Rodrigues   dm flakey: check ...
67
68
69
70
  		if (!arg_name) {
  			ti->error = "Insufficient feature arguments";
  			return -EINVAL;
  		}
b26f5e3d7   Mike Snitzer   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   Mike Snitzer   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   Mike Snitzer   dm flakey: add dr...
97
98
99
100
  			}
  
  			continue;
  		}
a3998799f   Mike Snitzer   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   Mike Snitzer   dm: flakey fix co...
105
  			if (!argc) {
a3998799f   Mike Snitzer   dm flakey: add co...
106
  				ti->error = "Feature corrupt_bio_byte requires parameters";
68e58a294   Mike Snitzer   dm: flakey fix co...
107
108
  				return -EINVAL;
  			}
a3998799f   Mike Snitzer   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   Mike Snitzer   dm flakey: suppor...
147
  		ti->error = "Unrecognised flakey feature requested";
a3998799f   Mike Snitzer   dm flakey: add co...
148
  		return -EINVAL;
dfd068b01   Mike Snitzer   dm flakey: suppor...
149
  	}
a3998799f   Mike Snitzer   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   Mike Snitzer   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   Mike Snitzer   dm flakey: add co...
157
158
159
  	}
  
  	return 0;
dfd068b01   Mike Snitzer   dm flakey: suppor...
160
  }
3407ef526   Josef Bacik   dm: add flakey ta...
161
  /*
dfd068b01   Mike Snitzer   dm flakey: suppor...
162
163
   * Construct a flakey mapping:
   * <dev_path> <offset> <up interval> <down interval> [<#feature args> [<arg>]*]
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
164
165
166
   *
   *   Feature args:
   *     [drop_writes]
a3998799f   Mike Snitzer   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   Josef Bacik   dm: add flakey ta...
172
173
174
   */
  static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
  {
5916a22b8   Eric Biggers   dm: constify argu...
175
  	static const struct dm_arg _args[] = {
dfd068b01   Mike Snitzer   dm flakey: suppor...
176
177
178
179
180
  		{0, UINT_MAX, "Invalid up interval"},
  		{0, UINT_MAX, "Invalid down interval"},
  	};
  
  	int r;
3407ef526   Josef Bacik   dm: add flakey ta...
181
  	struct flakey_c *fc;
dfd068b01   Mike Snitzer   dm flakey: suppor...
182
183
184
  	unsigned long long tmpll;
  	struct dm_arg_set as;
  	const char *devname;
31998ef19   Mikulas Patocka   dm: reject traili...
185
  	char dummy;
3407ef526   Josef Bacik   dm: add flakey ta...
186

dfd068b01   Mike Snitzer   dm flakey: suppor...
187
188
189
190
191
  	as.argc = argc;
  	as.argv = argv;
  
  	if (argc < 4) {
  		ti->error = "Invalid argument count";
3407ef526   Josef Bacik   dm: add flakey ta...
192
193
  		return -EINVAL;
  	}
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
194
  	fc = kzalloc(sizeof(*fc), GFP_KERNEL);
3407ef526   Josef Bacik   dm: add flakey ta...
195
  	if (!fc) {
75e3a0f55   Alasdair G Kergon   dm flakey: correc...
196
  		ti->error = "Cannot allocate context";
3407ef526   Josef Bacik   dm: add flakey ta...
197
198
199
  		return -ENOMEM;
  	}
  	fc->start_time = jiffies;
dfd068b01   Mike Snitzer   dm flakey: suppor...
200
  	devname = dm_shift_arg(&as);
e80d1c805   Vivek Goyal   dm: do not overri...
201
  	r = -EINVAL;
ef87bfc24   Milan Broz   dm: Check for dev...
202
  	if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
dfd068b01   Mike Snitzer   dm flakey: suppor...
203
  		ti->error = "Invalid device sector";
3407ef526   Josef Bacik   dm: add flakey ta...
204
205
  		goto bad;
  	}
dfd068b01   Mike Snitzer   dm flakey: suppor...
206
  	fc->start = tmpll;
3407ef526   Josef Bacik   dm: add flakey ta...
207

dfd068b01   Mike Snitzer   dm flakey: suppor...
208
209
  	r = dm_read_arg(_args, &as, &fc->up_interval, &ti->error);
  	if (r)
3407ef526   Josef Bacik   dm: add flakey ta...
210
  		goto bad;
3407ef526   Josef Bacik   dm: add flakey ta...
211

dfd068b01   Mike Snitzer   dm flakey: suppor...
212
213
  	r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error);
  	if (r)
3407ef526   Josef Bacik   dm: add flakey ta...
214
  		goto bad;
3407ef526   Josef Bacik   dm: add flakey ta...
215
216
  
  	if (!(fc->up_interval + fc->down_interval)) {
dfd068b01   Mike Snitzer   dm flakey: suppor...
217
  		ti->error = "Total (up + down) interval is zero";
bff7e067e   Wei Yongjun   dm flakey: return...
218
  		r = -EINVAL;
3407ef526   Josef Bacik   dm: add flakey ta...
219
220
221
222
  		goto bad;
  	}
  
  	if (fc->up_interval + fc->down_interval < fc->up_interval) {
dfd068b01   Mike Snitzer   dm flakey: suppor...
223
  		ti->error = "Interval overflow";
bff7e067e   Wei Yongjun   dm flakey: return...
224
  		r = -EINVAL;
3407ef526   Josef Bacik   dm: add flakey ta...
225
226
  		goto bad;
  	}
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
227
  	r = parse_features(&as, fc, ti);
dfd068b01   Mike Snitzer   dm flakey: suppor...
228
229
  	if (r)
  		goto bad;
e80d1c805   Vivek Goyal   dm: do not overri...
230
231
  	r = dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev);
  	if (r) {
dfd068b01   Mike Snitzer   dm flakey: suppor...
232
  		ti->error = "Device lookup failed";
3407ef526   Josef Bacik   dm: add flakey ta...
233
234
  		goto bad;
  	}
55a62eef8   Alasdair G Kergon   dm: rename reques...
235
236
  	ti->num_flush_bios = 1;
  	ti->num_discard_bios = 1;
30187e1d4   Mike Snitzer   dm: rename target...
237
  	ti->per_io_data_size = sizeof(struct per_bio_data);
3407ef526   Josef Bacik   dm: add flakey ta...
238
239
240
241
242
  	ti->private = fc;
  	return 0;
  
  bad:
  	kfree(fc);
e80d1c805   Vivek Goyal   dm: do not overri...
243
  	return r;
3407ef526   Josef Bacik   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   Mike Snitzer   dm flakey: use dm...
257
  	return fc->start + dm_target_offset(ti, bi_sector);
3407ef526   Josef Bacik   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   Christoph Hellwig   block: replace bi...
263
  	bio_set_dev(bio, fc->dev->bdev);
2e2d6f7e4   Ajay Joshi   dm: add zone open...
264
  	if (bio_sectors(bio) || op_is_zone_mgmt(bio_op(bio)))
4f024f379   Kent Overstreet   block: Abstract o...
265
266
  		bio->bi_iter.bi_sector =
  			flakey_map_sector(ti, bio->bi_iter.bi_sector);
3407ef526   Josef Bacik   dm: add flakey ta...
267
  }
a3998799f   Mike Snitzer   dm flakey: add co...
268
269
  static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
  {
a00f5276e   Sweet Tea   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   Mike Snitzer   dm flakey: add co...
277
278
  
  	/*
a00f5276e   Sweet Tea   dm flakey: Proper...
279
280
  	 * Overwrite the Nth byte of the bio's data, on whichever page
  	 * it falls.
a3998799f   Mike Snitzer   dm flakey: add co...
281
  	 */
a00f5276e   Sweet Tea   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   Mike Snitzer   dm flakey: add co...
296
297
  	}
  }
7de3ee57d   Mikulas Patocka   dm: remove map_info
298
  static int flakey_map(struct dm_target *ti, struct bio *bio)
3407ef526   Josef Bacik   dm: add flakey ta...
299
300
301
  {
  	struct flakey_c *fc = ti->private;
  	unsigned elapsed;
c7cfdf597   Mikulas Patocka   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   Josef Bacik   dm: add flakey ta...
304

2e2d6f7e4   Ajay Joshi   dm: add zone open...
305
  	if (op_is_zone_mgmt(bio_op(bio)))
124c44546   Damien Le Moal   dm flakey: add su...
306
  		goto map_bio;
3407ef526   Josef Bacik   dm: add flakey ta...
307
308
  	/* Are we alive ? */
  	elapsed = (jiffies - fc->start_time) / HZ;
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
309
  	if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) {
a3998799f   Mike Snitzer   dm flakey: add co...
310
311
312
  		/*
  		 * Flag this bio as submitted while down.
  		 */
c7cfdf597   Mikulas Patocka   dm flakey: dont u...
313
  		pb->bio_submitted = true;
a3998799f   Mike Snitzer   dm flakey: add co...
314
315
  
  		/*
ef548c551   Mike Snitzer   dm flakey: introd...
316
  		 * Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set.
299f6230b   Mike Snitzer   dm flakey: fix re...
317
  		 * Otherwise, flakey_end_io() will decide if the reads should be modified.
a3998799f   Mike Snitzer   dm flakey: add co...
318
  		 */
99f3c90d0   Mike Snitzer   dm flakey: error ...
319
  		if (bio_data_dir(bio) == READ) {
ef548c551   Mike Snitzer   dm flakey: introd...
320
321
  			if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) &&
  			    !test_bit(ERROR_WRITES, &fc->flags))
846785e6a   Christoph Hellwig   dm: don't return ...
322
  				return DM_MAPIO_KILL;
299f6230b   Mike Snitzer   dm flakey: fix re...
323
  			goto map_bio;
99f3c90d0   Mike Snitzer   dm flakey: error ...
324
  		}
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
325
326
  
  		/*
ef548c551   Mike Snitzer   dm flakey: introd...
327
  		 * Drop or error writes?
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
328
329
  		 */
  		if (test_bit(DROP_WRITES, &fc->flags)) {
4246a0b63   Christoph Hellwig   block: add a bi_e...
330
  			bio_endio(bio);
a3998799f   Mike Snitzer   dm flakey: add co...
331
332
  			return DM_MAPIO_SUBMITTED;
  		}
ef548c551   Mike Snitzer   dm flakey: introd...
333
334
335
336
  		else if (test_bit(ERROR_WRITES, &fc->flags)) {
  			bio_io_error(bio);
  			return DM_MAPIO_SUBMITTED;
  		}
a3998799f   Mike Snitzer   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   Mike Snitzer   dm flakey: add dr...
344
345
346
347
  			goto map_bio;
  		}
  
  		/*
a3998799f   Mike Snitzer   dm flakey: add co...
348
  		 * By default, error all I/O.
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
349
  		 */
846785e6a   Christoph Hellwig   dm: don't return ...
350
  		return DM_MAPIO_KILL;
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
351
  	}
3407ef526   Josef Bacik   dm: add flakey ta...
352

b26f5e3d7   Mike Snitzer   dm flakey: add dr...
353
  map_bio:
3407ef526   Josef Bacik   dm: add flakey ta...
354
355
356
357
  	flakey_map_bio(ti, bio);
  
  	return DM_MAPIO_REMAPPED;
  }
4e4cbee93   Christoph Hellwig   block: switch bio...
358
  static int flakey_end_io(struct dm_target *ti, struct bio *bio,
124c44546   Damien Le Moal   dm flakey: add su...
359
  			 blk_status_t *error)
a3998799f   Mike Snitzer   dm flakey: add co...
360
361
  {
  	struct flakey_c *fc = ti->private;
c7cfdf597   Mikulas Patocka   dm flakey: dont u...
362
  	struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
a3998799f   Mike Snitzer   dm flakey: add co...
363

2e2d6f7e4   Ajay Joshi   dm: add zone open...
364
  	if (op_is_zone_mgmt(bio_op(bio)))
124c44546   Damien Le Moal   dm flakey: add su...
365
  		return DM_ENDIO_DONE;
1be569098   Christoph Hellwig   dm: change ->end_...
366
  	if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
299f6230b   Mike Snitzer   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   Mike Snitzer   dm flakey: error ...
372
  			corrupt_bio_data(bio, fc);
299f6230b   Mike Snitzer   dm flakey: fix re...
373

ef548c551   Mike Snitzer   dm flakey: introd...
374
375
  		} else if (!test_bit(DROP_WRITES, &fc->flags) &&
  			   !test_bit(ERROR_WRITES, &fc->flags)) {
299f6230b   Mike Snitzer   dm flakey: fix re...
376
377
  			/*
  			 * Error read during the down_interval if drop_writes
ef548c551   Mike Snitzer   dm flakey: introd...
378
  			 * and error_writes were not configured.
299f6230b   Mike Snitzer   dm flakey: fix re...
379
  			 */
4e4cbee93   Christoph Hellwig   block: switch bio...
380
  			*error = BLK_STS_IOERR;
299f6230b   Mike Snitzer   dm flakey: fix re...
381
  		}
99f3c90d0   Mike Snitzer   dm flakey: error ...
382
  	}
a3998799f   Mike Snitzer   dm flakey: add co...
383

1be569098   Christoph Hellwig   dm: change ->end_...
384
  	return DM_ENDIO_DONE;
a3998799f   Mike Snitzer   dm flakey: add co...
385
  }
fd7c092e7   Mikulas Patocka   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   Josef Bacik   dm: add flakey ta...
388
  {
b26f5e3d7   Mike Snitzer   dm flakey: add dr...
389
  	unsigned sz = 0;
3407ef526   Josef Bacik   dm: add flakey ta...
390
  	struct flakey_c *fc = ti->private;
ef548c551   Mike Snitzer   dm flakey: introd...
391
  	unsigned drop_writes, error_writes;
3407ef526   Josef Bacik   dm: add flakey ta...
392
393
394
395
396
397
398
  
  	switch (type) {
  	case STATUSTYPE_INFO:
  		result[0] = '\0';
  		break;
  
  	case STATUSTYPE_TABLE:
b26f5e3d7   Mike Snitzer   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   Mike Snitzer   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   Mike Snitzer   dm flakey: add co...
406

b26f5e3d7   Mike Snitzer   dm flakey: add dr...
407
408
  		if (drop_writes)
  			DMEMIT("drop_writes ");
ef548c551   Mike Snitzer   dm flakey: introd...
409
410
  		else if (error_writes)
  			DMEMIT("error_writes ");
a3998799f   Mike Snitzer   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   Josef Bacik   dm: add flakey ta...
417
418
  		break;
  	}
3407ef526   Josef Bacik   dm: add flakey ta...
419
  }
5bd5e8d89   Mike Snitzer   dm: remove fmode_...
420
  static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
3407ef526   Josef Bacik   dm: add flakey ta...
421
422
  {
  	struct flakey_c *fc = ti->private;
e56f81e0b   Christoph Hellwig   dm: refactor ioct...
423
424
  
  	*bdev = fc->dev->bdev;
3407ef526   Josef Bacik   dm: add flakey ta...
425

ec8013bed   Paolo Bonzini   dm: do not forwar...
426
427
428
429
  	/*
  	 * Only pass ioctls through if the device sizes match exactly.
  	 */
  	if (fc->start ||
e56f81e0b   Christoph Hellwig   dm: refactor ioct...
430
431
432
  	    ti->len != i_size_read((*bdev)->bd_inode) >> SECTOR_SHIFT)
  		return 1;
  	return 0;
3407ef526   Josef Bacik   dm: add flakey ta...
433
  }
e76239a37   Christoph Hellwig   block: add a repo...
434
  #ifdef CONFIG_BLK_DEV_ZONED
d41003513   Christoph Hellwig   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   Christoph Hellwig   block: add a repo...
437
438
  {
  	struct flakey_c *fc = ti->private;
d41003513   Christoph Hellwig   block: rework zon...
439
  	sector_t sector = flakey_map_sector(ti, args->next_sector);
e76239a37   Christoph Hellwig   block: add a repo...
440

d41003513   Christoph Hellwig   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   Christoph Hellwig   block: add a repo...
444
445
  }
  #endif
3407ef526   Josef Bacik   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   Damien Le Moal   dm flakey: add su...
455
  	.version = {1, 5, 0},
118aa47c7   Damien Le Moal   dm linear: fix li...
456
  #ifdef CONFIG_BLK_DEV_ZONED
124c44546   Damien Le Moal   dm flakey: add su...
457
  	.features = DM_TARGET_ZONED_HM,
e76239a37   Christoph Hellwig   block: add a repo...
458
  	.report_zones = flakey_report_zones,
118aa47c7   Damien Le Moal   dm linear: fix li...
459
  #endif
3407ef526   Josef Bacik   dm: add flakey ta...
460
461
462
463
  	.module = THIS_MODULE,
  	.ctr    = flakey_ctr,
  	.dtr    = flakey_dtr,
  	.map    = flakey_map,
a3998799f   Mike Snitzer   dm flakey: add co...
464
  	.end_io = flakey_end_io,
3407ef526   Josef Bacik   dm: add flakey ta...
465
  	.status = flakey_status,
e56f81e0b   Christoph Hellwig   dm: refactor ioct...
466
  	.prepare_ioctl = flakey_prepare_ioctl,
3407ef526   Josef Bacik   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");