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