📄 dm-target.c
字号:
/* * Copyright (C) 2001 Sistina Software (UK) Limited * * This file is released under the GPL. */#include "dm.h"#include <linux/module.h>#include <linux/init.h>#include <linux/kmod.h>#include <linux/bio.h>#include <linux/slab.h>#define DM_MSG_PREFIX "target"struct tt_internal { struct target_type tt; struct list_head list; long use;};static LIST_HEAD(_targets);static DECLARE_RWSEM(_lock);#define DM_MOD_NAME_SIZE 32static inline struct tt_internal *__find_target_type(const char *name){ struct tt_internal *ti; list_for_each_entry (ti, &_targets, list) if (!strcmp(name, ti->tt.name)) return ti; return NULL;}static struct tt_internal *get_target_type(const char *name){ struct tt_internal *ti; down_read(&_lock); ti = __find_target_type(name); if (ti) { if ((ti->use == 0) && !try_module_get(ti->tt.module)) ti = NULL; else ti->use++; } up_read(&_lock); return ti;}static void load_module(const char *name){ request_module("dm-%s", name);}struct target_type *dm_get_target_type(const char *name){ struct tt_internal *ti = get_target_type(name); if (!ti) { load_module(name); ti = get_target_type(name); } return ti ? &ti->tt : NULL;}void dm_put_target_type(struct target_type *t){ struct tt_internal *ti = (struct tt_internal *) t; down_read(&_lock); if (--ti->use == 0) module_put(ti->tt.module); BUG_ON(ti->use < 0); 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, void *param), void *param){ struct tt_internal *ti; down_read(&_lock); list_for_each_entry (ti, &_targets, list) iter_func(&ti->tt, param); up_read(&_lock); return 0;}int dm_register_target(struct target_type *t){ int rv = 0; struct tt_internal *ti = alloc_target(t); if (!ti) return -ENOMEM; down_write(&_lock); if (__find_target_type(t->name)) rv = -EEXIST; else list_add(&ti->list, &_targets); up_write(&_lock); if (rv) kfree(ti); return rv;}int dm_unregister_target(struct target_type *t){ struct tt_internal *ti; down_write(&_lock); if (!(ti = __find_target_type(t->name))) { up_write(&_lock); return -EINVAL; } if (ti->use) { up_write(&_lock); return -ETXTBSY; } list_del(&ti->list); kfree(ti); up_write(&_lock); return 0;}/* * io-err: always fails an io, useful for bringing * up LVs that have holes in them. */static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args){ return 0;}static void io_err_dtr(struct dm_target *ti){ /* empty */}static int io_err_map(struct dm_target *ti, struct bio *bio, union map_info *map_context){ return -EIO;}static struct target_type error_target = { .name = "error", .version = {1, 0, 1}, .ctr = io_err_ctr, .dtr = io_err_dtr, .map = io_err_map,};int __init dm_target_init(void){ return dm_register_target(&error_target);}void dm_target_exit(void){ if (dm_unregister_target(&error_target)) DMWARN("error target unregistration failed");}EXPORT_SYMBOL(dm_register_target);EXPORT_SYMBOL(dm_unregister_target);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -