1

我正在尝试实现一个非常简单的文件系统驱动程序内核模块。它所要做的就是在挂载文件夹中创建一个文件,并为其提供对挂载设备的读/写访问权限。让我们有一个循环设备,它连接到某个文件。然后,如果该设备使用新的文件系统类型安装到某个目录,用户将能够使用单个文件系统文件作为一种接口读取/写入/修改连接到循环的文件。应该使用内存页面机制来实现对文件的访问。

到目前为止,我已经成功创建了一个 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. 它具有readpagewritepage功能。我的readpage实现调用mpage_readpage标准函数。mpage_readpagereadpage 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?

4

0 回答 0