一切皆文件之块设备驱动(二)
- 文件系统
- 2023-06-03
- 188热度
- 0评论
打开块设备
mknod
块设备同样要使用mknod创建设备节点,这与字符设备一样。会调用到init_special_inode填充inode的file_operations,只不过块设备注册的是def_blk_fops。
void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
{
inode->i_mode = mode;
if (S_ISCHR(mode)) {
inode->i_fop = &def_chr_fops;
inode->i_rdev = rdev;
} else if (S_ISBLK(mode)) {
inode->i_fop = &def_blk_fops;
inode->i_rdev = rdev;
} else if (S_ISFIFO(mode))
inode->i_fop = &pipefifo_fops;
else if (S_ISSOCK(mode))
; /* leave it no_open_fops */
else
printk(KERN_DEBUG "init_special_inode: bogus i_mode (
" inode
inode->i_ino);
}
def_blk_fops如下,与字符设备一样,当打开块设备时,就会调用到blk_dev_open。
const struct file_operations def_blk_fops = {
.open = blkdev_open,
.release = blkdev_close,
.llseek = blkdev_llseek,
.read_iter = blkdev_read_iter,
.write_iter = blkdev_write_iter,
.iopoll = blkdev_iopoll,
.mmap = generic_file_mmap,
.fsync = blkdev_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_blkdev_ioctl,
#endif
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = blkdev_fallocate,
}
blk_dev_open
blk_dev_open里面关键的操作时调用blkdev_get获取到块设备,并赋值file中f_mapping。
static int blkdev_open(struct inode *inode, struct file *filp)
{
struct block_device *bdev;
......
bdev = blkdev_get_by_dev(inode->i_rdev, filp->f_mode, filp);
if (IS_ERR(bdev))
return PTR_ERR(bdev);
filp->f_mapping = bdev->bd_inode->i_mapping;
filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping);
return 0;
}
bdev文件系统
blk_dev_open调用blkdev_get_by_dev获取到块设备得bdev,获取块设备是通过bdev文件系统来查询获取,下面先来了解下bdev文件系统的注册过程。
bdev是系统注册是在系统启动初始化阶段调用bdev_cache_init注册的,每个块设备在bdev文件系统中都有一个inode,linux利用block_inode数据结构将inode和block_device进行关联起来,对设备block_device的查找转化为在bdev文件系统中对inode的查找。