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