我正在尝试实现一个非常简单的文件系统驱动程序内核模块。它所要做的就是在挂载文件夹中创建一个文件,并为其提供对挂载设备的读/写访问权限。让我们有一个循环设备,它连接到某个文件。然后,如果该设备使用新的文件系统类型安装到某个目录,用户将能够使用单个文件系统文件作为一种接口读取/写入/修改连接到循环的文件。应该使用内存页面机制来实现对文件的访问。
到目前为止,我已经成功创建了一个 FS 单个文件。我有根目录的 inode 和 dentries 以及根文件夹中的一个文件。现在我需要提供文件访问的操作。所以,我创建了一个file_operations
类型结构来用作我的文件inode->f_ops
。它有read/write/aio_read/aio_write
函数,但read
函数只是调用do_sync_read
并且aio_read
是一个generic_file_aio_read
. 写作也是如此。
static struct file_operations fs_file_ops = {
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.write = do_sync_write,
.aio_write = generic_file_aio_write,
}
另外,我创建了一个address_space_operations
结构来用作inode->i_mapping->a_ops
. 它具有readpage
和writepage
功能。我的readpage
实现调用mpage_readpage
标准函数。mpage_readpage
用readpage
page
参数和get_block
函数调用。
static struct address_space_operations fs_aops = {
.readpage = fs_readpage,
.writepage = fs_writepage
};
static int fs_readpage(struct file *file, struct page *page)
{
return mpage_readpage(page, fs_get_block);
}
get_block
函数将超级块映射到缓冲区并为内存页面处理提供块,它以以下方式实现:
static int fs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, int create)
{
map_bh(bh, inode->i_sb, block);
size_t i_b_size = bh->b_size >> inode->i_blkbits;
size_t r_b_size = i_size_read(inode) >> inode->i_blkbits - block;
bh->b_size = min(i_b_size, r_b_size) << inode->i_blkbits;
return 0;
}
因此,当用户试图从文件中读取某些内容时,do_sync_read
会调用它,它使用generic_file_aio_read
. 它调用readpage
函数,readpage
函数调用mpage_readpage
,它fs_get_block
作为一个参数,为页面提供一个块。这个函数应该实现逐页读取文件。
问题是,目前我还没有设法从 FS 文件中获得所需的输出。那么,我的实施有什么问题?如果它不完整,那么我还应该在我的模块中实现哪些功能以使其工作?或者,也许问题出在我的get_block
?