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

Generated by: LCOV version 1.14