linux内核块设备,从内核模块访问块设备 - linux-kernel代码 - 源码查

问题

I am interested in developing kernel module that binds two block devices into a new block device in such manner that first block device contains data at mount time, and the other is considered empty. Every write is being made to second partition, so on next mount the base filesystem remains unchanged. I know of solutions like UnionFS, but those are filesystem-based, while i want to develop it a layer lower, block-based.

Can anyone tell me how could i open ad read/write block device from kernel module? Possibly without using userspace program for reading/writing merged block devices. I found similar topic here, but the answer was rather unsatysfying because filp_* functions are rather for reading small config files, not for (large) block device I/O.

Since interface for creating block devices is standarized i was thinking of direct (or almost direct) acces to functions implementing source devices, as i will be requested to export similar functions anyway. If i could do that i would simply create some proxy-functions calling appropriate functions on source devices. Can i somehow obtain pointer to a gendisk structure that belongs to different driver?

This serves only my own purposes (satisfying quriosity being main of them) so i am not worried about messing my kernel up seriously.

Or does somebody know if module like that already exists?

解决方法

The source code in the device mapper driver will suit your needs. Look at the code in the Linux source in Linux/drivers/md/dm-*.

You don't need to access the other device's gendisk structure, but rather its request queue. You can prepare I/O requests and push it down the other device's queue, and it will do the rest itself.

I have implemented a simple block device that opens another block device. Take a look in my post describing it:

stackbd: Stacking a block device over another block device

Here are some examples of functions that you need for accessing another device's gendisk.

The way to open another block device using its path ("/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 \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;

}

The simplest example of passing an I/O request from one device to another is by remapping it without modifying it. Notice in the following code that the bi_bdev entry is modified with a different device. One can also modify the block address (*bi_sector) and the data itself.

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);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值