Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2001 Sistina Software (UK) Limited
0003  *
0004  * This file is released under the GPL.
0005  */
0006 
0007 #include "dm-core.h"
0008 
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/kmod.h>
0012 #include <linux/bio.h>
0013 #include <linux/dax.h>
0014 
0015 #define DM_MSG_PREFIX "target"
0016 
0017 static LIST_HEAD(_targets);
0018 static DECLARE_RWSEM(_lock);
0019 
0020 static inline struct target_type *__find_target_type(const char *name)
0021 {
0022     struct target_type *tt;
0023 
0024     list_for_each_entry(tt, &_targets, list)
0025         if (!strcmp(name, tt->name))
0026             return tt;
0027 
0028     return NULL;
0029 }
0030 
0031 static struct target_type *get_target_type(const char *name)
0032 {
0033     struct target_type *tt;
0034 
0035     down_read(&_lock);
0036 
0037     tt = __find_target_type(name);
0038     if (tt && !try_module_get(tt->module))
0039         tt = NULL;
0040 
0041     up_read(&_lock);
0042     return tt;
0043 }
0044 
0045 static void load_module(const char *name)
0046 {
0047     request_module("dm-%s", name);
0048 }
0049 
0050 struct target_type *dm_get_target_type(const char *name)
0051 {
0052     struct target_type *tt = get_target_type(name);
0053 
0054     if (!tt) {
0055         load_module(name);
0056         tt = get_target_type(name);
0057     }
0058 
0059     return tt;
0060 }
0061 
0062 void dm_put_target_type(struct target_type *tt)
0063 {
0064     down_read(&_lock);
0065     module_put(tt->module);
0066     up_read(&_lock);
0067 }
0068 
0069 int dm_target_iterate(void (*iter_func)(struct target_type *tt,
0070                     void *param), void *param)
0071 {
0072     struct target_type *tt;
0073 
0074     down_read(&_lock);
0075     list_for_each_entry(tt, &_targets, list)
0076         iter_func(tt, param);
0077     up_read(&_lock);
0078 
0079     return 0;
0080 }
0081 
0082 int dm_register_target(struct target_type *tt)
0083 {
0084     int rv = 0;
0085 
0086     down_write(&_lock);
0087     if (__find_target_type(tt->name))
0088         rv = -EEXIST;
0089     else
0090         list_add(&tt->list, &_targets);
0091 
0092     up_write(&_lock);
0093     return rv;
0094 }
0095 
0096 void dm_unregister_target(struct target_type *tt)
0097 {
0098     down_write(&_lock);
0099     if (!__find_target_type(tt->name)) {
0100         DMCRIT("Unregistering unrecognised target: %s", tt->name);
0101         BUG();
0102     }
0103 
0104     list_del(&tt->list);
0105 
0106     up_write(&_lock);
0107 }
0108 
0109 /*
0110  * io-err: always fails an io, useful for bringing
0111  * up LVs that have holes in them.
0112  */
0113 static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
0114 {
0115     /*
0116      * Return error for discards instead of -EOPNOTSUPP
0117      */
0118     tt->num_discard_bios = 1;
0119 
0120     return 0;
0121 }
0122 
0123 static void io_err_dtr(struct dm_target *tt)
0124 {
0125     /* empty */
0126 }
0127 
0128 static int io_err_map(struct dm_target *tt, struct bio *bio)
0129 {
0130     return DM_MAPIO_KILL;
0131 }
0132 
0133 static int io_err_clone_and_map_rq(struct dm_target *ti, struct request *rq,
0134                    union map_info *map_context,
0135                    struct request **clone)
0136 {
0137     return DM_MAPIO_KILL;
0138 }
0139 
0140 static void io_err_release_clone_rq(struct request *clone,
0141                     union map_info *map_context)
0142 {
0143 }
0144 
0145 static long io_err_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
0146         long nr_pages, enum dax_access_mode mode, void **kaddr,
0147         pfn_t *pfn)
0148 {
0149     return -EIO;
0150 }
0151 
0152 static struct target_type error_target = {
0153     .name = "error",
0154     .version = {1, 5, 0},
0155     .features = DM_TARGET_WILDCARD,
0156     .ctr  = io_err_ctr,
0157     .dtr  = io_err_dtr,
0158     .map  = io_err_map,
0159     .clone_and_map_rq = io_err_clone_and_map_rq,
0160     .release_clone_rq = io_err_release_clone_rq,
0161     .direct_access = io_err_dax_direct_access,
0162 };
0163 
0164 int __init dm_target_init(void)
0165 {
0166     return dm_register_target(&error_target);
0167 }
0168 
0169 void dm_target_exit(void)
0170 {
0171     dm_unregister_target(&error_target);
0172 }
0173 
0174 EXPORT_SYMBOL(dm_register_target);
0175 EXPORT_SYMBOL(dm_unregister_target);