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 int do_lockfs = 1; 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 do_lockfs = 0; 777 778 if (!dm_suspended(md)) 779 r = dm_suspend(md, do_lockfs); 780 781 if (!r) 782 r = __dev_status(md, param); 783 784 dm_put(md); 785 return r; 786 } 787 788 static int do_resume(struct dm_ioctl *param) 789 { 790 int r = 0; 791 int do_lockfs = 1; 792 struct hash_cell *hc; 793 struct mapped_device *md; 794 struct dm_table *new_map; 795 796 down_write(&_hash_lock); 797 798 hc = __find_device_hash_cell(param); 799 if (!hc) { 800 DMWARN("device doesn't appear to be in the dev hash table."); 801 up_write(&_hash_lock); 802 return -ENXIO; 803 } 804 805 md = hc->md; 806 807 new_map = hc->new_map; 808 hc->new_map = NULL; 809 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 810 811 up_write(&_hash_lock); 812 813 /* Do we need to load a new map ? */ 814 if (new_map) { 815 /* Suspend if it isn't already suspended */ 816 if (param->flags & DM_SKIP_LOCKFS_FLAG) 817 do_lockfs = 0; 818 if (!dm_suspended(md)) 819 dm_suspend(md, do_lockfs); 820 821 r = dm_swap_table(md, new_map); 822 if (r) { 823 dm_put(md); 824 dm_table_put(new_map); 825 return r; 826 } 827 828 if (dm_table_get_mode(new_map) & FMODE_WRITE) 829 set_disk_ro(dm_disk(md), 0); 830 else 831 set_disk_ro(dm_disk(md), 1); 832 833 dm_table_put(new_map); 834 } 835 836 if (dm_suspended(md)) 837 r = dm_resume(md); 838 839 if (!r) 840 r = __dev_status(md, param); 841 842 dm_put(md); 843 return r; 844 } 845 846 /* 847 * Set or unset the suspension state of a device. 848 * If the device already is in the requested state we just return its status. 849 */ 850 static int dev_suspend(struct dm_ioctl *param, size_t param_size) 851 { 852 if (param->flags & DM_SUSPEND_FLAG) 853 return do_suspend(param); 854 855 return do_resume(param); 856 } 857 858 /* 859 * Copies device info back to user space, used by 860 * the create and info ioctls. 861 */ 862 static int dev_status(struct dm_ioctl *param, size_t param_size) 863 { 864 int r; 865 struct mapped_device *md; 866 867 md = find_device(param); 868 if (!md) 869 return -ENXIO; 870 871 r = __dev_status(md, param); 872 dm_put(md); 873 return r; 874 } 875 876 /* 877 * Build up the status struct for each target 878 */ 879 static void retrieve_status(struct dm_table *table, 880 struct dm_ioctl *param, size_t param_size) 881 { 882 unsigned int i, num_targets; 883 struct dm_target_spec *spec; 884 char *outbuf, *outptr; 885 status_type_t type; 886 size_t remaining, len, used = 0; 887 888 outptr = outbuf = get_result_buffer(param, param_size, &len); 889 890 if (param->flags & DM_STATUS_TABLE_FLAG) 891 type = STATUSTYPE_TABLE; 892 else 893 type = STATUSTYPE_INFO; 894 895 /* Get all the target info */ 896 num_targets = dm_table_get_num_targets(table); 897 for (i = 0; i < num_targets; i++) { 898 struct dm_target *ti = dm_table_get_target(table, i); 899 900 remaining = len - (outptr - outbuf); 901 if (remaining <= sizeof(struct dm_target_spec)) { 902 param->flags |= DM_BUFFER_FULL_FLAG; 903 break; 904 } 905 906 spec = (struct dm_target_spec *) outptr; 907 908 spec->status = 0; 909 spec->sector_start = ti->begin; 910 spec->length = ti->len; 911 strncpy(spec->target_type, ti->type->name, 912 sizeof(spec->target_type)); 913 914 outptr += sizeof(struct dm_target_spec); 915 remaining = len - (outptr - outbuf); 916 if (remaining <= 0) { 917 param->flags |= DM_BUFFER_FULL_FLAG; 918 break; 919 } 920 921 /* Get the status/table string from the target driver */ 922 if (ti->type->status) { 923 if (ti->type->status(ti, type, outptr, remaining)) { 924 param->flags |= DM_BUFFER_FULL_FLAG; 925 break; 926 } 927 } else 928 outptr[0] = '\0'; 929 930 outptr += strlen(outptr) + 1; 931 used = param->data_start + (outptr - outbuf); 932 933 outptr = align_ptr(outptr); 934 spec->next = outptr - outbuf; 935 } 936 937 if (used) 938 param->data_size = used; 939 940 param->target_count = num_targets; 941 } 942 943 /* 944 * Wait for a device to report an event 945 */ 946 static int dev_wait(struct dm_ioctl *param, size_t param_size) 947 { 948 int r; 949 struct mapped_device *md; 950 struct dm_table *table; 951 952 md = find_device(param); 953 if (!md) 954 return -ENXIO; 955 956 /* 957 * Wait for a notification event 958 */ 959 if (dm_wait_event(md, param->event_nr)) { 960 r = -ERESTARTSYS; 961 goto out; 962 } 963 964 /* 965 * The userland program is going to want to know what 966 * changed to trigger the event, so we may as well tell 967 * him and save an ioctl. 968 */ 969 r = __dev_status(md, param); 970 if (r) 971 goto out; 972 973 table = dm_get_table(md); 974 if (table) { 975 retrieve_status(table, param, param_size); 976 dm_table_put(table); 977 } 978 979 out: 980 dm_put(md); 981 return r; 982 } 983 984 static inline int get_mode(struct dm_ioctl *param) 985 { 986 int mode = FMODE_READ | FMODE_WRITE; 987 988 if (param->flags & DM_READONLY_FLAG) 989 mode = FMODE_READ; 990 991 return mode; 992 } 993 994 static int next_target(struct dm_target_spec *last, uint32_t next, void *end, 995 struct dm_target_spec **spec, char **target_params) 996 { 997 *spec = (struct dm_target_spec *) ((unsigned char *) last + next); 998 *target_params = (char *) (*spec + 1); 999 1000 if (*spec < (last + 1)) 1001 return -EINVAL; 1002 1003 return invalid_str(*target_params, end); 1004 } 1005 1006 static int populate_table(struct dm_table *table, 1007 struct dm_ioctl *param, size_t param_size) 1008 { 1009 int r; 1010 unsigned int i = 0; 1011 struct dm_target_spec *spec = (struct dm_target_spec *) param; 1012 uint32_t next = param->data_start; 1013 void *end = (void *) param + param_size; 1014 char *target_params; 1015 1016 if (!param->target_count) { 1017 DMWARN("populate_table: no targets specified"); 1018 return -EINVAL; 1019 } 1020 1021 for (i = 0; i < param->target_count; i++) { 1022 1023 r = next_target(spec, next, end, &spec, &target_params); 1024 if (r) { 1025 DMWARN("unable to find target"); 1026 return r; 1027 } 1028 1029 r = dm_table_add_target(table, spec->target_type, 1030 (sector_t) spec->sector_start, 1031 (sector_t) spec->length, 1032 target_params); 1033 if (r) { 1034 DMWARN("error adding target to table"); 1035 return r; 1036 } 1037 1038 next = spec->next; 1039 } 1040 1041 return dm_table_complete(table); 1042 } 1043 1044 static int table_load(struct dm_ioctl *param, size_t param_size) 1045 { 1046 int r; 1047 struct hash_cell *hc; 1048 struct dm_table *t; 1049 struct mapped_device *md; 1050 1051 md = find_device(param); 1052 if (!md) 1053 return -ENXIO; 1054 1055 r = dm_table_create(&t, get_mode(param), param->target_count, md); 1056 if (r) 1057 goto out; 1058 1059 r = populate_table(t, param, param_size); 1060 if (r) { 1061 dm_table_put(t); 1062 goto out; 1063 } 1064 1065 down_write(&_hash_lock); 1066 hc = dm_get_mdptr(md); 1067 if (!hc || hc->md != md) { 1068 DMWARN("device has been removed from the dev hash table."); 1069 dm_table_put(t); 1070 up_write(&_hash_lock); 1071 r = -ENXIO; 1072 goto out; 1073 } 1074 1075 if (hc->new_map) 1076 dm_table_put(hc->new_map); 1077 hc->new_map = t; 1078 up_write(&_hash_lock); 1079 1080 param->flags |= DM_INACTIVE_PRESENT_FLAG; 1081 r = __dev_status(md, param); 1082 1083 out: 1084 dm_put(md); 1085 1086 return r; 1087 } 1088 1089 static int table_clear(struct dm_ioctl *param, size_t param_size) 1090 { 1091 int r; 1092 struct hash_cell *hc; 1093 struct mapped_device *md; 1094 1095 down_write(&_hash_lock); 1096 1097 hc = __find_device_hash_cell(param); 1098 if (!hc) { 1099 DMWARN("device doesn't appear to be in the dev hash table."); 1100 up_write(&_hash_lock); 1101 return -ENXIO; 1102 } 1103 1104 if (hc->new_map) { 1105 dm_table_put(hc->new_map); 1106 hc->new_map = NULL; 1107 } 1108 1109 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 1110 1111 r = __dev_status(hc->md, param); 1112 md = hc->md; 1113 up_write(&_hash_lock); 1114 dm_put(md); 1115 return r; 1116 } 1117 1118 /* 1119 * Retrieves a list of devices used by a particular dm device. 1120 */ 1121 static void retrieve_deps(struct dm_table *table, 1122 struct dm_ioctl *param, size_t param_size) 1123 { 1124 unsigned int count = 0; 1125 struct list_head *tmp; 1126 size_t len, needed; 1127 struct dm_dev *dd; 1128 struct dm_target_deps *deps; 1129 1130 deps = get_result_buffer(param, param_size, &len); 1131 1132 /* 1133 * Count the devices. 1134 */ 1135 list_for_each (tmp, dm_table_get_devices(table)) 1136 count++; 1137 1138 /* 1139 * Check we have enough space. 1140 */ 1141 needed = sizeof(*deps) + (sizeof(*deps->dev) * count); 1142 if (len < needed) { 1143 param->flags |= DM_BUFFER_FULL_FLAG; 1144 return; 1145 } 1146 1147 /* 1148 * Fill in the devices. 1149 */ 1150 deps->count = count; 1151 count = 0; 1152 list_for_each_entry (dd, dm_table_get_devices(table), list) 1153 deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev); 1154 1155 param->data_size = param->data_start + needed; 1156 } 1157 1158 static int table_deps(struct dm_ioctl *param, size_t param_size) 1159 { 1160 int r = 0; 1161 struct mapped_device *md; 1162 struct dm_table *table; 1163 1164 md = find_device(param); 1165 if (!md) 1166 return -ENXIO; 1167 1168 r = __dev_status(md, param); 1169 if (r) 1170 goto out; 1171 1172 table = dm_get_table(md); 1173 if (table) { 1174 retrieve_deps(table, param, param_size); 1175 dm_table_put(table); 1176 } 1177 1178 out: 1179 dm_put(md); 1180 return r; 1181 } 1182 1183 /* 1184 * Return the status of a device as a text string for each 1185 * target. 1186 */ 1187 static int table_status(struct dm_ioctl *param, size_t param_size) 1188 { 1189 int r; 1190 struct mapped_device *md; 1191 struct dm_table *table; 1192 1193 md = find_device(param); 1194 if (!md) 1195 return -ENXIO; 1196 1197 r = __dev_status(md, param); 1198 if (r) 1199 goto out; 1200 1201 table = dm_get_table(md); 1202 if (table) { 1203 retrieve_status(table, param, param_size); 1204 dm_table_put(table); 1205 } 1206 1207 out: 1208 dm_put(md); 1209 return r; 1210 } 1211 1212 /* 1213 * Pass a message to the target that's at the supplied device offset. 1214 */ 1215 static int target_message(struct dm_ioctl *param, size_t param_size) 1216 { 1217 int r, argc; 1218 char **argv; 1219 struct mapped_device *md; 1220 struct dm_table *table; 1221 struct dm_target *ti; 1222 struct dm_target_msg *tmsg = (void *) param + param->data_start; 1223 1224 md = find_device(param); 1225 if (!md) 1226 return -ENXIO; 1227 1228 r = __dev_status(md, param); 1229 if (r) 1230 goto out; 1231 1232 if (tmsg < (struct dm_target_msg *) (param + 1) || 1233 invalid_str(tmsg->message, (void *) param + param_size)) { 1234 DMWARN("Invalid target message parameters."); 1235 r = -EINVAL; 1236 goto out; 1237 } 1238 1239 r = dm_split_args(&argc, &argv, tmsg->message); 1240 if (r) { 1241 DMWARN("Failed to split target message parameters"); 1242 goto out; 1243 } 1244 1245 table = dm_get_table(md); 1246 if (!table) 1247 goto out_argv; 1248 1249 if (tmsg->sector >= dm_table_get_size(table)) { 1250 DMWARN("Target message sector outside device."); 1251 r = -EINVAL; 1252 goto out_table; 1253 } 1254 1255 ti = dm_table_find_target(table, tmsg->sector); 1256 if (ti->type->message) 1257 r = ti->type->message(ti, argc, argv); 1258 else { 1259 DMWARN("Target type does not support messages"); 1260 r = -EINVAL; 1261 } 1262 1263 out_table: 1264 dm_table_put(table); 1265 out_argv: 1266 kfree(argv); 1267 out: 1268 param->data_size = 0; 1269 dm_put(md); 1270 return r; 1271 } 1272 1273 /*----------------------------------------------------------------- 1274 * Implementation of open/close/ioctl on the special char 1275 * device. 1276 *---------------------------------------------------------------*/ 1277 static ioctl_fn lookup_ioctl(unsigned int cmd) 1278 { 1279 static struct { 1280 int cmd; 1281 ioctl_fn fn; 1282 } _ioctls[] = { 1283 {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ 1284 {DM_REMOVE_ALL_CMD, remove_all}, 1285 {DM_LIST_DEVICES_CMD, list_devices}, 1286 1287 {DM_DEV_CREATE_CMD, dev_create}, 1288 {DM_DEV_REMOVE_CMD, dev_remove}, 1289 {DM_DEV_RENAME_CMD, dev_rename}, 1290 {DM_DEV_SUSPEND_CMD, dev_suspend}, 1291 {DM_DEV_STATUS_CMD, dev_status}, 1292 {DM_DEV_WAIT_CMD, dev_wait}, 1293 1294 {DM_TABLE_LOAD_CMD, table_load}, 1295 {DM_TABLE_CLEAR_CMD, table_clear}, 1296 {DM_TABLE_DEPS_CMD, table_deps}, 1297 {DM_TABLE_STATUS_CMD, table_status}, 1298 1299 {DM_LIST_VERSIONS_CMD, list_versions}, 1300 1301 {DM_TARGET_MSG_CMD, target_message}, 1302 {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry} 1303 }; 1304 1305 return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; 1306 } 1307 1308 /* 1309 * As well as checking the version compatibility this always 1310 * copies the kernel interface version out. 1311 */ 1312 static int check_version(unsigned int cmd, struct dm_ioctl __user *user) 1313 { 1314 uint32_t version[3]; 1315 int r = 0; 1316 1317 if (copy_from_user(version, user->version, sizeof(version))) 1318 return -EFAULT; 1319 1320 if ((DM_VERSION_MAJOR != version[0]) || 1321 (DM_VERSION_MINOR < version[1])) { 1322 DMWARN("ioctl interface mismatch: " 1323 "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)", 1324 DM_VERSION_MAJOR, DM_VERSION_MINOR, 1325 DM_VERSION_PATCHLEVEL, 1326 version[0], version[1], version[2], cmd); 1327 r = -EINVAL; 1328 } 1329 1330 /* 1331 * Fill in the kernel version. 1332 */ 1333 version[0] = DM_VERSION_MAJOR; 1334 version[1] = DM_VERSION_MINOR; 1335 version[2] = DM_VERSION_PATCHLEVEL; 1336 if (copy_to_user(user->version, version, sizeof(version))) 1337 return -EFAULT; 1338 1339 return r; 1340 } 1341 1342 static void free_params(struct dm_ioctl *param) 1343 { 1344 vfree(param); 1345 } 1346 1347 static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param) 1348 { 1349 struct dm_ioctl tmp, *dmi; 1350 1351 if (copy_from_user(&tmp, user, sizeof(tmp))) 1352 return -EFAULT; 1353 1354 if (tmp.data_size < sizeof(tmp)) 1355 return -EINVAL; 1356 1357 dmi = (struct dm_ioctl *) vmalloc(tmp.data_size); 1358 if (!dmi) 1359 return -ENOMEM; 1360 1361 if (copy_from_user(dmi, user, tmp.data_size)) { 1362 vfree(dmi); 1363 return -EFAULT; 1364 } 1365 1366 *param = dmi; 1367 return 0; 1368 } 1369 1370 static int validate_params(uint cmd, struct dm_ioctl *param) 1371 { 1372 /* Always clear this flag */ 1373 param->flags &= ~DM_BUFFER_FULL_FLAG; 1374 1375 /* Ignores parameters */ 1376 if (cmd == DM_REMOVE_ALL_CMD || 1377 cmd == DM_LIST_DEVICES_CMD || 1378 cmd == DM_LIST_VERSIONS_CMD) 1379 return 0; 1380 1381 if ((cmd == DM_DEV_CREATE_CMD)) { 1382 if (!*param->name) { 1383 DMWARN("name not supplied when creating device"); 1384 return -EINVAL; 1385 } 1386 } else if ((*param->uuid && *param->name)) { 1387 DMWARN("only supply one of name or uuid, cmd(%u)", cmd); 1388 return -EINVAL; 1389 } 1390 1391 /* Ensure strings are terminated */ 1392 param->name[DM_NAME_LEN - 1] = '\0'; 1393 param->uuid[DM_UUID_LEN - 1] = '\0'; 1394 1395 return 0; 1396 } 1397 1398 static int ctl_ioctl(struct inode *inode, struct file *file, 1399 uint command, ulong u) 1400 { 1401 int r = 0; 1402 unsigned int cmd; 1403 struct dm_ioctl *param; 1404 struct dm_ioctl __user *user = (struct dm_ioctl __user *) u; 1405 ioctl_fn fn = NULL; 1406 size_t param_size; 1407 1408 /* only root can play with this */ 1409 if (!capable(CAP_SYS_ADMIN)) 1410 return -EACCES; 1411 1412 if (_IOC_TYPE(command) != DM_IOCTL) 1413 return -ENOTTY; 1414 1415 cmd = _IOC_NR(command); 1416 1417 /* 1418 * Check the interface version passed in. This also 1419 * writes out the kernel's interface version. 1420 */ 1421 r = check_version(cmd, user); 1422 if (r) 1423 return r; 1424 1425 /* 1426 * Nothing more to do for the version command. 1427 */ 1428 if (cmd == DM_VERSION_CMD) 1429 return 0; 1430 1431 fn = lookup_ioctl(cmd); 1432 if (!fn) { 1433 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); 1434 return -ENOTTY; 1435 } 1436 1437 /* 1438 * Trying to avoid low memory issues when a device is 1439 * suspended. 1440 */ 1441 current->flags |= PF_MEMALLOC; 1442 1443 /* 1444 * Copy the parameters into kernel space. 1445 */ 1446 r = copy_params(user, ¶m); 1447 1448 current->flags &= ~PF_MEMALLOC; 1449 1450 if (r) 1451 return r; 1452 1453 r = validate_params(cmd, param); 1454 if (r) 1455 goto out; 1456 1457 param_size = param->data_size; 1458 param->data_size = sizeof(*param); 1459 r = fn(param, param_size); 1460 1461 /* 1462 * Copy the results back to userland. 1463 */ 1464 if (!r && copy_to_user(user, param, param->data_size)) 1465 r = -EFAULT; 1466 1467 out: 1468 free_params(param); 1469 return r; 1470 } 1471 1472 static struct file_operations _ctl_fops = { 1473 .ioctl = ctl_ioctl, 1474 .owner = THIS_MODULE, 1475 }; 1476 1477 static struct miscdevice _dm_misc = { 1478 .minor = MISC_DYNAMIC_MINOR, 1479 .name = DM_NAME, 1480 .fops = &_ctl_fops 1481 }; 1482 1483 /* 1484 * Create misc character device and link to DM_DIR/control. 1485 */ 1486 int __init dm_interface_init(void) 1487 { 1488 int r; 1489 1490 r = dm_hash_init(); 1491 if (r) 1492 return r; 1493 1494 r = misc_register(&_dm_misc); 1495 if (r) { 1496 DMERR("misc_register failed for control device"); 1497 dm_hash_exit(); 1498 return r; 1499 } 1500 1501 DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR, 1502 DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA, 1503 DM_DRIVER_EMAIL); 1504 return 0; 1505 } 1506 1507 void dm_interface_exit(void) 1508 { 1509 if (misc_deregister(&_dm_misc) < 0) 1510 DMERR("misc_deregister failed for control device"); 1511 1512 dm_hash_exit(); 1513 } 1514