我试图通过引用现有的dm-线性、dm-快照、dm-cache等实现设备映射器目标。在我的实现中,我需要在某个扇区范围内执行读/修改/写操作。由于设备映射器直接与块层对话,我不确定要使用什么数据结构/函数来读取内存中的扇区,修改缓冲区并将其写回另一个扇区范围。在应用程序级别,我们有syscalls,下面是vfs_read/vfs_write。设备映射层有类似的地方吗?我被困在这里很久了。任何帮助都将不胜感激。
发布于 2014-06-16 08:18:57
注意:我的答案与内核版本< 3.14有关,因为3.14API略有变化。
在内核中,您可以使用struct bio读写某些扇区。此结构用于所有块级I/O。综合文档可以在内核中和奥恩上找到。这些是这一结构中最重要的几个成员:
bio->bi_sector -块I/O请求的第一扇区bio->bi_size - I/O请求的大小bio->bi_bdev -读写设备bio->bi_end_io -内核将在请求结束时调用的回调在设备映射器目标中所做的工作是映射传入的创建设备映射器目标时,至少提供两个回调:ctr和map。例如,最简单的设备映射器目标dm声明它是回调如下所示
static struct target_type zero_target = {
.name = "zero",
.version = {1, 1, 0},
.module = THIS_MODULE,
.ctr = zero_ctr,
.map = zero_map,
};map是一个关键的回调--它是每个设备映射器目标的心脏。map接收传入的bio,它可以使用它做任何事情。例如,dm线性只通过预先定义的偏移量移动每个传入bio的移位扇区.见守则:
static sector_t linear_map_sector(struct dm_target *ti, sector_t bi_sector)
{
struct linear_c *lc = ti->private;
return lc->start + dm_target_offset(ti, bi_sector);
}
static void linear_map_bio(struct dm_target *ti, struct bio *bio)
{
struct linear_c *lc = ti->private;
bio->bi_bdev = lc->dev->bdev;
if (bio_sectors(bio))
bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
}
static int linear_map(struct dm_target *ti, struct bio *bio)
{
linear_map_bio(ti, bio);
return DM_MAPIO_REMAPPED;
}因为map接收到指向bio的指针,所以它可以在该指针下更改值,仅此而已。
这就是映射I/O请求的方式。如果您想要创建自己的请求,那么您必须分配bio,填充它的扇区、设备、大小、结束回调和添加缓冲区来读取/写入。基本上,这只是几个步骤:
bio->bi_bdev,bio->bi_sector,bio->bi_size,bio->bi_end_io于一身bio_add_page添加页面。submit_bio。bio->bi_end_io回调中的结果和错误例子可以在crypt_alloc_buffer函数中的dm-crypt目标中找到.
https://stackoverflow.com/questions/24214289
复制相似问题