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