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
  39/*
  40 * A dummy definition to make RCU happy.
  41 * struct dm_table should never be dereferenced in this file.
  42 */
  43struct dm_table {
  44        int undefined__;
  45};
  46
  47struct vers_iter {
  48    size_t param_size;
  49    struct dm_target_versions *vers, *old_vers;
  50    char *end;
  51    uint32_t flags;
  52};
  53
  54
  55#define NUM_BUCKETS 64
  56#define MASK_BUCKETS (NUM_BUCKETS - 1)
  57static struct list_head _name_buckets[NUM_BUCKETS];
  58static struct list_head _uuid_buckets[NUM_BUCKETS];
  59
  60static void dm_hash_remove_all(int keep_open_devices);
  61
  62/*
  63 * Guards access to both hash tables.
  64 */
  65static DECLARE_RWSEM(_hash_lock);
  66
  67/*
  68 * Protects use of mdptr to obtain hash cell name and uuid from mapped device.
  69 */
  70static DEFINE_MUTEX(dm_hash_cells_mutex);
  71
  72static void init_buckets(struct list_head *buckets)
  73{
  74        unsigned int i;
  75
  76        for (i = 0; i < NUM_BUCKETS; i++)
  77                INIT_LIST_HEAD(buckets + i);
  78}
  79
  80static int dm_hash_init(void)
  81{
  82        init_buckets(_name_buckets);
  83        init_buckets(_uuid_buckets);
  84        return 0;
  85}
  86
  87static void dm_hash_exit(void)
  88{
  89        dm_hash_remove_all(0);
  90}
  91
  92/*-----------------------------------------------------------------
  93 * Hash function:
  94 * We're not really concerned with the str hash function being
  95 * fast since it's only used by the ioctl interface.
  96 *---------------------------------------------------------------*/
  97static unsigned int hash_str(const char *str)
  98{
  99        const unsigned int hash_mult = 2654435387U;
 100        unsigned int h = 0;
 101
 102        while (*str)
 103                h = (h + (unsigned int) *str++) * hash_mult;
 104
 105        return h & MASK_BUCKETS;
 106}
 107
 108/*-----------------------------------------------------------------
 109 * Code for looking up a device by name
 110 *---------------------------------------------------------------*/
 111static struct hash_cell *__get_name_cell(const char *str)
 112{
 113        struct hash_cell *hc;
 114        unsigned int h = hash_str(str);
 115
 116        list_for_each_entry (hc, _name_buckets + h, name_list)
 117                if (!strcmp(hc->name, str)) {
 118                        dm_get(hc->md);
 119                        return hc;
 120                }
 121
 122        return NULL;
 123}
 124
 125static struct hash_cell *__get_uuid_cell(const char *str)
 126{
 127        struct hash_cell *hc;
 128        unsigned int h = hash_str(str);
 129
 130        list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
 131                if (!strcmp(hc->uuid, str)) {
 132                        dm_get(hc->md);
 133                        return hc;
 134                }
 135
 136        return NULL;
 137}
 138
 139static struct hash_cell *__get_dev_cell(uint64_t dev)
 140{
 141        struct mapped_device *md;
 142        struct hash_cell *hc;
 143
 144        md = dm_get_md(huge_decode_dev(dev));
 145        if (!md)
 146                return NULL;
 147
 148        hc = dm_get_mdptr(md);
 149        if (!hc) {
 150                dm_put(md);
 151                return NULL;
 152        }
 153
 154        return hc;
 155}
 156
 157/*-----------------------------------------------------------------
 158 * Inserting, removing and renaming a device.
 159 *---------------------------------------------------------------*/
 160static struct hash_cell *alloc_cell(const char *name, const char *uuid,
 161                                    struct mapped_device *md)
 162{
 163        struct hash_cell *hc;
 164
 165        hc = kmalloc(sizeof(*hc), GFP_KERNEL);
 166        if (!hc)
 167                return NULL;
 168
 169        hc->name = kstrdup(name, GFP_KERNEL);
 170        if (!hc->name) {
 171                kfree(hc);
 172                return NULL;
 173        }
 174
 175        if (!uuid)
 176                hc->uuid = NULL;
 177
 178        else {
 179                hc->uuid = kstrdup(uuid, GFP_KERNEL);
 180                if (!hc->uuid) {
 181                        kfree(hc->name);
 182                        kfree(hc);
 183                        return NULL;
 184                }
 185        }
 186
 187        INIT_LIST_HEAD(&hc->name_list);
 188        INIT_LIST_HEAD(&hc->uuid_list);
 189        hc->md = md;
 190        hc->new_map = NULL;
 191        return hc;
 192}
 193
 194static void free_cell(struct hash_cell *hc)
 195{
 196        if (hc) {
 197                kfree(hc->name);
 198                kfree(hc->uuid);
 199                kfree(hc);
 200        }
 201}
 202
 203/*
 204 * The kdev_t and uuid of a device can never change once it is
 205 * initially inserted.
 206 */
 207static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md)
 208{
 209        struct hash_cell *cell, *hc;
 210
 211        /*
 212         * Allocate the new cells.
 213         */
 214        cell = alloc_cell(name, uuid, md);
 215        if (!cell)
 216                return -ENOMEM;
 217
 218        /*
 219         * Insert the cell into both hash tables.
 220         */
 221        down_write(&_hash_lock);
 222        hc = __get_name_cell(name);
 223        if (hc) {
 224                dm_put(hc->md);
 225                goto bad;
 226        }
 227
 228        list_add(&cell->name_list, _name_buckets + hash_str(name));
 229
 230        if (uuid) {
 231                hc = __get_uuid_cell(uuid);
 232                if (hc) {
 233                        list_del(&cell->name_list);
 234                        dm_put(hc->md);
 235                        goto bad;
 236                }
 237                list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
 238        }
 239        dm_get(md);
 240        mutex_lock(&dm_hash_cells_mutex);
 241        dm_set_mdptr(md, cell);
 242        mutex_unlock(&dm_hash_cells_mutex);
 243        up_write(&_hash_lock);
 244
 245        return 0;
 246
 247 bad:
 248        up_write(&_hash_lock);
 249        free_cell(cell);
 250        return -EBUSY;
 251}
 252
 253static struct dm_table *__hash_remove(struct hash_cell *hc)
 254{
 255        struct dm_table *table;
 256        int srcu_idx;
 257
 258        /* remove from the dev hash */
 259        list_del(&hc->uuid_list);
 260        list_del(&hc->name_list);
 261        mutex_lock(&dm_hash_cells_mutex);
 262        dm_set_mdptr(hc->md, NULL);
 263        mutex_unlock(&dm_hash_cells_mutex);
 264
 265        table = dm_get_live_table(hc->md, &srcu_idx);
 266        if (table)
 267                dm_table_event(table);
 268        dm_put_live_table(hc->md, srcu_idx);
 269
 270        table = NULL;
 271        if (hc->new_map)
 272                table = hc->new_map;
 273        dm_put(hc->md);
 274        free_cell(hc);
 275
 276        return table;
 277}
 278
 279static void dm_hash_remove_all(int keep_open_devices)
 280{
 281        int i, dev_skipped;
 282        struct hash_cell *hc;
 283        struct mapped_device *md;
 284        struct dm_table *t;
 285
 286retry:
 287        dev_skipped = 0;
 288
 289        down_write(&_hash_lock);
 290
 291        for (i = 0; i < NUM_BUCKETS; i++) {
 292                list_for_each_entry(hc, _name_buckets + i, name_list) {
 293                        md = hc->md;
 294                        dm_get(md);
 295
 296                        if (keep_open_devices && dm_lock_for_deletion(md)) {
 297                                dm_put(md);
 298                                dev_skipped++;
 299                                continue;
 300                        }
 301
 302                        t = __hash_remove(hc);
 303
 304                        up_write(&_hash_lock);
 305
 306                        if (t) {
 307                                dm_sync_table(md);
 308                                dm_table_destroy(t);
 309                        }
 310                        dm_put(md);
 311                        if (likely(keep_open_devices))
 312                                dm_destroy(md);
 313                        else
 314                                dm_destroy_immediate(md);
 315
 316                        /*
 317                         * Some mapped devices may be using other mapped
 318                         * devices, so repeat until we make no further
 319                         * progress.  If a new mapped device is created
 320                         * here it will also get removed.
 321                         */
 322                        goto retry;
 323                }
 324        }
 325
 326        up_write(&_hash_lock);
 327
 328        if (dev_skipped)
 329                DMWARN("remove_all left %d open device(s)", dev_skipped);
 330}
 331
 332/*
 333 * Set the uuid of a hash_cell that isn't already set.
 334 */
 335static void __set_cell_uuid(struct hash_cell *hc, char *new_uuid)
 336{
 337        mutex_lock(&dm_hash_cells_mutex);
 338        hc->uuid = new_uuid;
 339        mutex_unlock(&dm_hash_cells_mutex);
 340
 341        list_add(&hc->uuid_list, _uuid_buckets + hash_str(new_uuid));
 342}
 343
 344/*
 345 * Changes the name of a hash_cell and returns the old name for
 346 * the caller to free.
 347 */
 348static char *__change_cell_name(struct hash_cell *hc, char *new_name)
 349{
 350        char *old_name;
 351
 352        /*
 353         * Rename and move the name cell.
 354         */
 355        list_del(&hc->name_list);
 356        old_name = hc->name;
 357
 358        mutex_lock(&dm_hash_cells_mutex);
 359        hc->name = new_name;
 360        mutex_unlock(&dm_hash_cells_mutex);
 361
 362        list_add(&hc->name_list, _name_buckets + hash_str(new_name));
 363
 364        return old_name;
 365}
 366
 367static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,
 368                                            const char *new)
 369{
 370        char *new_data, *old_name = NULL;
 371        struct hash_cell *hc;
 372        struct dm_table *table;
 373        struct mapped_device *md;
 374        unsigned change_uuid = (param->flags & DM_UUID_FLAG) ? 1 : 0;
 375        int srcu_idx;
 376
 377        /*
 378         * duplicate new.
 379         */
 380        new_data = kstrdup(new, GFP_KERNEL);
 381        if (!new_data)
 382                return ERR_PTR(-ENOMEM);
 383
 384        down_write(&_hash_lock);
 385
 386        /*
 387         * Is new free ?
 388         */
 389        if (change_uuid)
 390                hc = __get_uuid_cell(new);
 391        else
 392                hc = __get_name_cell(new);
 393
 394        if (hc) {
 395                DMWARN("Unable to change %s on mapped device %s to one that "
 396                       "already exists: %s",
 397                       change_uuid ? "uuid" : "name",
 398                       param->name, new);
 399                dm_put(hc->md);
 400                up_write(&_hash_lock);
 401                kfree(new_data);
 402                return ERR_PTR(-EBUSY);
 403        }
 404
 405        /*
 406         * Is there such a device as 'old' ?
 407         */
 408        hc = __get_name_cell(param->name);
 409        if (!hc) {
 410                DMWARN("Unable to rename non-existent device, %s to %s%s",
 411                       param->name, change_uuid ? "uuid " : "", new);
 412                up_write(&_hash_lock);
 413                kfree(new_data);
 414                return ERR_PTR(-ENXIO);
 415        }
 416
 417        /*
 418         * Does this device already have a uuid?
 419         */
 420        if (change_uuid && hc->uuid) {
 421                DMWARN("Unable to change uuid of mapped device %s to %s "
 422                       "because uuid is already set to %s",
 423                       param->name, new, hc->uuid);
 424                dm_put(hc->md);
 425                up_write(&_hash_lock);
 426                kfree(new_data);
 427                return ERR_PTR(-EINVAL);
 428        }
 429
 430        if (change_uuid)
 431                __set_cell_uuid(hc, new_data);
 432        else
 433                old_name = __change_cell_name(hc, new_data);
 434
 435        /*
 436         * Wake up any dm event waiters.
 437         */
 438        table = dm_get_live_table(hc->md, &srcu_idx);
 439        if (table)
 440                dm_table_event(table);
 441        dm_put_live_table(hc->md, srcu_idx);
 442
 443        if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, param->event_nr))
 444                param->flags |= DM_UEVENT_GENERATED_FLAG;
 445
 446        md = hc->md;
 447        up_write(&_hash_lock);
 448        kfree(old_name);
 449
 450        return md;
 451}
 452
 453/*-----------------------------------------------------------------
 454 * Implementation of the ioctl commands
 455 *---------------------------------------------------------------*/
 456/*
 457 * All the ioctl commands get dispatched to functions with this
 458 * prototype.
 459 */
 460typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size);
 461
 462static int remove_all(struct dm_ioctl *param, size_t param_size)
 463{
 464        dm_hash_remove_all(1);
 465        param->data_size = 0;
 466        return 0;
 467}
 468
 469/*
 470 * Round up the ptr to an 8-byte boundary.
 471 */
 472#define ALIGN_MASK 7
 473static inline void *align_ptr(void *ptr)
 474{
 475        return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK);
 476}
 477
 478/*
 479 * Retrieves the data payload buffer from an already allocated
 480 * struct dm_ioctl.
 481 */
 482static void *get_result_buffer(struct dm_ioctl *param, size_t param_size,
 483                               size_t *len)
 484{
 485        param->data_start = align_ptr(param + 1) - (void *) param;
 486
 487        if (param->data_start < param_size)
 488                *len = param_size - param->data_start;
 489        else
 490                *len = 0;
 491
 492        return ((void *) param) + param->data_start;
 493}
 494
 495static int list_devices(struct dm_ioctl *param, size_t param_size)
 496{
 497        unsigned int i;
 498        struct hash_cell *hc;
 499        size_t len, needed = 0;
 500        struct gendisk *disk;
 501        struct dm_name_list *nl, *old_nl = NULL;
 502
 503        down_write(&_hash_lock);
 504
 505        /*
 506         * Loop through all the devices working out how much
 507         * space we need.
 508         */
 509        for (i = 0; i < NUM_BUCKETS; i++) {
 510                list_for_each_entry (hc, _name_buckets + i, name_list) {
 511                        needed += sizeof(struct dm_name_list);
 512                        needed += strlen(hc->name) + 1;
 513                        needed += ALIGN_MASK;
 514                }
 515        }
 516
 517        /*
 518         * Grab our output buffer.
 519         */
 520        nl = get_result_buffer(param, param_size, &len);
 521        if (len < needed) {
 522                param->flags |= DM_BUFFER_FULL_FLAG;
 523                goto out;
 524        }
 525        param->data_size = param->data_start + needed;
 526
 527        nl->dev = 0;    /* Flags no data */
 528
 529        /*
 530         * Now loop through filling out the names.
 531         */
 532        for (i = 0; i < NUM_BUCKETS; i++) {
 533                list_for_each_entry (hc, _name_buckets + i, name_list) {
 534                        if (old_nl)
 535                                old_nl->next = (uint32_t) ((void *) nl -
 536                                                           (void *) old_nl);
 537                        disk = dm_disk(hc->md);
 538                        nl->dev = huge_encode_dev(disk_devt(disk));
 539                        nl->next = 0;
 540                        strcpy(nl->name, hc->name);
 541
 542                        old_nl = nl;
 543                        nl = align_ptr(((void *) ++nl) + strlen(hc->name) + 1);
 544                }
 545        }
 546
 547 out:
 548        up_write(&_hash_lock);
 549        return 0;
 550}
 551
 552static void list_version_get_needed(struct target_type *tt, void *needed_param)
 553{
 554    size_t *needed = needed_param;
 555
 556    *needed += sizeof(struct dm_target_versions);
 557    *needed += strlen(tt->name);
 558    *needed += ALIGN_MASK;
 559}
 560
 561static void list_version_get_info(struct target_type *tt, void *param)
 562{
 563    struct vers_iter *info = param;
 564
 565    /* Check space - it might have changed since the first iteration */
 566    if ((char *)info->vers + sizeof(tt->version) + strlen(tt->name) + 1 >
 567        info->end) {
 568
 569        info->flags = DM_BUFFER_FULL_FLAG;
 570        return;
 571    }
 572
 573    if (info->old_vers)
 574        info->old_vers->next = (uint32_t) ((void *)info->vers -
 575                                           (void *)info->old_vers);
 576    info->vers->version[0] = tt->version[0];
 577    info->vers->version[1] = tt->version[1];
 578    info->vers->version[2] = tt->version[2];
 579    info->vers->next = 0;
 580    strcpy(info->vers->name, tt->name);
 581
 582    info->old_vers = info->vers;
 583    info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1);
 584}
 585
 586static int list_versions(struct dm_ioctl *param, size_t param_size)
 587{
 588        size_t len, needed = 0;
 589        struct dm_target_versions *vers;
 590        struct vers_iter iter_info;
 591
 592        /*
 593         * Loop through all the devices working out how much
 594         * space we need.
 595         */
 596        dm_target_iterate(list_version_get_needed, &needed);
 597
 598        /*
 599         * Grab our output buffer.
 600         */
 601        vers = get_result_buffer(param, param_size, &len);
 602        if (len < needed) {
 603                param->flags |= DM_BUFFER_FULL_FLAG;
 604                goto out;
 605        }
 606        param->data_size = param->data_start + needed;
 607
 608        iter_info.param_size = param_size;
 609        iter_info.old_vers = NULL;
 610        iter_info.vers = vers;
 611        iter_info.flags = 0;
 612        iter_info.end = (char *)vers+len;
 613
 614        /*
 615         * Now loop through filling out the names & versions.
 616         */
 617        dm_target_iterate(list_version_get_info, &iter_info);
 618        param->flags |= iter_info.flags;
 619
 620 out:
 621        return 0;
 622}
 623
 624static int check_name(const char *name)
 625{
 626        if (strchr(name, '/')) {
 627                DMWARN("invalid device name");
 628                return -EINVAL;
 629        }
 630
 631        return 0;
 632}
 633
 634/*
 635 * On successful return, the caller must not attempt to acquire
 636 * _hash_lock without first calling dm_table_put, because dm_table_destroy
 637 * waits for this dm_table_put and could be called under this lock.
 638 */
 639static struct dm_table *dm_get_inactive_table(struct mapped_device *md, int *srcu_idx)
 640{
 641        struct hash_cell *hc;
 642        struct dm_table *table = NULL;
 643
 644        /* increment rcu count, we don't care about the table pointer */
 645        dm_get_live_table(md, srcu_idx);
 646
 647        down_read(&_hash_lock);
 648        hc = dm_get_mdptr(md);
 649        if (!hc || hc->md != md) {
 650                DMWARN("device has been removed from the dev hash table.");
 651                goto out;
 652        }
 653
 654        table = hc->new_map;
 655
 656out:
 657        up_read(&_hash_lock);
 658
 659        return table;
 660}
 661
 662static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md,
 663                                                      struct dm_ioctl *param,
 664                                                      int *srcu_idx)
 665{
 666        return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ?
 667                dm_get_inactive_table(md, srcu_idx) : dm_get_live_table(md, srcu_idx);
 668}
 669
 670/*
 671 * Fills in a dm_ioctl structure, ready for sending back to
 672 * userland.
 673 */
 674static void __dev_status(struct mapped_device *md, struct dm_ioctl *param)
 675{
 676        struct gendisk *disk = dm_disk(md);
 677        struct dm_table *table;
 678        int srcu_idx;
 679
 680        param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG |
 681                          DM_ACTIVE_PRESENT_FLAG);
 682
 683        if (dm_suspended_md(md))
 684                param->flags |= DM_SUSPEND_FLAG;
 685
 686        param->dev = huge_encode_dev(disk_devt(disk));
 687
 688        /*
 689         * Yes, this will be out of date by the time it gets back
 690         * to userland, but it is still very useful for
 691         * debugging.
 692         */
 693        param->open_count = dm_open_count(md);
 694
 695        param->event_nr = dm_get_event_nr(md);
 696        param->target_count = 0;
 697
 698        table = dm_get_live_table(md, &srcu_idx);
 699        if (table) {
 700                if (!(param->flags & DM_QUERY_INACTIVE_TABLE_FLAG)) {
 701                        if (get_disk_ro(disk))
 702                                param->flags |= DM_READONLY_FLAG;
 703                        param->target_count = dm_table_get_num_targets(table);
 704                }
 705
 706                param->flags |= DM_ACTIVE_PRESENT_FLAG;
 707        }
 708        dm_put_live_table(md, srcu_idx);
 709
 710        if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) {
 711                int srcu_idx;
 712                table = dm_get_inactive_table(md, &srcu_idx);
 713                if (table) {
 714                        if (!(dm_table_get_mode(table) & FMODE_WRITE))
 715                                param->flags |= DM_READONLY_FLAG;
 716                        param->target_count = dm_table_get_num_targets(table);
 717                }
 718                dm_put_live_table(md, srcu_idx);
 719        }
 720}
 721
 722static int dev_create(struct dm_ioctl *param, size_t param_size)
 723{
 724        int r, m = DM_ANY_MINOR;
 725        struct mapped_device *md;
 726
 727        r = check_name(param->name);
 728        if (r)
 729                return r;
 730
 731        if (param->flags & DM_PERSISTENT_DEV_FLAG)
 732                m = MINOR(huge_decode_dev(param->dev));
 733
 734        r = dm_create(m, &md);
 735        if (r)
 736                return r;
 737
 738        r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
 739        if (r) {
 740                dm_put(md);
 741                dm_destroy(md);
 742                return r;
 743        }
 744
 745        param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
 746
 747        __dev_status(md, param);
 748
 749        dm_put(md);
 750
 751        return 0;
 752}
 753
 754/*
 755 * Always use UUID for lookups if it's present, otherwise use name or dev.
 756 */
 757static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
 758{
 759        struct hash_cell *hc = NULL;
 760
 761        if (*param->uuid) {
 762                if (*param->name || param->dev)
 763                        return NULL;
 764
 765                hc = __get_uuid_cell(param->uuid);
 766                if (!hc)
 767                        return NULL;
 768        } else if (*param->name) {
 769                if (param->dev)
 770                        return NULL;
 771
 772                hc = __get_name_cell(param->name);
 773                if (!hc)
 774                        return NULL;
 775        } else if (param->dev) {
 776                hc = __get_dev_cell(param->dev);
 777                if (!hc)
 778                        return NULL;
 779        } else
 780                return NULL;
 781
 782        /*
 783         * Sneakily write in both the name and the uuid
 784         * while we have the cell.
 785         */
 786        strlcpy(param->name, hc->name, sizeof(param->name));
 787        if (hc->uuid)
 788                strlcpy(param->uuid, hc->uuid, sizeof(param->uuid));
 789        else
 790                param->uuid[0] = '\0';
 791
 792        if (hc->new_map)
 793                param->flags |= DM_INACTIVE_PRESENT_FLAG;
 794        else
 795                param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
 796
 797        return hc;
 798}
 799
 800static struct mapped_device *find_device(struct dm_ioctl *param)
 801{
 802        struct hash_cell *hc;
 803        struct mapped_device *md = NULL;
 804
 805        down_read(&_hash_lock);
 806        hc = __find_device_hash_cell(param);
 807        if (hc)
 808                md = hc->md;
 809        up_read(&_hash_lock);
 810
 811        return md;
 812}
 813
 814static int dev_remove(struct dm_ioctl *param, size_t param_size)
 815{
 816        struct hash_cell *hc;
 817        struct mapped_device *md;
 818        int r;
 819        struct dm_table *t;
 820
 821        down_write(&_hash_lock);
 822        hc = __find_device_hash_cell(param);
 823
 824        if (!hc) {
 825                DMDEBUG_LIMIT("device doesn't appear to be in the dev hash table.");
 826                up_write(&_hash_lock);
 827                return -ENXIO;
 828        }
 829
 830        md = hc->md;
 831
 832        /*
 833         * Ensure the device is not open and nothing further can open it.
 834         */
 835        r = dm_lock_for_deletion(md);
 836        if (r) {
 837                DMDEBUG_LIMIT("unable to remove open device %s", hc->name);
 838                up_write(&_hash_lock);
 839                dm_put(md);
 840                return r;
 841        }
 842
 843        t = __hash_remove(hc);
 844        up_write(&_hash_lock);
 845
 846        if (t) {
 847                dm_sync_table(md);
 848                dm_table_destroy(t);
 849        }
 850
 851        if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
 852                param->flags |= DM_UEVENT_GENERATED_FLAG;
 853
 854        dm_put(md);
 855        dm_destroy(md);
 856        return 0;
 857}
 858
 859/*
 860 * Check a string doesn't overrun the chunk of
 861 * memory we copied from userland.
 862 */
 863static int invalid_str(char *str, void *end)
 864{
 865        while ((void *) str < end)
 866                if (!*str++)
 867                        return 0;
 868
 869        return -EINVAL;
 870}
 871
 872static int dev_rename(struct dm_ioctl *param, size_t param_size)
 873{
 874        int r;
 875        char *new_data = (char *) param + param->data_start;
 876        struct mapped_device *md;
 877        unsigned change_uuid = (param->flags & DM_UUID_FLAG) ? 1 : 0;
 878
 879        if (new_data < param->data ||
 880            invalid_str(new_data, (void *) param + param_size) ||
 881            strlen(new_data) > (change_uuid ? DM_UUID_LEN - 1 : DM_NAME_LEN - 1)) {
 882                DMWARN("Invalid new mapped device name or uuid string supplied.");
 883                return -EINVAL;
 884        }
 885
 886        if (!change_uuid) {
 887                r = check_name(new_data);
 888                if (r)
 889                        return r;
 890        }
 891
 892        md = dm_hash_rename(param, new_data);
 893        if (IS_ERR(md))
 894                return PTR_ERR(md);
 895
 896        __dev_status(md, param);
 897        dm_put(md);
 898
 899        return 0;
 900}
 901
 902static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
 903{
 904        int r = -EINVAL, x;
 905        struct mapped_device *md;
 906        struct hd_geometry geometry;
 907        unsigned long indata[4];
 908        char *geostr = (char *) param + param->data_start;
 909        char dummy;
 910
 911        md = find_device(param);
 912        if (!md)
 913                return -ENXIO;
 914
 915        if (geostr < param->data ||
 916            invalid_str(geostr, (void *) param + param_size)) {
 917                DMWARN("Invalid geometry supplied.");
 918                goto out;
 919        }
 920
 921        x = sscanf(geostr, "%lu %lu %lu %lu%c", indata,
 922                   indata + 1, indata + 2, indata + 3, &dummy);
 923
 924        if (x != 4) {
 925                DMWARN("Unable to interpret geometry settings.");
 926                goto out;
 927        }
 928
 929        if (indata[0] > 65535 || indata[1] > 255 ||
 930            indata[2] > 255 || indata[3] > ULONG_MAX) {
 931                DMWARN("Geometry exceeds range limits.");
 932                goto out;
 933        }
 934
 935        geometry.cylinders = indata[0];
 936        geometry.heads = indata[1];
 937        geometry.sectors = indata[2];
 938        geometry.start = indata[3];
 939
 940        r = dm_set_geometry(md, &geometry);
 941
 942        param->data_size = 0;
 943
 944out:
 945        dm_put(md);
 946        return r;
 947}
 948
 949static int do_suspend(struct dm_ioctl *param)
 950{
 951        int r = 0;
 952        unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG;
 953        struct mapped_device *md;
 954
 955        md = find_device(param);
 956        if (!md)
 957                return -ENXIO;
 958
 959        if (param->flags & DM_SKIP_LOCKFS_FLAG)
 960                suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
 961        if (param->flags & DM_NOFLUSH_FLAG)
 962                suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
 963
 964        if (!dm_suspended_md(md)) {
 965                r = dm_suspend(md, suspend_flags);
 966                if (r)
 967                        goto out;
 968        }
 969
 970        __dev_status(md, param);
 971
 972out:
 973        dm_put(md);
 974
 975        return r;
 976}
 977
 978static int do_resume(struct dm_ioctl *param)
 979{
 980        int r = 0;
 981        unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG;
 982        struct hash_cell *hc;
 983        struct mapped_device *md;
 984        struct dm_table *new_map, *old_map = NULL;
 985
 986        down_write(&_hash_lock);
 987
 988        hc = __find_device_hash_cell(param);
 989        if (!hc) {
 990                DMDEBUG_LIMIT("device doesn't appear to be in the dev hash table.");
 991                up_write(&_hash_lock);
 992                return -ENXIO;
 993        }
 994
 995        md = hc->md;
 996
 997        new_map = hc->new_map;
 998        hc->new_map = NULL;
 999        param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
1000
1001        up_write(&_hash_lock);
1002
1003        /* Do we need to load a new map ? */
1004        if (new_map) {
1005                /* Suspend if it isn't already suspended */
1006                if (param->flags & DM_SKIP_LOCKFS_FLAG)
1007                        suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
1008                if (param->flags & DM_NOFLUSH_FLAG)
1009                        suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
1010                if (!dm_suspended_md(md))
1011                        dm_suspend(md, suspend_flags);
1012
1013                old_map = dm_swap_table(md, new_map);
1014                if (IS_ERR(old_map)) {
1015                        dm_sync_table(md);
1016                        dm_table_destroy(new_map);
1017                        dm_put(md);
1018                        return PTR_ERR(old_map);
1019                }
1020
1021                if (dm_table_get_mode(new_map) & FMODE_WRITE)
1022                        set_disk_ro(dm_disk(md), 0);
1023                else
1024                        set_disk_ro(dm_disk(md), 1);
1025        }
1026
1027        if (dm_suspended_md(md)) {
1028                r = dm_resume(md);
1029                if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr))
1030                        param->flags |= DM_UEVENT_GENERATED_FLAG;
1031        }
1032
1033        /*
1034         * Since dm_swap_table synchronizes RCU, nobody should be in
1035         * read-side critical section already.
1036         */
1037        if (old_map)
1038                dm_table_destroy(old_map);
1039
1040        if (!r)
1041                __dev_status(md, param);
1042
1043        dm_put(md);
1044        return r;
1045}
1046
1047/*
1048 * Set or unset the suspension state of a device.
1049 * If the device already is in the requested state we just return its status.
1050 */
1051static int dev_suspend(struct dm_ioctl *param, size_t param_size)
1052{
1053        if (param->flags & DM_SUSPEND_FLAG)
1054                return do_suspend(param);
1055
1056        return do_resume(param);
1057}
1058
1059/*
1060 * Copies device info back to user space, used by
1061 * the create and info ioctls.
1062 */
1063static int dev_status(struct dm_ioctl *param, size_t param_size)
1064{
1065        struct mapped_device *md;
1066
1067        md = find_device(param);
1068        if (!md)
1069                return -ENXIO;
1070
1071        __dev_status(md, param);
1072        dm_put(md);
1073
1074        return 0;
1075}
1076
1077/*
1078 * Build up the status struct for each target
1079 */
1080static void retrieve_status(struct dm_table *table,
1081                            struct dm_ioctl *param, size_t param_size)
1082{
1083        unsigned int i, num_targets;
1084        struct dm_target_spec *spec;
1085        char *outbuf, *outptr;
1086        status_type_t type;
1087        size_t remaining, len, used = 0;
1088        unsigned status_flags = 0;
1089
1090        outptr = outbuf = get_result_buffer(param, param_size, &len);
1091
1092        if (param->flags & DM_STATUS_TABLE_FLAG)
1093                type = STATUSTYPE_TABLE;
1094        else
1095                type = STATUSTYPE_INFO;
1096
1097        /* Get all the target info */
1098        num_targets = dm_table_get_num_targets(table);
1099        for (i = 0; i < num_targets; i++) {
1100                struct dm_target *ti = dm_table_get_target(table, i);
1101                size_t l;
1102
1103                remaining = len - (outptr - outbuf);
1104                if (remaining <= sizeof(struct dm_target_spec)) {
1105                        param->flags |= DM_BUFFER_FULL_FLAG;
1106                        break;
1107                }
1108
1109                spec = (struct dm_target_spec *) outptr;
1110
1111                spec->status = 0;
1112                spec->sector_start = ti->begin;
1113                spec->length = ti->len;
1114                strncpy(spec->target_type, ti->type->name,
1115                        sizeof(spec->target_type));
1116
1117                outptr += sizeof(struct dm_target_spec);
1118                remaining = len - (outptr - outbuf);
1119                if (remaining <= 0) {
1120                        param->flags |= DM_BUFFER_FULL_FLAG;
1121                        break;
1122                }
1123
1124                /* Get the status/table string from the target driver */
1125                if (ti->type->status) {
1126                        if (param->flags & DM_NOFLUSH_FLAG)
1127                                status_flags |= DM_STATUS_NOFLUSH_FLAG;
1128                        ti->type->status(ti, type, status_flags, outptr, remaining);
1129                } else
1130                        outptr[0] = '\0';
1131
1132                l = strlen(outptr) + 1;
1133                if (l == remaining) {
1134                        param->flags |= DM_BUFFER_FULL_FLAG;
1135                        break;
1136                }
1137
1138                outptr += l;
1139                used = param->data_start + (outptr - outbuf);
1140
1141                outptr = align_ptr(outptr);
1142                spec->next = outptr - outbuf;
1143        }
1144
1145        if (used)
1146                param->data_size = used;
1147
1148        param->target_count = num_targets;
1149}
1150
1151/*
1152 * Wait for a device to report an event
1153 */
1154static int dev_wait(struct dm_ioctl *param, size_t param_size)
1155{
1156        int r = 0;
1157        struct mapped_device *md;
1158        struct dm_table *table;
1159        int srcu_idx;
1160
1161        md = find_device(param);
1162        if (!md)
1163                return -ENXIO;
1164
1165        /*
1166         * Wait for a notification event
1167         */
1168        if (dm_wait_event(md, param->event_nr)) {
1169                r = -ERESTARTSYS;
1170                goto out;
1171        }
1172
1173        /*
1174         * The userland program is going to want to know what
1175         * changed to trigger the event, so we may as well tell
1176         * him and save an ioctl.
1177         */
1178        __dev_status(md, param);
1179
1180        table = dm_get_live_or_inactive_table(md, param, &srcu_idx);
1181        if (table)
1182                retrieve_status(table, param, param_size);
1183        dm_put_live_table(md, srcu_idx);
1184
1185out:
1186        dm_put(md);
1187
1188        return r;
1189}
1190
1191static inline fmode_t get_mode(struct dm_ioctl *param)
1192{
1193        fmode_t mode = FMODE_READ | FMODE_WRITE;
1194
1195        if (param->flags & DM_READONLY_FLAG)
1196                mode = FMODE_READ;
1197
1198        return mode;
1199}
1200
1201static int next_target(struct dm_target_spec *last, uint32_t next, void *end,
1202                       struct dm_target_spec **spec, char **target_params)
1203{
1204        *spec = (struct dm_target_spec *) ((unsigned char *) last + next);
1205        *target_params = (char *) (*spec + 1);
1206
1207        if (*spec < (last + 1))
1208                return -EINVAL;
1209
1210        return invalid_str(*target_params, end);
1211}
1212
1213static int populate_table(struct dm_table *table,
1214                          struct dm_ioctl *param, size_t param_size)
1215{
1216        int r;
1217        unsigned int i = 0;
1218        struct dm_target_spec *spec = (struct dm_target_spec *) param;
1219        uint32_t next = param->data_start;
1220        void *end = (void *) param + param_size;
1221        char *target_params;
1222
1223        if (!param->target_count) {
1224                DMWARN("populate_table: no targets specified");
1225                return -EINVAL;
1226        }
1227
1228        for (i = 0; i < param->target_count; i++) {
1229
1230                r = next_target(spec, next, end, &spec, &target_params);
1231                if (r) {
1232                        DMWARN("unable to find target");
1233                        return r;
1234                }
1235
1236                r = dm_table_add_target(table, spec->target_type,
1237                                        (sector_t) spec->sector_start,
1238                                        (sector_t) spec->length,
1239                                        target_params);
1240                if (r) {
1241                        DMWARN("error adding target to table");
1242                        return r;
1243                }
1244
1245                next = spec->next;
1246        }
1247
1248        return dm_table_complete(table);
1249}
1250
1251static int table_load(struct dm_ioctl *param, size_t param_size)
1252{
1253        int r;
1254        struct hash_cell *hc;
1255        struct dm_table *t, *old_map = NULL;
1256        struct mapped_device *md;
1257        struct target_type *immutable_target_type;
1258
1259        md = find_device(param);
1260        if (!md)
1261                return -ENXIO;
1262
1263        r = dm_table_create(&t, get_mode(param), param->target_count, md);
1264        if (r)
1265                goto out;
1266
1267        r = populate_table(t, param, param_size);
1268        if (r) {
1269                dm_table_destroy(t);
1270                goto out;
1271        }
1272
1273        immutable_target_type = dm_get_immutable_target_type(md);
1274        if (immutable_target_type &&
1275            (immutable_target_type != dm_table_get_immutable_target_type(t))) {
1276                DMWARN("can't replace immutable target type %s",
1277                       immutable_target_type->name);
1278                dm_table_destroy(t);
1279                r = -EINVAL;
1280                goto out;
1281        }
1282
1283        /* Protect md->type and md->queue against concurrent table loads. */
1284        dm_lock_md_type(md);
1285        if (dm_get_md_type(md) == DM_TYPE_NONE)
1286                /* Initial table load: acquire type of table. */
1287                dm_set_md_type(md, dm_table_get_type(t));
1288        else if (dm_get_md_type(md) != dm_table_get_type(t)) {
1289                DMWARN("can't change device type after initial table load.");
1290                dm_table_destroy(t);
1291                dm_unlock_md_type(md);
1292                r = -EINVAL;
1293                goto out;
1294        }
1295
1296        /* setup md->queue to reflect md's type (may block) */
1297        r = dm_setup_md_queue(md);
1298        if (r) {
1299                DMWARN("unable to set up device queue for new table.");
1300                dm_table_destroy(t);
1301                dm_unlock_md_type(md);
1302                goto out;
1303        }
1304        dm_unlock_md_type(md);
1305
1306        /* stage inactive table */
1307        down_write(&_hash_lock);
1308        hc = dm_get_mdptr(md);
1309        if (!hc || hc->md != md) {
1310                DMWARN("device has been removed from the dev hash table.");
1311                up_write(&_hash_lock);
1312                dm_table_destroy(t);
1313                r = -ENXIO;
1314                goto out;
1315        }
1316
1317        if (hc->new_map)
1318                old_map = hc->new_map;
1319        hc->new_map = t;
1320        up_write(&_hash_lock);
1321
1322        param->flags |= DM_INACTIVE_PRESENT_FLAG;
1323        __dev_status(md, param);
1324
1325out:
1326        if (old_map) {
1327                dm_sync_table(md);
1328                dm_table_destroy(old_map);
1329        }
1330
1331        dm_put(md);
1332
1333        return r;
1334}
1335
1336static int table_clear(struct dm_ioctl *param, size_t param_size)
1337{
1338        struct hash_cell *hc;
1339        struct mapped_device *md;
1340        struct dm_table *old_map = NULL;
1341
1342        down_write(&_hash_lock);
1343
1344        hc = __find_device_hash_cell(param);
1345        if (!hc) {
1346                DMDEBUG_LIMIT("device doesn't appear to be in the dev hash table.");
1347                up_write(&_hash_lock);
1348                return -ENXIO;
1349        }
1350
1351        if (hc->new_map) {
1352                old_map = hc->new_map;
1353                hc->new_map = NULL;
1354        }
1355
1356        param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
1357
1358        __dev_status(hc->md, param);
1359        md = hc->md;
1360        up_write(&_hash_lock);
1361        if (old_map) {
1362                dm_sync_table(md);
1363                dm_table_destroy(old_map);
1364        }
1365        dm_put(md);
1366
1367        return 0;
1368}
1369
1370/*
1371 * Retrieves a list of devices used by a particular dm device.
1372 */
1373static void retrieve_deps(struct dm_table *table,
1374                          struct dm_ioctl *param, size_t param_size)
1375{
1376        unsigned int count = 0;
1377        struct list_head *tmp;
1378        size_t len, needed;
1379        struct dm_dev_internal *dd;
1380        struct dm_target_deps *deps;
1381
1382        deps = get_result_buffer(param, param_size, &len);
1383
1384        /*
1385         * Count the devices.
1386         */
1387        list_for_each (tmp, dm_table_get_devices(table))
1388                count++;
1389
1390        /*
1391         * Check we have enough space.
1392         */
1393        needed = sizeof(*deps) + (sizeof(*deps->dev) * count);
1394        if (len < needed) {
1395                param->flags |= DM_BUFFER_FULL_FLAG;
1396                return;
1397        }
1398
1399        /*
1400         * Fill in the devices.
1401         */
1402        deps->count = count;
1403        count = 0;
1404        list_for_each_entry (dd, dm_table_get_devices(table), list)
1405                deps->dev[count++] = huge_encode_dev(dd->dm_dev.bdev->bd_dev);
1406
1407        param->data_size = param->data_start + needed;
1408}
1409
1410static int table_deps(struct dm_ioctl *param, size_t param_size)
1411{
1412        struct mapped_device *md;
1413        struct dm_table *table;
1414        int srcu_idx;
1415
1416        md = find_device(param);
1417        if (!md)
1418                return -ENXIO;
1419
1420        __dev_status(md, param);
1421
1422        table = dm_get_live_or_inactive_table(md, param, &srcu_idx);
1423        if (table)
1424                retrieve_deps(table, param, param_size);
1425        dm_put_live_table(md, srcu_idx);
1426
1427        dm_put(md);
1428
1429        return 0;
1430}
1431
1432/*
1433 * Return the status of a device as a text string for each
1434 * target.
1435 */
1436static int table_status(struct dm_ioctl *param, size_t param_size)
1437{
1438        struct mapped_device *md;
1439        struct dm_table *table;
1440        int srcu_idx;
1441
1442        md = find_device(param);
1443        if (!md)
1444                return -ENXIO;
1445
1446        __dev_status(md, param);
1447
1448        table = dm_get_live_or_inactive_table(md, param, &srcu_idx);
1449        if (table)
1450                retrieve_status(table, param, param_size);
1451        dm_put_live_table(md, srcu_idx);
1452
1453        dm_put(md);
1454
1455        return 0;
1456}
1457
1458static bool buffer_test_overflow(char *result, unsigned maxlen)
1459{
1460        return !maxlen || strlen(result) + 1 >= maxlen;
1461}
1462
1463/*
1464 * Process device-mapper dependent messages.
1465 * Returns a number <= 1 if message was processed by device mapper.
1466 * Returns 2 if message should be delivered to the target.
1467 */
1468static int message_for_md(struct mapped_device *md, unsigned argc, char **argv,
1469                          char *result, unsigned maxlen)
1470{
1471        return 2;
1472}
1473
1474/*
1475 * Pass a message to the target that's at the supplied device offset.
1476 */
1477static int target_message(struct dm_ioctl *param, size_t param_size)
1478{
1479        int r, argc;
1480        char **argv;
1481        struct mapped_device *md;
1482        struct dm_table *table;
1483        struct dm_target *ti;
1484        struct dm_target_msg *tmsg = (void *) param + param->data_start;
1485        size_t maxlen;
1486        char *result = get_result_buffer(param, param_size, &maxlen);
1487        int srcu_idx;
1488
1489        md = find_device(param);
1490        if (!md)
1491                return -ENXIO;
1492
1493        if (tmsg < (struct dm_target_msg *) param->data ||
1494            invalid_str(tmsg->message, (void *) param + param_size)) {
1495                DMWARN("Invalid target message parameters.");
1496                r = -EINVAL;
1497                goto out;
1498        }
1499
1500        r = dm_split_args(&argc, &argv, tmsg->message);
1501        if (r) {
1502                DMWARN("Failed to split target message parameters");
1503                goto out;
1504        }
1505
1506        if (!argc) {
1507                DMWARN("Empty message received.");
1508                goto out_argv;
1509        }
1510
1511        r = message_for_md(md, argc, argv, result, maxlen);
1512        if (r <= 1)
1513                goto out_argv;
1514
1515        table = dm_get_live_table(md, &srcu_idx);
1516        if (!table)
1517                goto out_table;
1518
1519        if (dm_deleting_md(md)) {
1520                r = -ENXIO;
1521                goto out_table;
1522        }
1523
1524        ti = dm_table_find_target(table, tmsg->sector);
1525        if (!dm_target_is_valid(ti)) {
1526                DMWARN("Target message sector outside device.");
1527                r = -EINVAL;
1528        } else if (ti->type->message)
1529                r = ti->type->message(ti, argc, argv);
1530        else {
1531                DMWARN("Target type does not support messages");
1532                r = -EINVAL;
1533        }
1534
1535 out_table:
1536        dm_put_live_table(md, srcu_idx);
1537 out_argv:
1538        kfree(argv);
1539 out:
1540        if (r >= 0)
1541                __dev_status(md, param);
1542
1543        if (r == 1) {
1544                param->flags |= DM_DATA_OUT_FLAG;
1545                if (buffer_test_overflow(result, maxlen))
1546                        param->flags |= DM_BUFFER_FULL_FLAG;
1547                else
1548                        param->data_size = param->data_start + strlen(result) + 1;
1549                r = 0;
1550        }
1551
1552        dm_put(md);
1553        return r;
1554}
1555
1556/*
1557 * The ioctl parameter block consists of two parts, a dm_ioctl struct
1558 * followed by a data buffer.  This flag is set if the second part,
1559 * which has a variable size, is not used by the function processing
1560 * the ioctl.
1561 */
1562#define IOCTL_FLAGS_NO_PARAMS   1
1563
1564/*-----------------------------------------------------------------
1565 * Implementation of open/close/ioctl on the special char
1566 * device.
1567 *---------------------------------------------------------------*/
1568static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
1569{
1570        static struct {
1571                int cmd;
1572                int flags;
1573                ioctl_fn fn;
1574        } _ioctls[] = {
1575                {DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */
1576                {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all},
1577                {DM_LIST_DEVICES_CMD, 0, list_devices},
1578
1579                {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create},
1580                {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove},
1581                {DM_DEV_RENAME_CMD, 0, dev_rename},
1582                {DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend},
1583                {DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status},
1584                {DM_DEV_WAIT_CMD, 0, dev_wait},
1585
1586                {DM_TABLE_LOAD_CMD, 0, table_load},
1587                {DM_TABLE_CLEAR_CMD, IOCTL_FLAGS_NO_PARAMS, table_clear},
1588                {DM_TABLE_DEPS_CMD, 0, table_deps},
1589                {DM_TABLE_STATUS_CMD, 0, table_status},
1590
1591                {DM_LIST_VERSIONS_CMD, 0, list_versions},
1592
1593                {DM_TARGET_MSG_CMD, 0, target_message},
1594                {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}
1595        };
1596
1597        if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))
1598                return NULL;
1599
1600        *ioctl_flags = _ioctls[cmd].flags;
1601        return _ioctls[cmd].fn;
1602}
1603
1604/*
1605 * As well as checking the version compatibility this always
1606 * copies the kernel interface version out.
1607 */
1608static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
1609{
1610        uint32_t version[3];
1611        int r = 0;
1612
1613        if (copy_from_user(version, user->version, sizeof(version)))
1614                return -EFAULT;
1615
1616        if ((DM_VERSION_MAJOR != version[0]) ||
1617            (DM_VERSION_MINOR < version[1])) {
1618                DMWARN("ioctl interface mismatch: "
1619                       "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
1620                       DM_VERSION_MAJOR, DM_VERSION_MINOR,
1621                       DM_VERSION_PATCHLEVEL,
1622                       version[0], version[1], version[2], cmd);
1623                r = -EINVAL;
1624        }
1625
1626        /*
1627         * Fill in the kernel version.
1628         */
1629        version[0] = DM_VERSION_MAJOR;
1630        version[1] = DM_VERSION_MINOR;
1631        version[2] = DM_VERSION_PATCHLEVEL;
1632        if (copy_to_user(user->version, version, sizeof(version)))
1633                return -EFAULT;
1634
1635        return r;
1636}
1637
1638#define DM_PARAMS_KMALLOC       0x0001  /* Params alloced with kmalloc */
1639#define DM_PARAMS_VMALLOC       0x0002  /* Params alloced with vmalloc */
1640#define DM_WIPE_BUFFER          0x0010  /* Wipe input buffer before returning from ioctl */
1641
1642static void free_params(struct dm_ioctl *param, size_t param_size, int param_flags)
1643{
1644        if (param_flags & DM_WIPE_BUFFER)
1645                memset(param, 0, param_size);
1646
1647        if (param_flags & DM_PARAMS_KMALLOC)
1648                kfree(param);
1649        if (param_flags & DM_PARAMS_VMALLOC)
1650                vfree(param);
1651}
1652
1653static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kernel,
1654                       int ioctl_flags,
1655                       struct dm_ioctl **param, int *param_flags)
1656{
1657        struct dm_ioctl *dmi;
1658        int secure_data;
1659        const size_t minimum_data_size = sizeof(*param_kernel) - sizeof(param_kernel->data);
1660
1661        if (copy_from_user(param_kernel, user, minimum_data_size))
1662                return -EFAULT;
1663
1664        if (param_kernel->data_size < minimum_data_size)
1665                return -EINVAL;
1666
1667        secure_data = param_kernel->flags & DM_SECURE_DATA_FLAG;
1668
1669        *param_flags = secure_data ? DM_WIPE_BUFFER : 0;
1670
1671        if (ioctl_flags & IOCTL_FLAGS_NO_PARAMS) {
1672                dmi = param_kernel;
1673                dmi->data_size = minimum_data_size;
1674                goto data_copied;
1675        }
1676
1677        /*
1678         * Try to avoid low memory issues when a device is suspended.
1679         * Use kmalloc() rather than vmalloc() when we can.
1680         */
1681        dmi = NULL;
1682        if (param_kernel->data_size <= KMALLOC_MAX_SIZE) {
1683                dmi = kmalloc(param_kernel->data_size, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
1684                if (dmi)
1685                        *param_flags |= DM_PARAMS_KMALLOC;
1686        }
1687
1688        if (!dmi) {
1689                unsigned noio_flag;
1690                noio_flag = memalloc_noio_save();
1691                dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_REPEAT | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
1692                memalloc_noio_restore(noio_flag);
1693                if (dmi)
1694                        *param_flags |= DM_PARAMS_VMALLOC;
1695        }
1696
1697        if (!dmi) {
1698                if (secure_data && clear_user(user, param_kernel->data_size))
1699                        return -EFAULT;
1700                return -ENOMEM;
1701        }
1702
1703        if (copy_from_user(dmi, user, param_kernel->data_size))
1704                goto bad;
1705
1706data_copied:
1707        /*
1708         * Abort if something changed the ioctl data while it was being copied.
1709         */
1710        if (dmi->data_size != param_kernel->data_size) {
1711                DMERR("rejecting ioctl: data size modified while processing parameters");
1712                goto bad;
1713        }
1714
1715        /* Wipe the user buffer so we do not return it to userspace */
1716        if (secure_data && clear_user(user, param_kernel->data_size))
1717                goto bad;
1718
1719        *param = dmi;
1720        return 0;
1721
1722bad:
1723        free_params(dmi, param_kernel->data_size, *param_flags);
1724
1725        return -EFAULT;
1726}
1727
1728static int validate_params(uint cmd, struct dm_ioctl *param)
1729{
1730        /* Always clear this flag */
1731        param->flags &= ~DM_BUFFER_FULL_FLAG;
1732        param->flags &= ~DM_UEVENT_GENERATED_FLAG;
1733        param->flags &= ~DM_SECURE_DATA_FLAG;
1734        param->flags &= ~DM_DATA_OUT_FLAG;
1735
1736        /* Ignores parameters */
1737        if (cmd == DM_REMOVE_ALL_CMD ||
1738            cmd == DM_LIST_DEVICES_CMD ||
1739            cmd == DM_LIST_VERSIONS_CMD)
1740                return 0;
1741
1742        if ((cmd == DM_DEV_CREATE_CMD)) {
1743                if (!*param->name) {
1744                        DMWARN("name not supplied when creating device");
1745                        return -EINVAL;
1746                }
1747        } else if ((*param->uuid && *param->name)) {
1748                DMWARN("only supply one of name or uuid, cmd(%u)", cmd);
1749                return -EINVAL;
1750        }
1751
1752        /* Ensure strings are terminated */
1753        param->name[DM_NAME_LEN - 1] = '\0';
1754        param->uuid[DM_UUID_LEN - 1] = '\0';
1755
1756        return 0;
1757}
1758
1759static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
1760{
1761        int r = 0;
1762        int ioctl_flags;
1763        int param_flags;
1764        unsigned int cmd;
1765        struct dm_ioctl *uninitialized_var(param);
1766        ioctl_fn fn = NULL;
1767        size_t input_param_size;
1768        struct dm_ioctl param_kernel;
1769
1770        /* only root can play with this */
1771        if (!capable(CAP_SYS_ADMIN))
1772                return -EACCES;
1773
1774        if (_IOC_TYPE(command) != DM_IOCTL)
1775                return -ENOTTY;
1776
1777        cmd = _IOC_NR(command);
1778
1779        /*
1780         * Check the interface version passed in.  This also
1781         * writes out the kernel's interface version.
1782         */
1783        r = check_version(cmd, user);
1784        if (r)
1785                return r;
1786
1787        /*
1788         * Nothing more to do for the version command.
1789         */
1790        if (cmd == DM_VERSION_CMD)
1791                return 0;
1792
1793        fn = lookup_ioctl(cmd, &ioctl_flags);
1794        if (!fn) {
1795                DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
1796                return -ENOTTY;
1797        }
1798
1799        /*
1800         * Copy the parameters into kernel space.
1801         */
1802        r = copy_params(user, &param_kernel, ioctl_flags, &param, &param_flags);
1803
1804        if (r)
1805                return r;
1806
1807        input_param_size = param->data_size;
1808        r = validate_params(cmd, param);
1809        if (r)
1810                goto out;
1811
1812        param->data_size = sizeof(*param);
1813        r = fn(param, input_param_size);
1814
1815        if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
1816            unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS))
1817                DMERR("ioctl %d tried to output some data but has IOCTL_FLAGS_NO_PARAMS set", cmd);
1818
1819        /*
1820         * Copy the results back to userland.
1821         */
1822        if (!r && copy_to_user(user, param, param->data_size))
1823                r = -EFAULT;
1824
1825out:
1826        free_params(param, input_param_size, param_flags);
1827        return r;
1828}
1829
1830static long dm_ctl_ioctl(struct file *file, uint command, ulong u)
1831{
1832        return (long)ctl_ioctl(command, (struct dm_ioctl __user *)u);
1833}
1834
1835#ifdef CONFIG_COMPAT
1836static long dm_compat_ctl_ioctl(struct file *file, uint command, ulong u)
1837{
1838        return (long)dm_ctl_ioctl(file, command, (ulong) compat_ptr(u));
1839}
1840#else
1841#define dm_compat_ctl_ioctl NULL
1842#endif
1843
1844static const struct file_operations _ctl_fops = {
1845        .open = nonseekable_open,
1846        .unlocked_ioctl  = dm_ctl_ioctl,
1847        .compat_ioctl = dm_compat_ctl_ioctl,
1848        .owner   = THIS_MODULE,
1849        .llseek  = noop_llseek,
1850};
1851
1852static struct miscdevice _dm_misc = {
1853        .minor          = MAPPER_CTRL_MINOR,
1854        .name           = DM_NAME,
1855        .nodename       = DM_DIR "/" DM_CONTROL_NODE,
1856        .fops           = &_ctl_fops
1857};
1858
1859MODULE_ALIAS_MISCDEV(MAPPER_CTRL_MINOR);
1860MODULE_ALIAS("devname:" DM_DIR "/" DM_CONTROL_NODE);
1861
1862/*
1863 * Create misc character device and link to DM_DIR/control.
1864 */
1865int __init dm_interface_init(void)
1866{
1867        int r;
1868
1869        r = dm_hash_init();
1870        if (r)
1871                return r;
1872
1873        r = misc_register(&_dm_misc);
1874        if (r) {
1875                DMERR("misc_register failed for control device");
1876                dm_hash_exit();
1877                return r;
1878        }
1879
1880        DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR,
1881               DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA,
1882               DM_DRIVER_EMAIL);
1883        return 0;
1884}
1885
1886void dm_interface_exit(void)
1887{
1888        if (misc_deregister(&_dm_misc) < 0)
1889                DMERR("misc_deregister failed for control device");
1890
1891        dm_hash_exit();
1892}
1893
1894/**
1895 * dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers
1896 * @md: Pointer to mapped_device
1897 * @name: Buffer (size DM_NAME_LEN) for name
1898 * @uuid: Buffer (size DM_UUID_LEN) for uuid or empty string if uuid not defined
1899 */
1900int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
1901{
1902        int r = 0;
1903        struct hash_cell *hc;
1904
1905        if (!md)
1906                return -ENXIO;
1907
1908        mutex_lock(&dm_hash_cells_mutex);
1909        hc = dm_get_mdptr(md);
1910        if (!hc || hc->md != md) {
1911                r = -ENXIO;
1912                goto out;
1913        }
1914
1915        if (name)
1916                strcpy(name, hc->name);
1917        if (uuid)
1918                strcpy(uuid, hc->uuid ? : "");
1919
1920out:
1921        mutex_unlock(&dm_hash_cells_mutex);
1922
1923        return r;
1924}
1925
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.