device-mapper.h
table的类型,mapped_device 的内存池和请求队列
enum dm_queue_mode {
DM_TYPE_NONE = 0,
DM_TYPE_BIO_BASED = 1,
DM_TYPE_REQUEST_BASED = 2,
DM_TYPE_MQ_REQUEST_BASED = 3,
DM_TYPE_DAX_BIO_BASED = 4,
};
一些函数原型如:
typedef int (dm_ctr_fn) (struct dm_target target,
unsigned int argc, char **argv);
/*
- The map function must return:
- < 0: error
- = 0: The target will handle the io by resubmitting it later
- = 1: simple remap complete
- = 2: The target wants to push back the io
/
typedef int (dm_map_fn) (struct dm_target ti, struct bio bio);
/*
- Returns:
- < 0 : error (currently ignored)
- 0 : ended successfully
- 1 : for some reason the io has still not completed (eg,
- multipath target might want to requeue a failed io).
- 2 : The target wants to push back the io
/
typedef int (dm_endio_fn) (struct dm_target *ti,struct bio *bio, int error);
target_type
struct target_type {
uint64_t features;
const char name;
struct module module;
unsigned version[3];
dm_ctr_fn ctr;
dm_dtr_fn dtr;
dm_map_fn map;
dm_map_request_fn map_rq;
dm_clone_and_map_request_fn clone_and_map_rq;
dm_release_clone_request_fn release_clone_rq;
dm_endio_fn end_io;
dm_request_endio_fn rq_end_io;
dm_presuspend_fn presuspend;
dm_presuspend_undo_fn presuspend_undo;
dm_postsuspend_fn postsuspend;
dm_preresume_fn preresume;
dm_resume_fn resume;
dm_status_fn status;
dm_message_fn message;
dm_prepare_ioctl_fn prepare_ioctl;
dm_merge_fn merge;
dm_busy_fn busy;
dm_iterate_devices_fn iterate_devices;
dm_io_hints_fn io_hints;
dm_dax_direct_access_fn direct_access;
dm_dax_memcpy_fromiovecend_fn dax_memcpy_fromiovecend;
dm_dax_memcpy_toiovecend_fn dax_memcpy_toiovecend;
/* For internal device-mapper use. */
struct list_head list;
};
2020-4-5
从devicemapper 初始化开始看:
在dm-ioctl.c中
创建混杂设备(混杂设备是一种字符设备):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20int __init dm_interface_init(void)
{
int r;
r = dm_hash_init();
if (r)
return r;
r = misc_register(&_dm_misc); //注册混杂设备
if (r) {
DMERR("misc_register failed for control device");
dm_hash_exit();
return r;
}
DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR,
DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA,
DM_DRIVER_EMAIL);
return 0;
}
在dm.c 调用并初始化1
2
3
4
5
6static struct miscdevice _dm_misc = {
.minor = MAPPER_CTRL_MINOR,
.name = DM_NAME,
.nodename = DM_DIR "/" DM_CONTROL_NODE,
.fops = &_ctl_fops //设置混杂设备的一些操作
};
混杂设备具体的操作:1
2
3
4
5
6
7
8
9static const struct file_operations _ctl_fops = {
.open = dm_open,
.release = dm_release,
.poll = dm_poll,
.unlocked_ioctl = dm_ctl_ioctl,
.compat_ioctl = dm_compat_ctl_ioctl,
.owner = THIS_MODULE,
.llseek = noop_llseek,
};
在dm_ctl_ioctl中实现具体的ioctl操作
dm_ctl_ioctl() -> ctl_ioctl() -> lookup_ioctl() //查找对应的ioctl操作
在 ctl_ioctl中执行对应的ioctl操作
1 | static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags) |
看一下创建一个mapping device的过程:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31static int dev_create(struct file *filp, struct dm_ioctl *param, size_t param_size)
{
int r, m = DM_ANY_MINOR;
struct mapped_device *md;
r = check_name(param->name);
if (r)
return r;
if (param->flags & DM_PERSISTENT_DEV_FLAG)
m = MINOR(huge_decode_dev(param->dev));
r = dm_create(m, &md);
if (r)
return r;
r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
if (r) {
dm_put(md);
dm_destroy(md);
return r;
}
param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
__dev_status(md, param);
dm_put(md);
return 0;
}