root/drivers/md/dm-cache-policy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __find_policy
  2. __get_policy_once
  3. get_policy_once
  4. get_policy
  5. put_policy
  6. dm_cache_policy_register
  7. dm_cache_policy_unregister
  8. dm_cache_policy_create
  9. dm_cache_policy_destroy
  10. dm_cache_policy_get_name
  11. dm_cache_policy_get_version
  12. dm_cache_policy_get_hint_size

   1 /*
   2  * Copyright (C) 2012 Red Hat. All rights reserved.
   3  *
   4  * This file is released under the GPL.
   5  */
   6 
   7 #include "dm-cache-policy-internal.h"
   8 #include "dm.h"
   9 
  10 #include <linux/module.h>
  11 #include <linux/slab.h>
  12 
  13 /*----------------------------------------------------------------*/
  14 
  15 #define DM_MSG_PREFIX "cache-policy"
  16 
  17 static DEFINE_SPINLOCK(register_lock);
  18 static LIST_HEAD(register_list);
  19 
  20 static struct dm_cache_policy_type *__find_policy(const char *name)
  21 {
  22         struct dm_cache_policy_type *t;
  23 
  24         list_for_each_entry(t, &register_list, list)
  25                 if (!strcmp(t->name, name))
  26                         return t;
  27 
  28         return NULL;
  29 }
  30 
  31 static struct dm_cache_policy_type *__get_policy_once(const char *name)
  32 {
  33         struct dm_cache_policy_type *t = __find_policy(name);
  34 
  35         if (t && !try_module_get(t->owner)) {
  36                 DMWARN("couldn't get module %s", name);
  37                 t = ERR_PTR(-EINVAL);
  38         }
  39 
  40         return t;
  41 }
  42 
  43 static struct dm_cache_policy_type *get_policy_once(const char *name)
  44 {
  45         struct dm_cache_policy_type *t;
  46 
  47         spin_lock(&register_lock);
  48         t = __get_policy_once(name);
  49         spin_unlock(&register_lock);
  50 
  51         return t;
  52 }
  53 
  54 static struct dm_cache_policy_type *get_policy(const char *name)
  55 {
  56         struct dm_cache_policy_type *t;
  57 
  58         t = get_policy_once(name);
  59         if (IS_ERR(t))
  60                 return NULL;
  61 
  62         if (t)
  63                 return t;
  64 
  65         request_module("dm-cache-%s", name);
  66 
  67         t = get_policy_once(name);
  68         if (IS_ERR(t))
  69                 return NULL;
  70 
  71         return t;
  72 }
  73 
  74 static void put_policy(struct dm_cache_policy_type *t)
  75 {
  76         module_put(t->owner);
  77 }
  78 
  79 int dm_cache_policy_register(struct dm_cache_policy_type *type)
  80 {
  81         int r;
  82 
  83         /* One size fits all for now */
  84         if (type->hint_size != 0 && type->hint_size != 4) {
  85                 DMWARN("hint size must be 0 or 4 but %llu supplied.", (unsigned long long) type->hint_size);
  86                 return -EINVAL;
  87         }
  88 
  89         spin_lock(&register_lock);
  90         if (__find_policy(type->name)) {
  91                 DMWARN("attempt to register policy under duplicate name %s", type->name);
  92                 r = -EINVAL;
  93         } else {
  94                 list_add(&type->list, &register_list);
  95                 r = 0;
  96         }
  97         spin_unlock(&register_lock);
  98 
  99         return r;
 100 }
 101 EXPORT_SYMBOL_GPL(dm_cache_policy_register);
 102 
 103 void dm_cache_policy_unregister(struct dm_cache_policy_type *type)
 104 {
 105         spin_lock(&register_lock);
 106         list_del_init(&type->list);
 107         spin_unlock(&register_lock);
 108 }
 109 EXPORT_SYMBOL_GPL(dm_cache_policy_unregister);
 110 
 111 struct dm_cache_policy *dm_cache_policy_create(const char *name,
 112                                                dm_cblock_t cache_size,
 113                                                sector_t origin_size,
 114                                                sector_t cache_block_size)
 115 {
 116         struct dm_cache_policy *p = NULL;
 117         struct dm_cache_policy_type *type;
 118 
 119         type = get_policy(name);
 120         if (!type) {
 121                 DMWARN("unknown policy type");
 122                 return ERR_PTR(-EINVAL);
 123         }
 124 
 125         p = type->create(cache_size, origin_size, cache_block_size);
 126         if (!p) {
 127                 put_policy(type);
 128                 return ERR_PTR(-ENOMEM);
 129         }
 130         p->private = type;
 131 
 132         return p;
 133 }
 134 EXPORT_SYMBOL_GPL(dm_cache_policy_create);
 135 
 136 void dm_cache_policy_destroy(struct dm_cache_policy *p)
 137 {
 138         struct dm_cache_policy_type *t = p->private;
 139 
 140         p->destroy(p);
 141         put_policy(t);
 142 }
 143 EXPORT_SYMBOL_GPL(dm_cache_policy_destroy);
 144 
 145 const char *dm_cache_policy_get_name(struct dm_cache_policy *p)
 146 {
 147         struct dm_cache_policy_type *t = p->private;
 148 
 149         /* if t->real is set then an alias was used (e.g. "default") */
 150         if (t->real)
 151                 return t->real->name;
 152 
 153         return t->name;
 154 }
 155 EXPORT_SYMBOL_GPL(dm_cache_policy_get_name);
 156 
 157 const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p)
 158 {
 159         struct dm_cache_policy_type *t = p->private;
 160 
 161         return t->version;
 162 }
 163 EXPORT_SYMBOL_GPL(dm_cache_policy_get_version);
 164 
 165 size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p)
 166 {
 167         struct dm_cache_policy_type *t = p->private;
 168 
 169         return t->hint_size;
 170 }
 171 EXPORT_SYMBOL_GPL(dm_cache_policy_get_hint_size);
 172 
 173 /*----------------------------------------------------------------*/

/* [<][>][^][v][top][bottom][index][help] */