LCOV - code coverage report
Current view: top level - drivers/md - dm-ioctl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 763 0.0 %
Date: 2014-02-18 Functions: 0 51 0.0 %
Branches: 0 478 0.0 %

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

Generated by: LCOV version 1.9