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