Ras*_*ikh 5 linux-device-driver linux-kernel device-mapper
我试图通过引用已有的dm-linear,dm-snapshot,dm-cache等来实现设备映射器目标.在我的实现中,我需要对某个扇区范围执行读/修改/写操作.由于器件映射器直接与块层对话,我不确定用什么数据结构/函数来读取存储器中的扇区,修改缓冲区并将其写回另一个扇区范围.在应用程序级别,我们有系统调用,下面我们有vfs_read/vfs_write.设备映射器层有什么类似的东西吗?我被困在这里很久了.任何帮助将不胜感激.
注意:我的答案与内核版本<3.14有关,因为3.14 API略有改变.
在内核中,您可以读取/写入某些扇区struct bio.此结构用于所有块级I/O. 可以在内核和lwn中找到全面的文档.这些是该结构中几个最重要的成员:
bio->bi_sector - 块I/O请求的第一个扇区bio->bi_size - I/O请求的大小bio->bi_bdev - 读/写设备bio->bi_end_io - 内核将在请求结束时调用的回调您在设备映射器目标中执行的操作是映射传入bio.在创建设备映射器目标时,您至少提供2个回调:ctr和map.例如,最简单的device-mapper目标dm-zero声明它的回调如下:
static struct target_type zero_target = {
.name = "zero",
.version = {1, 1, 0},
.module = THIS_MODULE,
.ctr = zero_ctr,
.map = zero_map,
};
Run Code Online (Sandbox Code Playgroud)
map是一个关键的回调 - 它是每个设备映射器目标的核心.map收到来电bio,它可以做任何事情.例如,dm-linear只是将每个输入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;
}
Run Code Online (Sandbox Code Playgroud)
因为map接收指向bio它的指针可以改变该指针下的值,就是这样.
这就是你映射I/O请求的方式.如果要创建自己的请求,则必须分配bio,填充扇区,设备,大小,结束回调并添加缓冲区以读取/写入.基本上,它只是几个步骤:
bio->bi_bdev,bio->bi_sector,bio->bi_size,bio->bi_end_iobio_add_page.submit_bio.bio->bi_end_io回调中的结果和错误示例可以在函数中的dm-crypt目标中找到crypt_alloc_buffer.
| 归档时间: |
|
| 查看次数: |
1931 次 |
| 最近记录: |