1 /* 2 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. 3 * Copyright (C) 2004 - 2006 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8 #include "dm.h" 9 10 #include <linux/module.h> 11 #include <linux/vmalloc.h> 12 #include <linux/miscdevice.h> 13 #include <linux/init.h> 14 #include <linux/wait.h> 15 #include <linux/slab.h> 16 #include <linux/dm-ioctl.h> 17 #include <linux/hdreg.h> 18 19 #include <asm/uaccess.h> 20 21 #define DM_MSG_PREFIX "ioctl" 22 #define DM_DRIVER_EMAIL "dm-devel@redhat.com" 23 24 /*----------------------------------------------------------------- 25 * The ioctl interface needs to be able to look up devices by 26 * name or uuid. 27 *---------------------------------------------------------------*/ 28 struct hash_cell { 29 struct list_head name_list; 30 struct list_head uuid_list; 31 32 char *name; 33 char *uuid; 34 struct mapped_device *md; 35 struct dm_table *new_map; 36 }; 37 38 struct vers_iter { 39 size_t param_size; 40 struct dm_target_versions *vers, *old_vers; 41 char *end; 42 uint32_t flags; 43 }; 44 45 46 #define NUM_BUCKETS 64 47 #define MASK_BUCKETS (NUM_BUCKETS - 1) 48 static struct list_head _name_buckets[NUM_BUCKETS]; 49 static struct list_head _uuid_buckets[NUM_BUCKETS]; 50 51 static void dm_hash_remove_all(int keep_open_devices); 52 53 /* 54 * Guards access to both hash tables. 55 */ 56 static DECLARE_RWSEM(_hash_lock); 57 58 static void init_buckets(struct list_head *buckets) 59 { 60 unsigned int i; 61 62 for (i = 0; i < NUM_BUCKETS; i++) 63 INIT_LIST_HEAD(buckets + i); 64 } 65 66 static int dm_hash_init(void) 67 { 68 init_buckets(_name_buckets); 69 init_buckets(_uuid_buckets); 70 return 0; 71 } 72 73 static void dm_hash_exit(void) 74 { 75 dm_hash_remove_all(0); 76 } 77 78 /*----------------------------------------------------------------- 79 * Hash function: 80 * We're not really concerned with the str hash function being 81 * fast since it's only used by the ioctl interface. 82 *---------------------------------------------------------------*/ 83 static unsigned int hash_str(const char *str) 84 { 85 const unsigned int hash_mult = 2654435387U; 86 unsigned int h = 0; 87 88 while (*str) 89 h = (h + (unsigned int) *str++) * hash_mult; 90 91 return h & MASK_BUCKETS; 92 } 93 94 /*----------------------------------------------------------------- 95 * Code for looking up a device by name 96 *---------------------------------------------------------------*/ 97 static struct hash_cell *__get_name_cell(const char *str) 98 { 99 struct hash_cell *hc; 100 unsigned int h = hash_str(str); 101 102 list_for_each_entry (hc, _name_buckets + h, name_list) 103 if (!strcmp(hc->name, str)) { 104 dm_get(hc->md); 105 return hc; 106 } 107 108 return NULL; 109 } 110 111 static struct hash_cell *__get_uuid_cell(const char *str) 112 { 113 struct hash_cell *hc; 114 unsigned int h = hash_str(str); 115 116 list_for_each_entry (hc, _uuid_buckets + h, uuid_list) 117 if (!strcmp(hc->uuid, str)) { 118 dm_get(hc->md); 119 return hc; 120 } 121 122 return NULL; 123 } 124 125 /*----------------------------------------------------------------- 126 * Inserting, removing and renaming a device. 127 *---------------------------------------------------------------*/ 128 static struct hash_cell *alloc_cell(const char *name, const char *uuid, 129 struct mapped_device *md) 130 { 131 struct hash_cell *hc; 132 133 hc = kmalloc(sizeof(*hc), GFP_KERNEL); 134 if (!hc) 135 return NULL; 136 137 hc->name = kstrdup(name, GFP_KERNEL); 138 if (!hc->name) { 139 kfree(hc); 140 return NULL; 141 } 142 143 if (!uuid) 144 hc->uuid = NULL; 145 146 else { 147 hc->uuid = kstrdup(uuid, GFP_KERNEL); 148 if (!hc->uuid) { 149 kfree(hc->name); 150 kfree(hc); 151 return NULL; 152 } 153 } 154 155 INIT_LIST_HEAD(&hc->name_list); 156 INIT_LIST_HEAD(&hc->uuid_list); 157 hc->md = md; 158 hc->new_map = NULL; 159 return hc; 160 } 161 162 static void free_cell(struct hash_cell *hc) 163 { 164 if (hc) { 165 kfree(hc->name); 166 kfree(hc->uuid); 167 kfree(hc); 168 } 169 } 170 171 /* 172 * The kdev_t and uuid of a device can never change once it is 173 * initially inserted. 174 */ 175 static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) 176 { 177 struct hash_cell *cell, *hc; 178 179 /* 180 * Allocate the new cells. 181 */ 182 cell = alloc_cell(name, uuid, md); 183 if (!cell) 184 return -ENOMEM; 185 186 /* 187 * Insert the cell into both hash tables. 188 */ 189 down_write(&_hash_lock); 190 hc = __get_name_cell(name); 191 if (hc) { 192 dm_put(hc->md); 193 goto bad; 194 } 195 196 list_add(&cell->name_list, _name_buckets + hash_str(name)); 197 198 if (uuid) { 199 hc = __get_uuid_cell(uuid); 200 if (hc) { 201 list_del(&cell->name_list); 202 dm_put(hc->md); 203 goto bad; 204 } 205 list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); 206 } 207 dm_get(md); 208 dm_set_mdptr(md, cell); 209 up_write(&_hash_lock); 210 211 return 0; 212 213 bad: 214 up_write(&_hash_lock); 215 free_cell(cell); 216 return -EBUSY; 217 } 218 219 static void __hash_remove(struct hash_cell *hc) 220 { 221 struct dm_table *table; 222 223 /* remove from the dev hash */ 224 list_del(&hc->uuid_list); 225 list_del(&hc->name_list); 226 dm_set_mdptr(hc->md, NULL); 227 228 table = dm_get_table(hc->md); 229 if (table) { 230 dm_table_event(table); 231 dm_table_put(table); 232 } 233 234 if (hc->new_map) 235 dm_table_put(hc->new_map); 236 dm_put(hc->md); 237 free_cell(hc); 238 } 239 240 static void dm_hash_remove_all(int keep_open_devices) 241 { 242 int i, dev_skipped, dev_removed; 243 struct hash_cell *hc; 244 struct list_head *tmp, *n; 245 246 down_write(&_hash_lock); 247 248 retry: 249 dev_skipped = dev_removed = 0; 250 for (i = 0; i < NUM_BUCKETS; i++) { 251 list_for_each_safe (tmp, n, _name_buckets + i) { 252 hc = list_entry(tmp, struct hash_cell, name_list); 253 254 if (keep_open_devices && 255 dm_lock_for_deletion(hc->md)) { 256 dev_skipped++; 257 continue; 258 } 259 __hash_remove(hc); 260 dev_removed = 1; 261 } 262 } 263 264 /* 265 * Some mapped devices may be using other mapped devices, so if any 266 * still exist, repeat until we make no further progress. 267 */ 268 if (dev_skipped) { 269 if (dev_removed) 270 goto retry; 271 272 DMWARN("remove_all left %d open device(s)", dev_skipped); 273 } 274 275 up_write(&_hash_lock); 276 } 277 278 static int dm_hash_rename(const char *old, const char *new) 279 { 280 char *new_name, *old_name; 281 struct hash_cell *hc; 282 struct dm_table *table; 283 284 /* 285 * duplicate new. 286 */ 287 new_name = kstrdup(new, GFP_KERNEL); 288 if (!new_name) 289 return -ENOMEM; 290 291 down_write(&_hash_lock); 292 293 /* 294 * Is new free ? 295 */ 296 hc = __get_name_cell(new); 297 if (hc) { 298 DMWARN("asked to rename to an already existing name %s -> %s", 299 old, new); 300 dm_put(hc->md); 301 up_write(&_hash_lock); 302 kfree(new_name); 303 return -EBUSY; 304 } 305 306 /* 307 * Is there such a device as 'old' ? 308 */ 309 hc = __get_name_cell(old); 310 if (!hc) { 311 DMWARN("asked to rename a non existent device %s -> %s", 312 old, new); 313 up_write(&_hash_lock); 314 kfree(new_name); 315 return -ENXIO; 316 } 317 318 /* 319 * rename and move the name cell. 320 */ 321 list_del(&hc->name_list); 322 old_name = hc->name; 323 hc->name = new_name; 324 list_add(&hc->name_list, _name_buckets + hash_str(new_name)); 325 326 /* 327 * Wake up any dm event waiters. 328 */ 329 table = dm_get_table(hc->md); 330 if (table) { 331 dm_table_event(table); 332 dm_table_put(table); 333 } 334 335 dm_put(hc->md); 336 up_write(&_hash_lock); 337 kfree(old_name); 338 return 0; 339 } 340 341 /*----------------------------------------------------------------- 342 * Implementation of the ioctl commands 343 *---------------------------------------------------------------*/ 344 /* 345 * All the ioctl commands get dispatched to functions with this 346 * prototype. 347 */ 348 typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size); 349 350 static int remove_all(struct dm_ioctl *param, size_t param_size) 351 { 352 dm_hash_remove_all(1); 353 param->data_size = 0; 354 return 0; 355 } 356 357 /* 358 * Round up the ptr to an 8-byte boundary. 359 */ 360 #define ALIGN_MASK 7 361 static inline void *align_ptr(void *ptr) 362 { 363 return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK); 364 } 365 366 /* 367 * Retrieves the data payload buffer from an already allocated 368 * struct dm_ioctl. 369 */ 370 static void *get_result_buffer(struct dm_ioctl *param, size_t param_size, 371 size_t *len) 372 { 373 param->data_start = align_ptr(param + 1) - (void *) param; 374 375 if (param->data_start < param_size) 376 *len = param_size - param->data_start; 377 else 378 *len = 0; 379 380 return ((void *) param) + param->data_start; 381 } 382 383 static int list_devices(struct dm_ioctl *param, size_t param_size) 384 { 385 unsigned int i; 386 struct hash_cell *hc; 387 size_t len, needed = 0; 388 struct gendisk *disk; 389 struct dm_name_list *nl, *old_nl = NULL; 390 391 down_write(&_hash_lock); 392 393 /* 394 * Loop through all the devices working out how much 395 * space we need. 396 */ 397 for (i = 0; i < NUM_BUCKETS; i++) { 398 list_for_each_entry (hc, _name_buckets + i, name_list) { 399 needed += sizeof(struct dm_name_list); 400 needed += strlen(hc->name) + 1; 401 needed += ALIGN_MASK; 402 } 403 } 404 405 /* 406 * Grab our output buffer. 407 */ 408 nl = get_result_buffer(param, param_size, &len); 409 if (len < needed) { 410 param->flags |= DM_BUFFER_FULL_FLAG; 411 goto out; 412 } 413 param->data_size = param->data_start + needed; 414 415 nl->dev = 0; /* Flags no data */ 416 417 /* 418 * Now loop through filling out the names. 419 */ 420 for (i = 0; i < NUM_BUCKETS; i++) { 421 list_for_each_entry (hc, _name_buckets + i, name_list) { 422 if (old_nl) 423 old_nl->next = (uint32_t) ((void *) nl - 424 (void *) old_nl); 425 disk = dm_disk(hc->md); 426 nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); 427 nl->next = 0; 428 strcpy(nl->name, hc->name); 429 430 old_nl = nl; 431 nl = align_ptr(((void *) ++nl) + strlen(hc->name) + 1); 432 } 433 } 434 435 out: 436 up_write(&_hash_lock); 437 return 0; 438 } 439 440 static void list_version_get_needed(struct target_type *tt, void *needed_param) 441 { 442 size_t *needed = needed_param; 443 444 *needed += sizeof(struct dm_target_versions); 445 *needed += strlen(tt->name); 446 *needed += ALIGN_MASK; 447 } 448 449 static void list_version_get_info(struct target_type *tt, void *param) 450 { 451 struct vers_iter *info = param; 452 453 /* Check space - it might have changed since the first iteration */ 454 if ((char *)info->vers + sizeof(tt->version) + strlen(tt->name) + 1 > 455 info->end) { 456 457 info->flags = DM_BUFFER_FULL_FLAG; 458 return; 459 } 460 461 if (info->old_vers) 462 info->old_vers->next = (uint32_t) ((void *)info->vers - 463 (void *)info->old_vers); 464 info->vers->version[0] = tt->version[0]; 465 info->vers->version[1] = tt->version[1]; 466 info->vers->version[2] = tt->version[2]; 467 info->vers->next = 0; 468 strcpy(info->vers->name, tt->name); 469 470 info->old_vers = info->vers; 471 info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1); 472 } 473 474 static int list_versions(struct dm_ioctl *param, size_t param_size) 475 { 476 size_t len, needed = 0; 477 struct dm_target_versions *vers; 478 struct vers_iter iter_info; 479 480 /* 481 * Loop through all the devices working out how much 482 * space we need. 483 */ 484 dm_target_iterate(list_version_get_needed, &needed); 485 486 /* 487 * Grab our output buffer. 488 */ 489 vers = get_result_buffer(param, param_size, &len); 490 if (len < needed) { 491 param->flags |= DM_BUFFER_FULL_FLAG; 492 goto out; 493 } 494 param->data_size = param->data_start + needed; 495 496 iter_info.param_size = param_size; 497 iter_info.old_vers = NULL; 498 iter_info.vers = vers; 499 iter_info.flags = 0; 500 iter_info.end = (char *)vers+len; 501 502 /* 503 * Now loop through filling out the names & versions. 504 */ 505 dm_target_iterate(list_version_get_info, &iter_info); 506 param->flags |= iter_info.flags; 507 508 out: 509 return 0; 510 } 511 512 513 514 static int check_name(const char *name) 515 { 516 if (strchr(name, '/')) { 517 DMWARN("invalid device name"); 518 return -EINVAL; 519 } 520 521 return 0; 522 } 523 524 /* 525 * Fills in a dm_ioctl structure, ready for sending back to 526 * userland. 527 */ 528 static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) 529 { 530 struct gendisk *disk = dm_disk(md); 531 struct dm_table *table; 532 533 param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG | 534 DM_ACTIVE_PRESENT_FLAG); 535 536 if (dm_suspended(md)) 537 param->flags |= DM_SUSPEND_FLAG; 538 539 param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); 540 541 /* 542 * Yes, this will be out of date by the time it gets back 543 * to userland, but it is still very useful for 544 * debugging. 545 */ 546 param->open_count = dm_open_count(md); 547 548 if (disk->policy) 549 param->flags |= DM_READONLY_FLAG; 550 551 param->event_nr = dm_get_event_nr(md); 552 553 table = dm_get_table(md); 554 if (table) { 555 param->flags |= DM_ACTIVE_PRESENT_FLAG; 556 param->target_count = dm_table_get_num_targets(table); 557 dm_table_put(table); 558 } else 559 param->target_count = 0; 560 561 return 0; 562 } 563 564 static int dev_create(struct dm_ioctl *param, size_t param_size) 565 { 566 int r, m = DM_ANY_MINOR; 567 struct mapped_device *md; 568 569 r = check_name(param->name); 570 if (r) 571 return r; 572 573 if (param->flags & DM_PERSISTENT_DEV_FLAG) 574 m = MINOR(huge_decode_dev(param->dev)); 575 576 r = dm_create(m, &md); 577 if (r) 578 return r; 579 580 r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md); 581 if (r) { 582 dm_put(md); 583 return r; 584 } 585 586 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 587 588 r = __dev_status(md, param); 589 dm_put(md); 590 591 return r; 592 } 593 594 /* 595 * Always use UUID for lookups if it's present, otherwise use name or dev. 596 */ 597 static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) 598 { 599 struct mapped_device *md; 600 void *mdptr = NULL; 601 602 if (*param->uuid) 603 return __get_uuid_cell(param->uuid); 604 605 if (*param->name) 606 return __get_name_cell(param->name); 607 608 md = dm_get_md(huge_decode_dev(param->dev)); 609 if (!md) 610 goto out; 611 612 mdptr = dm_get_mdptr(md); 613 if (!mdptr) 614 dm_put(md); 615 616 out: 617 return mdptr; 618 } 619 620 static struct mapped_device *find_device(struct dm_ioctl *param) 621 { 622 struct hash_cell *hc; 623 struct mapped_device *md = NULL; 624 625 down_read(&_hash_lock); 626 hc = __find_device_hash_cell(param); 627 if (hc) { 628 md = hc->md; 629 630 /* 631 * Sneakily write in both the name and the uuid 632 * while we have the cell. 633 */ 634 strncpy(param->name, hc->name, sizeof(param->name)); 635 if (hc->uuid) 636 strncpy(param->uuid, hc->uuid, sizeof(param->uuid)-1); 637 else 638 param->uuid[0] = '\0'; 639 640 if (hc->new_map) 641 param->flags |= DM_INACTIVE_PRESENT_FLAG; 642 else 643 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 644 } 645 up_read(&_hash_lock); 646 647 return md; 648 } 649 650 static int dev_remove(struct dm_ioctl *param, size_t param_size) 651 { 652 struct hash_cell *hc; 653 struct mapped_device *md; 654 int r; 655 656 down_write(&_hash_lock); 657 hc = __find_device_hash_cell(param); 658 659 if (!hc) { 660 DMWARN("device doesn't appear to be in the dev hash table."); 661 up_write(&_hash_lock); 662 return -ENXIO; 663 } 664 665 md = hc->md; 666 667 /* 668 * Ensure the device is not open and nothing further can open it. 669 */ 670 r = dm_lock_for_deletion(md); 671 if (r) { 672 DMWARN("unable to remove open device %s", hc->name); 673 up_write(&_hash_lock); 674 dm_put(md); 675 return r; 676 } 677 678 __hash_remove(hc); 679 up_write(&_hash_lock); 680 dm_put(md); 681 param->data_size = 0; 682 return 0; 683 } 684 685 /* 686 * Check a string doesn't overrun the chunk of 687 * memory we copied from userland. 688 */ 689 static int invalid_str(char *str, void *end) 690 { 691 while ((void *) str < end) 692 if (!*str++) 693 return 0; 694 695 return -EINVAL; 696 } 697 698 static int dev_rename(struct dm_ioctl *param, size_t param_size) 699 { 700 int r; 701 char *new_name = (char *) param + param->data_start; 702 703 if (new_name < (char *) (param + 1) || 704 invalid_str(new_name, (void *) param + param_size)) { 705 DMWARN("Invalid new logical volume name supplied."); 706 return -EINVAL; 707 } 708 709 r = check_name(new_name); 710 if (r) 711 return r; 712 713 param->data_size = 0; 714 return dm_hash_rename(param->name, new_name); 715 } 716 717 static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) 718 { 719 int r = -EINVAL, x; 720 struct mapped_device *md; 721 struct hd_geometry geometry; 722 unsigned long indata[4]; 723 char *geostr = (char *) param + param->data_start; 724 725 md = find_device(param); 726 if (!md) 727 return -ENXIO; 728 729 if (geostr < (char *) (param + 1) || 730 invalid_str(geostr, (void *) param + param_size)) { 731 DMWARN("Invalid geometry supplied."); 732 goto out; 733 } 734 735 x = sscanf(geostr, "%lu %lu %lu %lu", indata, 736 indata + 1, indata + 2, indata + 3); 737 738 if (x != 4) { 739 DMWARN("Unable to interpret geometry settings."); 740 goto out; 741 } 742 743 if (indata[0] > 65535 || indata[1] > 255 || 744 indata[2] > 255 || indata[3] > ULONG_MAX) { 745 DMWARN("Geometry exceeds range limits."); 746 goto out; 747 } 748 749 geometry.cylinders = indata[0]; 750 geometry.heads = indata[1]; 751 geometry.sectors = indata[2]; 752 geometry.start = indata[3]; 753 754 r = dm_set_geometry(md, &geometry); 755 if (!r) 756 r = __dev_status(md, param); 757 758 param->data_size = 0; 759 760 out: 761 dm_put(md); 762 return r; 763 } 764 765 static int do_suspend(struct dm_ioctl *param) 766 { 767 int r = 0; 768 unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG; 769 struct mapped_device *md; 770 771 md = find_device(param); 772 if (!md) 773 return -ENXIO; 774 775 if (param->flags & DM_SKIP_LOCKFS_FLAG) 776 suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; 777 if (param->flags & DM_NOFLUSH_FLAG) 778 suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; 779 780 if (!dm_suspended(md)) 781 r = dm_suspend(md, suspend_flags); 782 783 if (!r) 784 r = __dev_status(md, param); 785 786 dm_put(md); 787 return r; 788 } 789 790 static int do_resume(struct dm_ioctl *param) 791 { 792 int r = 0; 793 unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG; 794 struct hash_cell *hc; 795 struct mapped_device *md; 796 struct dm_table *new_map; 797 798 down_write(&_hash_lock); 799 800 hc = __find_device_hash_cell(param); 801 if (!hc) { 802 DMWARN("device doesn't appear to be in the dev hash table."); 803 up_write(&_hash_lock); 804 return -ENXIO; 805 } 806 807 md = hc->md; 808 809 new_map = hc->new_map; 810 hc->new_map = NULL; 811 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 812 813 up_write(&_hash_lock); 814 815 /* Do we need to load a new map ? */ 816 if (new_map) { 817 /* Suspend if it isn't already suspended */ 818 if (param->flags & DM_SKIP_LOCKFS_FLAG) 819 suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; 820 if (param->flags & DM_NOFLUSH_FLAG) 821 suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; 822 if (!dm_suspended(md)) 823 dm_suspend(md, suspend_flags); 824 825 r = dm_swap_table(md, new_map); 826 if (r) { 827 dm_put(md); 828 dm_table_put(new_map); 829 return r; 830 } 831 832 if (dm_table_get_mode(new_map) & FMODE_WRITE) 833 set_disk_ro(dm_disk(md), 0); 834 else 835 set_disk_ro(dm_disk(md), 1); 836 837 dm_table_put(new_map); 838 } 839 840 if (dm_suspended(md)) 841 r = dm_resume(md); 842 843 if (!r) 844 r = __dev_status(md, param); 845 846 dm_put(md); 847 return r; 848 } 849 850 /* 851 * Set or unset the suspension state of a device. 852 * If the device already is in the requested state we just return its status. 853 */ 854 static int dev_suspend(struct dm_ioctl *param, size_t param_size) 855 { 856 if (param->flags & DM_SUSPEND_FLAG) 857 return do_suspend(param); 858 859 return do_resume(param); 860 } 861 862 /* 863 * Copies device info back to user space, used by 864 * the create and info ioctls. 865 */ 866 static int dev_status(struct dm_ioctl *param, size_t param_size) 867 { 868 int r; 869 struct mapped_device *md; 870 871 md = find_device(param); 872 if (!md) 873 return -ENXIO; 874 875 r = __dev_status(md, param); 876 dm_put(md); 877 return r; 878 } 879 880 /* 881 * Build up the status struct for each target 882 */ 883 static void retrieve_status(struct dm_table *table, 884 struct dm_ioctl *param, size_t param_size) 885 { 886 unsigned int i, num_targets; 887 struct dm_target_spec *spec; 888 char *outbuf, *outptr; 889 status_type_t type; 890 size_t remaining, len, used = 0; 891 892 outptr = outbuf = get_result_buffer(param, param_size, &len); 893 894 if (param->flags & DM_STATUS_TABLE_FLAG) 895 type = STATUSTYPE_TABLE; 896 else 897 type = STATUSTYPE_INFO; 898 899 /* Get all the target info */ 900 num_targets = dm_table_get_num_targets(table); 901 for (i = 0; i < num_targets; i++) { 902 struct dm_target *ti = dm_table_get_target(table, i); 903 904 remaining = len - (outptr - outbuf); 905 if (remaining <= sizeof(struct dm_target_spec)) { 906 param->flags |= DM_BUFFER_FULL_FLAG; 907 break; 908 } 909 910 spec = (struct dm_target_spec *) outptr; 911 912 spec->status = 0; 913 spec->sector_start = ti->begin; 914 spec->length = ti->len; 915 strncpy(spec->target_type, ti->type->name, 916 sizeof(spec->target_type)); 917 918 outptr += sizeof(struct dm_target_spec); 919 remaining = len - (outptr - outbuf); 920 if (remaining <= 0) { 921 param->flags |= DM_BUFFER_FULL_FLAG; 922 break; 923 } 924 925 /* Get the status/table string from the target driver */ 926 if (ti->type->status) { 927 if (ti->type->status(ti, type, outptr, remaining)) { 928 param->flags |= DM_BUFFER_FULL_FLAG; 929 break; 930 } 931 } else 932 outptr[0] = '\0'; 933 934 outptr += strlen(outptr) + 1; 935 used = param->data_start + (outptr - outbuf); 936 937 outptr = align_ptr(outptr); 938 spec->next = outptr - outbuf; 939 } 940 941 if (used) 942 param->data_size = used; 943 944 param->target_count = num_targets; 945 } 946 947 /* 948 * Wait for a device to report an event 949 */ 950 static int dev_wait(struct dm_ioctl *param, size_t param_size) 951 { 952 int r; 953 struct mapped_device *md; 954 struct dm_table *table; 955 956 md = find_device(param); 957 if (!md) 958 return -ENXIO; 959 960 /* 961 * Wait for a notification event 962 */ 963 if (dm_wait_event(md, param->event_nr)) { 964 r = -ERESTARTSYS; 965 goto out; 966 } 967 968 /* 969 * The userland program is going to want to know what 970 * changed to trigger the event, so we may as well tell 971 * him and save an ioctl. 972 */ 973 r = __dev_status(md, param); 974 if (r) 975 goto out; 976 977 table = dm_get_table(md); 978 if (table) { 979 retrieve_status(table, param, param_size); 980 dm_table_put(table); 981 } 982 983 out: 984 dm_put(md); 985 return r; 986 } 987 988 static inline int get_mode(struct dm_ioctl *param) 989 { 990 int mode = FMODE_READ | FMODE_WRITE; 991 992 if (param->flags & DM_READONLY_FLAG) 993 mode = FMODE_READ; 994 995 return mode; 996 } 997 998 static int next_target(struct dm_target_spec *last, uint32_t next, void *end, 999 struct dm_target_spec **spec, char **target_params) 1000 { 1001 *spec = (struct dm_target_spec *) ((unsigned char *) last + next); 1002 *target_params = (char *) (*spec + 1); 1003 1004 if (*spec < (last + 1)) 1005 return -EINVAL; 1006 1007 return invalid_str(*target_params, end); 1008 } 1009 1010 static int populate_table(struct dm_table *table, 1011 struct dm_ioctl *param, size_t param_size) 1012 { 1013 int r; 1014 unsigned int i = 0; 1015 struct dm_target_spec *spec = (struct dm_target_spec *) param; 1016 uint32_t next = param->data_start; 1017 void *end = (void *) param + param_size; 1018 char *target_params; 1019 1020 if (!param->target_count) { 1021 DMWARN("populate_table: no targets specified"); 1022 return -EINVAL; 1023 } 1024 1025 for (i = 0; i < param->target_count; i++) { 1026 1027 r = next_target(spec, next, end, &spec, &target_params); 1028 if (r) { 1029 DMWARN("unable to find target"); 1030 return r; 1031 } 1032 1033 r = dm_table_add_target(table, spec->target_type, 1034 (sector_t) spec->sector_start, 1035 (sector_t) spec->length, 1036 target_params); 1037 if (r) { 1038 DMWARN("error adding target to table"); 1039 return r; 1040 } 1041 1042 next = spec->next; 1043 } 1044 1045 return dm_table_complete(table); 1046 } 1047 1048 static int table_load(struct dm_ioctl *param, size_t param_size) 1049 { 1050 int r; 1051 struct hash_cell *hc; 1052 struct dm_table *t; 1053 struct mapped_device *md; 1054 1055 md = find_device(param); 1056 if (!md) 1057 return -ENXIO; 1058 1059 r = dm_table_create(&t, get_mode(param), param->target_count, md); 1060 if (r) 1061 goto out; 1062 1063 r = populate_table(t, param, param_size); 1064 if (r) { 1065 dm_table_put(t); 1066 goto out; 1067 } 1068 1069 down_write(&_hash_lock); 1070 hc = dm_get_mdptr(md); 1071 if (!hc || hc->md != md) { 1072 DMWARN("device has been removed from the dev hash table."); 1073 dm_table_put(t); 1074 up_write(&_hash_lock); 1075 r = -ENXIO; 1076 goto out; 1077 } 1078 1079 if (hc->new_map) 1080 dm_table_put(hc->new_map); 1081 hc->new_map = t; 1082 up_write(&_hash_lock); 1083 1084 param->flags |= DM_INACTIVE_PRESENT_FLAG; 1085 r = __dev_status(md, param); 1086 1087 out: 1088 dm_put(md); 1089 1090 return r; 1091 } 1092 1093 static int table_clear(struct dm_ioctl *param, size_t param_size) 1094 { 1095 int r; 1096 struct hash_cell *hc; 1097 struct mapped_device *md; 1098 1099 down_write(&_hash_lock); 1100 1101 hc = __find_device_hash_cell(param); 1102 if (!hc) { 1103 DMWARN("device doesn't appear to be in the dev hash table."); 1104 up_write(&_hash_lock); 1105 return -ENXIO; 1106 } 1107 1108 if (hc->new_map) { 1109 dm_table_put(hc->new_map); 1110 hc->new_map = NULL; 1111 } 1112 1113 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 1114 1115 r = __dev_status(hc->md, param); 1116 md = hc->md; 1117 up_write(&_hash_lock); 1118 dm_put(md); 1119 return r; 1120 } 1121 1122 /* 1123 * Retrieves a list of devices used by a particular dm device. 1124 */ 1125 static void retrieve_deps(struct dm_table *table, 1126 struct dm_ioctl *param, size_t param_size) 1127 { 1128 unsigned int count = 0; 1129 struct list_head *tmp; 1130 size_t len, needed; 1131 struct dm_dev *dd; 1132 struct dm_target_deps *deps; 1133 1134 deps = get_result_buffer(param, param_size, &len); 1135 1136 /* 1137 * Count the devices. 1138 */ 1139 list_for_each (tmp, dm_table_get_devices(table)) 1140 count++; 1141 1142 /* 1143 * Check we have enough space. 1144 */ 1145 needed = sizeof(*deps) + (sizeof(*deps->dev) * count); 1146 if (len < needed) { 1147 param->flags |= DM_BUFFER_FULL_FLAG; 1148 return; 1149 } 1150 1151 /* 1152 * Fill in the devices. 1153 */ 1154 deps->count = count; 1155 count = 0; 1156 list_for_each_entry (dd, dm_table_get_devices(table), list) 1157 deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev); 1158 1159 param->data_size = param->data_start + needed; 1160 } 1161 1162 static int table_deps(struct dm_ioctl *param, size_t param_size) 1163 { 1164 int r = 0; 1165 struct mapped_device *md; 1166 struct dm_table *table; 1167 1168 md = find_device(param); 1169 if (!md) 1170 return -ENXIO; 1171 1172 r = __dev_status(md, param); 1173 if (r) 1174 goto out; 1175 1176 table = dm_get_table(md); 1177 if (table) { 1178 retrieve_deps(table, param, param_size); 1179 dm_table_put(table); 1180 } 1181 1182 out: 1183 dm_put(md); 1184 return r; 1185 } 1186 1187 /* 1188 * Return the status of a device as a text string for each 1189 * target. 1190 */ 1191 static int table_status(struct dm_ioctl *param, size_t param_size) 1192 { 1193 int r; 1194 struct mapped_device *md; 1195 struct dm_table *table; 1196 1197 md = find_device(param); 1198 if (!md) 1199 return -ENXIO; 1200 1201 r = __dev_status(md, param); 1202 if (r) 1203 goto out; 1204 1205 table = dm_get_table(md); 1206 if (table) { 1207 retrieve_status(table, param, param_size); 1208 dm_table_put(table); 1209 } 1210 1211 out: 1212 dm_put(md); 1213 return r; 1214 } 1215 1216 /* 1217 * Pass a message to the target that's at the supplied device offset. 1218 */ 1219 static int target_message(struct dm_ioctl *param, size_t param_size) 1220 { 1221 int r, argc; 1222 char **argv; 1223 struct mapped_device *md; 1224 struct dm_table *table; 1225 struct dm_target *ti; 1226 struct dm_target_msg *tmsg = (void *) param + param->data_start; 1227 1228 md = find_device(param); 1229 if (!md) 1230 return -ENXIO; 1231 1232 r = __dev_status(md, param); 1233 if (r) 1234 goto out; 1235 1236 if (tmsg < (struct dm_target_msg *) (param + 1) || 1237 invalid_str(tmsg->message, (void *) param + param_size)) { 1238 DMWARN("Invalid target message parameters."); 1239 r = -EINVAL; 1240 goto out; 1241 } 1242 1243 r = dm_split_args(&argc, &argv, tmsg->message); 1244 if (r) { 1245 DMWARN("Failed to split target message parameters"); 1246 goto out; 1247 } 1248 1249 table = dm_get_table(md); 1250 if (!table) 1251 goto out_argv; 1252 1253 if (tmsg->sector >= dm_table_get_size(table)) { 1254 DMWARN("Target message sector outside device."); 1255 r = -EINVAL; 1256 goto out_table; 1257 } 1258 1259 ti = dm_table_find_target(table, tmsg->sector); 1260 if (ti->type->message) 1261 r = ti->type->message(ti, argc, argv); 1262 else { 1263 DMWARN("Target type does not support messages"); 1264 r = -EINVAL; 1265 } 1266 1267 out_table: 1268 dm_table_put(table); 1269 out_argv: 1270 kfree(argv); 1271 out: 1272 param->data_size = 0; 1273 dm_put(md); 1274 return r; 1275 } 1276 1277 /*----------------------------------------------------------------- 1278 * Implementation of open/close/ioctl on the special char 1279 * device. 1280 *---------------------------------------------------------------*/ 1281 static ioctl_fn lookup_ioctl(unsigned int cmd) 1282 { 1283 static struct { 1284 int cmd; 1285 ioctl_fn fn; 1286 } _ioctls[] = { 1287 {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ 1288 {DM_REMOVE_ALL_CMD, remove_all}, 1289 {DM_LIST_DEVICES_CMD, list_devices}, 1290 1291 {DM_DEV_CREATE_CMD, dev_create}, 1292 {DM_DEV_REMOVE_CMD, dev_remove}, 1293 {DM_DEV_RENAME_CMD, dev_rename}, 1294 {DM_DEV_SUSPEND_CMD, dev_suspend}, 1295 {DM_DEV_STATUS_CMD, dev_status}, 1296 {DM_DEV_WAIT_CMD, dev_wait}, 1297 1298 {DM_TABLE_LOAD_CMD, table_load}, 1299 {DM_TABLE_CLEAR_CMD, table_clear}, 1300 {DM_TABLE_DEPS_CMD, table_deps}, 1301 {DM_TABLE_STATUS_CMD, table_status}, 1302 1303 {DM_LIST_VERSIONS_CMD, list_versions}, 1304 1305 {DM_TARGET_MSG_CMD, target_message}, 1306 {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry} 1307 }; 1308 1309 return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; 1310 } 1311 1312 /* 1313 * As well as checking the version compatibility this always 1314 * copies the kernel interface version out. 1315 */ 1316 static int check_version(unsigned int cmd, struct dm_ioctl __user *user) 1317 { 1318 uint32_t version[3]; 1319 int r = 0; 1320 1321 if (copy_from_user(version, user->version, sizeof(version))) 1322 return -EFAULT; 1323 1324 if ((DM_VERSION_MAJOR != version[0]) || 1325 (DM_VERSION_MINOR < version[1])) { 1326 DMWARN("ioctl interface mismatch: " 1327 "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)", 1328 DM_VERSION_MAJOR, DM_VERSION_MINOR, 1329 DM_VERSION_PATCHLEVEL, 1330 version[0], version[1], version[2], cmd); 1331 r = -EINVAL; 1332 } 1333 1334 /* 1335 * Fill in the kernel version. 1336 */ 1337 version[0] = DM_VERSION_MAJOR; 1338 version[1] = DM_VERSION_MINOR; 1339 version[2] = DM_VERSION_PATCHLEVEL; 1340 if (copy_to_user(user->version, version, sizeof(version))) 1341 return -EFAULT; 1342 1343 return r; 1344 } 1345 1346 static void free_params(struct dm_ioctl *param) 1347 { 1348 vfree(param); 1349 } 1350 1351 static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param) 1352 { 1353 struct dm_ioctl tmp, *dmi; 1354 1355 if (copy_from_user(&tmp, user, sizeof(tmp))) 1356 return -EFAULT; 1357 1358 if (tmp.data_size < sizeof(tmp)) 1359 return -EINVAL; 1360 1361 dmi = (struct dm_ioctl *) vmalloc(tmp.data_size); 1362 if (!dmi) 1363 return -ENOMEM; 1364 1365 if (copy_from_user(dmi, user, tmp.data_size)) { 1366 vfree(dmi); 1367 return -EFAULT; 1368 } 1369 1370 *param = dmi; 1371 return 0; 1372 } 1373 1374 static int validate_params(uint cmd, struct dm_ioctl *param) 1375 { 1376 /* Always clear this flag */ 1377 param->flags &= ~DM_BUFFER_FULL_FLAG; 1378 1379 /* Ignores parameters */ 1380 if (cmd == DM_REMOVE_ALL_CMD || 1381 cmd == DM_LIST_DEVICES_CMD || 1382 cmd == DM_LIST_VERSIONS_CMD) 1383 return 0; 1384 1385 if ((cmd == DM_DEV_CREATE_CMD)) { 1386 if (!*param->name) { 1387 DMWARN("name not supplied when creating device"); 1388 return -EINVAL; 1389 } 1390 } else if ((*param->uuid && *param->name)) { 1391 DMWARN("only supply one of name or uuid, cmd(%u)", cmd); 1392 return -EINVAL; 1393 } 1394 1395 /* Ensure strings are terminated */ 1396 param->name[DM_NAME_LEN - 1] = '\0'; 1397 param->uuid[DM_UUID_LEN - 1] = '\0'; 1398 1399 return 0; 1400 } 1401 1402 static int ctl_ioctl(struct inode *inode, struct file *file, 1403 uint command, ulong u) 1404 { 1405 int r = 0; 1406 unsigned int cmd; 1407 struct dm_ioctl *param; 1408 struct dm_ioctl __user *user = (struct dm_ioctl __user *) u; 1409 ioctl_fn fn = NULL; 1410 size_t param_size; 1411 1412 /* only root can play with this */ 1413 if (!capable(CAP_SYS_ADMIN)) 1414 return -EACCES; 1415 1416 if (_IOC_TYPE(command) != DM_IOCTL) 1417 return -ENOTTY; 1418 1419 cmd = _IOC_NR(command); 1420 1421 /* 1422 * Check the interface version passed in. This also 1423 * writes out the kernel's interface version. 1424 */ 1425 r = check_version(cmd, user); 1426 if (r) 1427 return r; 1428 1429 /* 1430 * Nothing more to do for the version command. 1431 */ 1432 if (cmd == DM_VERSION_CMD) 1433 return 0; 1434 1435 fn = lookup_ioctl(cmd); 1436 if (!fn) { 1437 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); 1438 return -ENOTTY; 1439 } 1440 1441 /* 1442 * Trying to avoid low memory issues when a device is 1443 * suspended. 1444 */ 1445 current->flags |= PF_MEMALLOC; 1446 1447 /* 1448 * Copy the parameters into kernel space. 1449 */ 1450 r = copy_params(user, ¶m); 1451 1452 current->flags &= ~PF_MEMALLOC; 1453 1454 if (r) 1455 return r; 1456 1457 r = validate_params(cmd, param); 1458 if (r) 1459 goto out; 1460 1461 param_size = param->data_size; 1462 param->data_size = sizeof(*param); 1463 r = fn(param, param_size); 1464 1465 /* 1466 * Copy the results back to userland. 1467 */ 1468 if (!r && copy_to_user(user, param, param->data_size)) 1469 r = -EFAULT; 1470 1471 out: 1472 free_params(param); 1473 return r; 1474 } 1475 1476 static const struct file_operations _ctl_fops = { 1477 .ioctl = ctl_ioctl, 1478 .owner = THIS_MODULE, 1479 }; 1480 1481 static struct miscdevice _dm_misc = { 1482 .minor = MISC_DYNAMIC_MINOR, 1483 .name = DM_NAME, 1484 .fops = &_ctl_fops 1485 }; 1486 1487 /* 1488 * Create misc character device and link to DM_DIR/control. 1489 */ 1490 int __init dm_interface_init(void) 1491 { 1492 int r; 1493 1494 r = dm_hash_init(); 1495 if (r) 1496 return r; 1497 1498 r = misc_register(&_dm_misc); 1499 if (r) { 1500 DMERR("misc_register failed for control device"); 1501 dm_hash_exit(); 1502 return r; 1503 } 1504 1505 DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR, 1506 DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA, 1507 DM_DRIVER_EMAIL); 1508 return 0; 1509 } 1510 1511 void dm_interface_exit(void) 1512 { 1513 if (misc_deregister(&_dm_misc) < 0) 1514 DMERR("misc_deregister failed for control device"); 1515 1516 dm_hash_exit(); 1517 } 1518