Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dm-stripe.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2001-2003 Sistina Software (UK) Limited.
3  *
4  * This file is released under the GPL.
5  */
6 
7 #include <linux/device-mapper.h>
8 
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/blkdev.h>
12 #include <linux/bio.h>
13 #include <linux/slab.h>
14 #include <linux/log2.h>
15 
16 #define DM_MSG_PREFIX "striped"
17 #define DM_IO_ERROR_THRESHOLD 15
18 
19 struct stripe {
20  struct dm_dev *dev;
22 
24 };
25 
26 struct stripe_c {
29 
30  /* The size of this target / num. stripes */
32 
35 
36  /* Needed for handling events */
37  struct dm_target *ti;
38 
39  /* Work struct used for triggering events*/
41 
42  struct stripe stripe[0];
43 };
44 
45 /*
46  * An event is triggered whenever a drive
47  * drops out of a stripe volume.
48  */
49 static void trigger_event(struct work_struct *work)
50 {
51  struct stripe_c *sc = container_of(work, struct stripe_c,
53  dm_table_event(sc->ti->table);
54 }
55 
56 static inline struct stripe_c *alloc_context(unsigned int stripes)
57 {
58  size_t len;
59 
60  if (dm_array_too_big(sizeof(struct stripe_c), sizeof(struct stripe),
61  stripes))
62  return NULL;
63 
64  len = sizeof(struct stripe_c) + (sizeof(struct stripe) * stripes);
65 
66  return kmalloc(len, GFP_KERNEL);
67 }
68 
69 /*
70  * Parse a single <dev> <sector> pair
71  */
72 static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
73  unsigned int stripe, char **argv)
74 {
75  unsigned long long start;
76  char dummy;
77 
78  if (sscanf(argv[1], "%llu%c", &start, &dummy) != 1)
79  return -EINVAL;
80 
81  if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
82  &sc->stripe[stripe].dev))
83  return -ENXIO;
84 
85  sc->stripe[stripe].physical_start = start;
86 
87  return 0;
88 }
89 
90 /*
91  * Construct a striped mapping.
92  * <number of stripes> <chunk size> [<dev_path> <offset>]+
93  */
94 static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
95 {
96  struct stripe_c *sc;
100  int r;
101  unsigned int i;
102 
103  if (argc < 2) {
104  ti->error = "Not enough arguments";
105  return -EINVAL;
106  }
107 
108  if (kstrtouint(argv[0], 10, &stripes) || !stripes) {
109  ti->error = "Invalid stripe count";
110  return -EINVAL;
111  }
112 
113  if (kstrtouint(argv[1], 10, &chunk_size) || !chunk_size) {
114  ti->error = "Invalid chunk_size";
115  return -EINVAL;
116  }
117 
118  width = ti->len;
119  if (sector_div(width, chunk_size)) {
120  ti->error = "Target length not divisible by "
121  "chunk size";
122  return -EINVAL;
123  }
124 
125  if (sector_div(width, stripes)) {
126  ti->error = "Target length not divisible by "
127  "number of stripes";
128  return -EINVAL;
129  }
130 
131  /*
132  * Do we have enough arguments for that many stripes ?
133  */
134  if (argc != (2 + 2 * stripes)) {
135  ti->error = "Not enough destinations "
136  "specified";
137  return -EINVAL;
138  }
139 
140  sc = alloc_context(stripes);
141  if (!sc) {
142  ti->error = "Memory allocation for striped context "
143  "failed";
144  return -ENOMEM;
145  }
146 
148 
149  /* Set pointer to dm target; used in trigger_event */
150  sc->ti = ti;
151  sc->stripes = stripes;
152  sc->stripe_width = width;
153 
154  if (stripes & (stripes - 1))
155  sc->stripes_shift = -1;
156  else
157  sc->stripes_shift = __ffs(stripes);
158 
159  r = dm_set_target_max_io_len(ti, chunk_size);
160  if (r)
161  return r;
162 
165 
166  sc->chunk_size = chunk_size;
167  if (chunk_size & (chunk_size - 1))
168  sc->chunk_size_shift = -1;
169  else
170  sc->chunk_size_shift = __ffs(chunk_size);
171 
172  /*
173  * Get the stripe destinations.
174  */
175  for (i = 0; i < stripes; i++) {
176  argv += 2;
177 
178  r = get_stripe(ti, sc, i, argv);
179  if (r < 0) {
180  ti->error = "Couldn't parse stripe destination";
181  while (i--)
182  dm_put_device(ti, sc->stripe[i].dev);
183  kfree(sc);
184  return r;
185  }
186  atomic_set(&(sc->stripe[i].error_count), 0);
187  }
188 
189  ti->private = sc;
190 
191  return 0;
192 }
193 
194 static void stripe_dtr(struct dm_target *ti)
195 {
196  unsigned int i;
197  struct stripe_c *sc = (struct stripe_c *) ti->private;
198 
199  for (i = 0; i < sc->stripes; i++)
200  dm_put_device(ti, sc->stripe[i].dev);
201 
203  kfree(sc);
204 }
205 
206 static void stripe_map_sector(struct stripe_c *sc, sector_t sector,
207  uint32_t *stripe, sector_t *result)
208 {
209  sector_t chunk = dm_target_offset(sc->ti, sector);
211 
212  if (sc->chunk_size_shift < 0)
213  chunk_offset = sector_div(chunk, sc->chunk_size);
214  else {
215  chunk_offset = chunk & (sc->chunk_size - 1);
216  chunk >>= sc->chunk_size_shift;
217  }
218 
219  if (sc->stripes_shift < 0)
220  *stripe = sector_div(chunk, sc->stripes);
221  else {
222  *stripe = chunk & (sc->stripes - 1);
223  chunk >>= sc->stripes_shift;
224  }
225 
226  if (sc->chunk_size_shift < 0)
227  chunk *= sc->chunk_size;
228  else
229  chunk <<= sc->chunk_size_shift;
230 
231  *result = chunk + chunk_offset;
232 }
233 
234 static void stripe_map_range_sector(struct stripe_c *sc, sector_t sector,
235  uint32_t target_stripe, sector_t *result)
236 {
238 
239  stripe_map_sector(sc, sector, &stripe, result);
240  if (stripe == target_stripe)
241  return;
242 
243  /* round down */
244  sector = *result;
245  if (sc->chunk_size_shift < 0)
246  *result -= sector_div(sector, sc->chunk_size);
247  else
248  *result = sector & ~(sector_t)(sc->chunk_size - 1);
249 
250  if (target_stripe < stripe)
251  *result += sc->chunk_size; /* next chunk */
252 }
253 
254 static int stripe_map_discard(struct stripe_c *sc, struct bio *bio,
255  uint32_t target_stripe)
256 {
257  sector_t begin, end;
258 
259  stripe_map_range_sector(sc, bio->bi_sector, target_stripe, &begin);
260  stripe_map_range_sector(sc, bio->bi_sector + bio_sectors(bio),
261  target_stripe, &end);
262  if (begin < end) {
263  bio->bi_bdev = sc->stripe[target_stripe].dev->bdev;
264  bio->bi_sector = begin + sc->stripe[target_stripe].physical_start;
265  bio->bi_size = to_bytes(end - begin);
266  return DM_MAPIO_REMAPPED;
267  } else {
268  /* The range doesn't map to the target stripe */
269  bio_endio(bio, 0);
270  return DM_MAPIO_SUBMITTED;
271  }
272 }
273 
274 static int stripe_map(struct dm_target *ti, struct bio *bio,
275  union map_info *map_context)
276 {
277  struct stripe_c *sc = ti->private;
279  unsigned target_request_nr;
280 
281  if (bio->bi_rw & REQ_FLUSH) {
282  target_request_nr = map_context->target_request_nr;
283  BUG_ON(target_request_nr >= sc->stripes);
284  bio->bi_bdev = sc->stripe[target_request_nr].dev->bdev;
285  return DM_MAPIO_REMAPPED;
286  }
287  if (unlikely(bio->bi_rw & REQ_DISCARD)) {
288  target_request_nr = map_context->target_request_nr;
289  BUG_ON(target_request_nr >= sc->stripes);
290  return stripe_map_discard(sc, bio, target_request_nr);
291  }
292 
293  stripe_map_sector(sc, bio->bi_sector, &stripe, &bio->bi_sector);
294 
295  bio->bi_sector += sc->stripe[stripe].physical_start;
296  bio->bi_bdev = sc->stripe[stripe].dev->bdev;
297 
298  return DM_MAPIO_REMAPPED;
299 }
300 
301 /*
302  * Stripe status:
303  *
304  * INFO
305  * #stripes [stripe_name <stripe_name>] [group word count]
306  * [error count 'A|D' <error count 'A|D'>]
307  *
308  * TABLE
309  * #stripes [stripe chunk size]
310  * [stripe_name physical_start <stripe_name physical_start>]
311  *
312  */
313 
314 static int stripe_status(struct dm_target *ti, status_type_t type,
315  unsigned status_flags, char *result, unsigned maxlen)
316 {
317  struct stripe_c *sc = (struct stripe_c *) ti->private;
318  char buffer[sc->stripes + 1];
319  unsigned int sz = 0;
320  unsigned int i;
321 
322  switch (type) {
323  case STATUSTYPE_INFO:
324  DMEMIT("%d ", sc->stripes);
325  for (i = 0; i < sc->stripes; i++) {
326  DMEMIT("%s ", sc->stripe[i].dev->name);
327  buffer[i] = atomic_read(&(sc->stripe[i].error_count)) ?
328  'D' : 'A';
329  }
330  buffer[i] = '\0';
331  DMEMIT("1 %s", buffer);
332  break;
333 
334  case STATUSTYPE_TABLE:
335  DMEMIT("%d %llu", sc->stripes,
336  (unsigned long long)sc->chunk_size);
337  for (i = 0; i < sc->stripes; i++)
338  DMEMIT(" %s %llu", sc->stripe[i].dev->name,
339  (unsigned long long)sc->stripe[i].physical_start);
340  break;
341  }
342  return 0;
343 }
344 
345 static int stripe_end_io(struct dm_target *ti, struct bio *bio,
346  int error, union map_info *map_context)
347 {
348  unsigned i;
349  char major_minor[16];
350  struct stripe_c *sc = ti->private;
351 
352  if (!error)
353  return 0; /* I/O complete */
354 
355  if ((error == -EWOULDBLOCK) && (bio->bi_rw & REQ_RAHEAD))
356  return error;
357 
358  if (error == -EOPNOTSUPP)
359  return error;
360 
361  memset(major_minor, 0, sizeof(major_minor));
362  sprintf(major_minor, "%d:%d",
363  MAJOR(disk_devt(bio->bi_bdev->bd_disk)),
364  MINOR(disk_devt(bio->bi_bdev->bd_disk)));
365 
366  /*
367  * Test to see which stripe drive triggered the event
368  * and increment error count for all stripes on that device.
369  * If the error count for a given device exceeds the threshold
370  * value we will no longer trigger any further events.
371  */
372  for (i = 0; i < sc->stripes; i++)
373  if (!strcmp(sc->stripe[i].dev->name, major_minor)) {
374  atomic_inc(&(sc->stripe[i].error_count));
375  if (atomic_read(&(sc->stripe[i].error_count)) <
378  }
379 
380  return error;
381 }
382 
383 static int stripe_iterate_devices(struct dm_target *ti,
385 {
386  struct stripe_c *sc = ti->private;
387  int ret = 0;
388  unsigned i = 0;
389 
390  do {
391  ret = fn(ti, sc->stripe[i].dev,
392  sc->stripe[i].physical_start,
393  sc->stripe_width, data);
394  } while (!ret && ++i < sc->stripes);
395 
396  return ret;
397 }
398 
399 static void stripe_io_hints(struct dm_target *ti,
400  struct queue_limits *limits)
401 {
402  struct stripe_c *sc = ti->private;
403  unsigned chunk_size = sc->chunk_size << SECTOR_SHIFT;
404 
405  blk_limits_io_min(limits, chunk_size);
406  blk_limits_io_opt(limits, chunk_size * sc->stripes);
407 }
408 
409 static int stripe_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
410  struct bio_vec *biovec, int max_size)
411 {
412  struct stripe_c *sc = ti->private;
413  sector_t bvm_sector = bvm->bi_sector;
415  struct request_queue *q;
416 
417  stripe_map_sector(sc, bvm_sector, &stripe, &bvm_sector);
418 
419  q = bdev_get_queue(sc->stripe[stripe].dev->bdev);
420  if (!q->merge_bvec_fn)
421  return max_size;
422 
423  bvm->bi_bdev = sc->stripe[stripe].dev->bdev;
424  bvm->bi_sector = sc->stripe[stripe].physical_start + bvm_sector;
425 
426  return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
427 }
428 
429 static struct target_type stripe_target = {
430  .name = "striped",
431  .version = {1, 5, 0},
432  .module = THIS_MODULE,
433  .ctr = stripe_ctr,
434  .dtr = stripe_dtr,
435  .map = stripe_map,
436  .end_io = stripe_end_io,
437  .status = stripe_status,
438  .iterate_devices = stripe_iterate_devices,
439  .io_hints = stripe_io_hints,
440  .merge = stripe_merge,
441 };
442 
444 {
445  int r;
446 
447  r = dm_register_target(&stripe_target);
448  if (r < 0) {
449  DMWARN("target registration failed");
450  return r;
451  }
452 
453  return r;
454 }
455 
456 void dm_stripe_exit(void)
457 {
458  dm_unregister_target(&stripe_target);
459 }