提交 45194e4f 编写于 作者: C Cheng Renquan 提交者: Alasdair G Kergon

dm target: remove struct tt_internal

The tt_internal is really just a list_head to manage registered target_type
in a double linked list,

Here embed the list_head into target_type directly,
1. to avoid kmalloc/kfree;
2. then tt_internal is really unneeded;

Cc: stable@kernel.org
Signed-off-by: NCheng Renquan <crquan@gmail.com>
Signed-off-by: NAlasdair G Kergon <agk@redhat.com>
Reviewed-by: NAlasdair G Kergon <agk@redhat.com>
上级 570b9d96
...@@ -14,40 +14,34 @@ ...@@ -14,40 +14,34 @@
#define DM_MSG_PREFIX "target" #define DM_MSG_PREFIX "target"
struct tt_internal {
struct target_type tt;
struct list_head list;
};
static LIST_HEAD(_targets); static LIST_HEAD(_targets);
static DECLARE_RWSEM(_lock); static DECLARE_RWSEM(_lock);
#define DM_MOD_NAME_SIZE 32 #define DM_MOD_NAME_SIZE 32
static inline struct tt_internal *__find_target_type(const char *name) static inline struct target_type *__find_target_type(const char *name)
{ {
struct tt_internal *ti; struct target_type *tt;
list_for_each_entry (ti, &_targets, list) list_for_each_entry(tt, &_targets, list)
if (!strcmp(name, ti->tt.name)) if (!strcmp(name, tt->name))
return ti; return tt;
return NULL; return NULL;
} }
static struct tt_internal *get_target_type(const char *name) static struct target_type *get_target_type(const char *name)
{ {
struct tt_internal *ti; struct target_type *tt;
down_read(&_lock); down_read(&_lock);
ti = __find_target_type(name); tt = __find_target_type(name);
if (ti && !try_module_get(ti->tt.module)) if (tt && !try_module_get(tt->module))
ti = NULL; tt = NULL;
up_read(&_lock); up_read(&_lock);
return ti; return tt;
} }
static void load_module(const char *name) static void load_module(const char *name)
...@@ -57,83 +51,59 @@ static void load_module(const char *name) ...@@ -57,83 +51,59 @@ static void load_module(const char *name)
struct target_type *dm_get_target_type(const char *name) struct target_type *dm_get_target_type(const char *name)
{ {
struct tt_internal *ti = get_target_type(name); struct target_type *tt = get_target_type(name);
if (!ti) { if (!tt) {
load_module(name); load_module(name);
ti = get_target_type(name); tt = get_target_type(name);
} }
return ti ? &ti->tt : NULL; return tt;
} }
void dm_put_target_type(struct target_type *t) void dm_put_target_type(struct target_type *tt)
{ {
struct tt_internal *ti = (struct tt_internal *) t;
down_read(&_lock); down_read(&_lock);
module_put(ti->tt.module); module_put(tt->module);
up_read(&_lock); up_read(&_lock);
return;
} }
static struct tt_internal *alloc_target(struct target_type *t)
{
struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
if (ti)
ti->tt = *t;
return ti;
}
int dm_target_iterate(void (*iter_func)(struct target_type *tt, int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param) void *param), void *param)
{ {
struct tt_internal *ti; struct target_type *tt;
down_read(&_lock); down_read(&_lock);
list_for_each_entry (ti, &_targets, list) list_for_each_entry(tt, &_targets, list)
iter_func(&ti->tt, param); iter_func(tt, param);
up_read(&_lock); up_read(&_lock);
return 0; return 0;
} }
int dm_register_target(struct target_type *t) int dm_register_target(struct target_type *tt)
{ {
int rv = 0; int rv = 0;
struct tt_internal *ti = alloc_target(t);
if (!ti)
return -ENOMEM;
down_write(&_lock); down_write(&_lock);
if (__find_target_type(t->name)) if (__find_target_type(tt->name))
rv = -EEXIST; rv = -EEXIST;
else else
list_add(&ti->list, &_targets); list_add(&tt->list, &_targets);
up_write(&_lock); up_write(&_lock);
if (rv)
kfree(ti);
return rv; return rv;
} }
void dm_unregister_target(struct target_type *t) void dm_unregister_target(struct target_type *tt)
{ {
struct tt_internal *ti;
down_write(&_lock); down_write(&_lock);
if (!(ti = __find_target_type(t->name))) { if (!__find_target_type(tt->name)) {
DMCRIT("Unregistering unrecognised target: %s", t->name); DMCRIT("Unregistering unrecognised target: %s", tt->name);
BUG(); BUG();
} }
list_del(&ti->list); list_del(&tt->list);
kfree(ti);
up_write(&_lock); up_write(&_lock);
} }
...@@ -142,17 +112,17 @@ void dm_unregister_target(struct target_type *t) ...@@ -142,17 +112,17 @@ void dm_unregister_target(struct target_type *t)
* io-err: always fails an io, useful for bringing * io-err: always fails an io, useful for bringing
* up LVs that have holes in them. * up LVs that have holes in them.
*/ */
static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args) static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
{ {
return 0; return 0;
} }
static void io_err_dtr(struct dm_target *ti) static void io_err_dtr(struct dm_target *tt)
{ {
/* empty */ /* empty */
} }
static int io_err_map(struct dm_target *ti, struct bio *bio, static int io_err_map(struct dm_target *tt, struct bio *bio,
union map_info *map_context) union map_info *map_context)
{ {
return -EIO; return -EIO;
......
...@@ -60,7 +60,7 @@ int dm_table_barrier_ok(struct dm_table *t); ...@@ -60,7 +60,7 @@ int dm_table_barrier_ok(struct dm_table *t);
int dm_target_init(void); int dm_target_init(void);
void dm_target_exit(void); void dm_target_exit(void);
struct target_type *dm_get_target_type(const char *name); struct target_type *dm_get_target_type(const char *name);
void dm_put_target_type(struct target_type *t); void dm_put_target_type(struct target_type *tt);
int dm_target_iterate(void (*iter_func)(struct target_type *tt, int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param); void *param), void *param);
......
...@@ -139,6 +139,9 @@ struct target_type { ...@@ -139,6 +139,9 @@ struct target_type {
dm_ioctl_fn ioctl; dm_ioctl_fn ioctl;
dm_merge_fn merge; dm_merge_fn merge;
dm_busy_fn busy; dm_busy_fn busy;
/* For internal device-mapper use. */
struct list_head list;
}; };
struct io_restrictions { struct io_restrictions {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册