2 * Copyright (C) 2012 Red Hat. All rights reserved.
4 * This file is released under the GPL.
7 #include "dm-cache-policy-internal.h"
10 #include <linux/module.h>
11 #include <linux/slab.h>
13 /*----------------------------------------------------------------*/
15 #define DM_MSG_PREFIX "cache-policy"
17 static DEFINE_SPINLOCK(register_lock
);
18 static LIST_HEAD(register_list
);
20 static struct dm_cache_policy_type
*__find_policy(const char *name
)
22 struct dm_cache_policy_type
*t
;
24 list_for_each_entry(t
, ®ister_list
, list
)
25 if (!strcmp(t
->name
, name
))
31 static struct dm_cache_policy_type
*__get_policy_once(const char *name
)
33 struct dm_cache_policy_type
*t
= __find_policy(name
);
35 if (t
&& !try_module_get(t
->owner
)) {
36 DMWARN("couldn't get module %s", name
);
43 static struct dm_cache_policy_type
*get_policy_once(const char *name
)
45 struct dm_cache_policy_type
*t
;
47 spin_lock(®ister_lock
);
48 t
= __get_policy_once(name
);
49 spin_unlock(®ister_lock
);
54 static struct dm_cache_policy_type
*get_policy(const char *name
)
56 struct dm_cache_policy_type
*t
;
58 t
= get_policy_once(name
);
65 request_module("dm-cache-%s", name
);
67 t
= get_policy_once(name
);
74 static void put_policy(struct dm_cache_policy_type
*t
)
79 int dm_cache_policy_register(struct dm_cache_policy_type
*type
)
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
);
89 spin_lock(®ister_lock
);
90 if (__find_policy(type
->name
)) {
91 DMWARN("attempt to register policy under duplicate name %s", type
->name
);
94 list_add(&type
->list
, ®ister_list
);
97 spin_unlock(®ister_lock
);
101 EXPORT_SYMBOL_GPL(dm_cache_policy_register
);
103 void dm_cache_policy_unregister(struct dm_cache_policy_type
*type
)
105 spin_lock(®ister_lock
);
106 list_del_init(&type
->list
);
107 spin_unlock(®ister_lock
);
109 EXPORT_SYMBOL_GPL(dm_cache_policy_unregister
);
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
)
116 struct dm_cache_policy
*p
= NULL
;
117 struct dm_cache_policy_type
*type
;
119 type
= get_policy(name
);
121 DMWARN("unknown policy type");
122 return ERR_PTR(-EINVAL
);
125 p
= type
->create(cache_size
, origin_size
, cache_block_size
);
128 return ERR_PTR(-ENOMEM
);
134 EXPORT_SYMBOL_GPL(dm_cache_policy_create
);
136 void dm_cache_policy_destroy(struct dm_cache_policy
*p
)
138 struct dm_cache_policy_type
*t
= p
->private;
143 EXPORT_SYMBOL_GPL(dm_cache_policy_destroy
);
145 const char *dm_cache_policy_get_name(struct dm_cache_policy
*p
)
147 struct dm_cache_policy_type
*t
= p
->private;
149 /* if t->real is set then an alias was used (e.g. "default") */
151 return t
->real
->name
;
155 EXPORT_SYMBOL_GPL(dm_cache_policy_get_name
);
157 const unsigned *dm_cache_policy_get_version(struct dm_cache_policy
*p
)
159 struct dm_cache_policy_type
*t
= p
->private;
163 EXPORT_SYMBOL_GPL(dm_cache_policy_get_version
);
165 size_t dm_cache_policy_get_hint_size(struct dm_cache_policy
*p
)
167 struct dm_cache_policy_type
*t
= p
->private;
171 EXPORT_SYMBOL_GPL(dm_cache_policy_get_hint_size
);
173 /*----------------------------------------------------------------*/