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