设备映射器驱动程序中的源代码将满足您的需要。在 Linux/drivers/md/dm-* 中查看 Linux 源码中的代码。
您不需要访问其他设备的 gendisk 结构,而是访问它的请求队列。您可以准备 I/O 请求并将其推送到其他设备的队列中,其余的将自己完成。
我已经实现了一个简单的块设备,可以打开另一个块设备。看看我描述它的帖子:
stackbd: Stacking a block device over another block device
以下是访问其他设备的 gendisk 所需的一些功能示例。使用路径(“/dev/”)打开另一个块设备的方法:
struct block_device *bdev_raw = lookup_bdev(dev_path);
printk("Opened %s\n", dev_path);
if (IS_ERR(bdev_raw))
{
printk("stackbd: error opening raw device <%lu>\n", PTR_ERR(bdev_raw));
return NULL;
}
if (!bdget(bdev_raw->bd_dev))
{
printk("stackbd: error bdget()\n");
return NULL;
}
if (blkdev_get(bdev_raw, STACKBD_BDEV_MODE, &stackbd))
{
printk("stackbd: error blkdev_get()\n");
bdput(bdev_raw);
return NULL;
}
将 I/O 请求从一台设备传递到另一台设备的最简单示例是在不修改的情况下重新映射它。请注意,在以下代码中,bi_bdev条目已使用不同的设备进行了修改。还可以修改块地址(*bi_sector)和数据本身。
static void stackbd_io_fn(struct bio *bio)
{
bio->bi_bdev = stackbd.bdev_raw;
trace_block_bio_remap(bdev_get_queue(stackbd.bdev_raw), bio,
bio->bi_bdev->bd_dev, bio->bi_sector);
/* No need to call bio_endio() */
generic_make_request(bio);
}