LCOV - code coverage report
Current view: top level - drivers/md - dm-target.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 13 65 20.0 %
Date: 2021-04-22 12:43:58 Functions: 3 15 20.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2001 Sistina Software (UK) Limited
       3             :  *
       4             :  * This file is released under the GPL.
       5             :  */
       6             : 
       7             : #include "dm-core.h"
       8             : 
       9             : #include <linux/module.h>
      10             : #include <linux/init.h>
      11             : #include <linux/kmod.h>
      12             : #include <linux/bio.h>
      13             : 
      14             : #define DM_MSG_PREFIX "target"
      15             : 
      16             : static LIST_HEAD(_targets);
      17             : static DECLARE_RWSEM(_lock);
      18             : 
      19           3 : static inline struct target_type *__find_target_type(const char *name)
      20             : {
      21           3 :         struct target_type *tt;
      22             : 
      23           6 :         list_for_each_entry(tt, &_targets, list)
      24           3 :                 if (!strcmp(name, tt->name))
      25           0 :                         return tt;
      26             : 
      27             :         return NULL;
      28             : }
      29             : 
      30           0 : static struct target_type *get_target_type(const char *name)
      31             : {
      32           0 :         struct target_type *tt;
      33             : 
      34           0 :         down_read(&_lock);
      35             : 
      36           0 :         tt = __find_target_type(name);
      37           0 :         if (tt && !try_module_get(tt->module))
      38             :                 tt = NULL;
      39             : 
      40           0 :         up_read(&_lock);
      41           0 :         return tt;
      42             : }
      43             : 
      44           0 : static void load_module(const char *name)
      45             : {
      46           0 :         request_module("dm-%s", name);
      47             : }
      48             : 
      49           0 : struct target_type *dm_get_target_type(const char *name)
      50             : {
      51           0 :         struct target_type *tt = get_target_type(name);
      52             : 
      53           0 :         if (!tt) {
      54           0 :                 load_module(name);
      55           0 :                 tt = get_target_type(name);
      56             :         }
      57             : 
      58           0 :         return tt;
      59             : }
      60             : 
      61           0 : void dm_put_target_type(struct target_type *tt)
      62             : {
      63           0 :         down_read(&_lock);
      64           0 :         module_put(tt->module);
      65           0 :         up_read(&_lock);
      66           0 : }
      67             : 
      68           0 : int dm_target_iterate(void (*iter_func)(struct target_type *tt,
      69             :                                         void *param), void *param)
      70             : {
      71           0 :         struct target_type *tt;
      72             : 
      73           0 :         down_read(&_lock);
      74           0 :         list_for_each_entry(tt, &_targets, list)
      75           0 :                 iter_func(tt, param);
      76           0 :         up_read(&_lock);
      77             : 
      78           0 :         return 0;
      79             : }
      80             : 
      81           3 : int dm_register_target(struct target_type *tt)
      82             : {
      83           3 :         int rv = 0;
      84             : 
      85           3 :         down_write(&_lock);
      86           3 :         if (__find_target_type(tt->name))
      87             :                 rv = -EEXIST;
      88             :         else
      89           3 :                 list_add(&tt->list, &_targets);
      90             : 
      91           3 :         up_write(&_lock);
      92           3 :         return rv;
      93             : }
      94             : 
      95           0 : void dm_unregister_target(struct target_type *tt)
      96             : {
      97           0 :         down_write(&_lock);
      98           0 :         if (!__find_target_type(tt->name)) {
      99           0 :                 DMCRIT("Unregistering unrecognised target: %s", tt->name);
     100           0 :                 BUG();
     101             :         }
     102             : 
     103           0 :         list_del(&tt->list);
     104             : 
     105           0 :         up_write(&_lock);
     106           0 : }
     107             : 
     108             : /*
     109             :  * io-err: always fails an io, useful for bringing
     110             :  * up LVs that have holes in them.
     111             :  */
     112           0 : static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
     113             : {
     114             :         /*
     115             :          * Return error for discards instead of -EOPNOTSUPP
     116             :          */
     117           0 :         tt->num_discard_bios = 1;
     118             : 
     119           0 :         return 0;
     120             : }
     121             : 
     122           0 : static void io_err_dtr(struct dm_target *tt)
     123             : {
     124             :         /* empty */
     125           0 : }
     126             : 
     127           0 : static int io_err_map(struct dm_target *tt, struct bio *bio)
     128             : {
     129           0 :         return DM_MAPIO_KILL;
     130             : }
     131             : 
     132           0 : static int io_err_clone_and_map_rq(struct dm_target *ti, struct request *rq,
     133             :                                    union map_info *map_context,
     134             :                                    struct request **clone)
     135             : {
     136           0 :         return DM_MAPIO_KILL;
     137             : }
     138             : 
     139           0 : static void io_err_release_clone_rq(struct request *clone,
     140             :                                     union map_info *map_context)
     141             : {
     142           0 : }
     143             : 
     144           0 : static long io_err_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
     145             :                 long nr_pages, void **kaddr, pfn_t *pfn)
     146             : {
     147           0 :         return -EIO;
     148             : }
     149             : 
     150             : static struct target_type error_target = {
     151             :         .name = "error",
     152             :         .version = {1, 5, 0},
     153             :         .features = DM_TARGET_WILDCARD,
     154             :         .ctr  = io_err_ctr,
     155             :         .dtr  = io_err_dtr,
     156             :         .map  = io_err_map,
     157             :         .clone_and_map_rq = io_err_clone_and_map_rq,
     158             :         .release_clone_rq = io_err_release_clone_rq,
     159             :         .direct_access = io_err_dax_direct_access,
     160             : };
     161             : 
     162           1 : int __init dm_target_init(void)
     163             : {
     164           1 :         return dm_register_target(&error_target);
     165             : }
     166             : 
     167           0 : void dm_target_exit(void)
     168             : {
     169           0 :         dm_unregister_target(&error_target);
     170           0 : }
     171             : 
     172             : EXPORT_SYMBOL(dm_register_target);
     173             : EXPORT_SYMBOL(dm_unregister_target);

Generated by: LCOV version 1.14