我正在WrapFS中实现地址空间操作,我试图模仿现有ecryptfs文件系统源代码,因为我的目标是最终实现加密文件系统。下面给出的代码实现非常适用于readpage()
,write_begin()
和write_end()
,但writepage()
未执行,因此当我尝试通过此文件系统复制大文件时复制大约300 MB的文件后它会卡住。
static int wrapfs_writepage(struct page *page, struct writeback_control *wbc)
{
int err = -EIO;
struct inode *inode;
struct inode *lower_inode;
struct page *lower_page;
struct address_space *lower_mapping; /* lower inode mapping */
gfp_t mask;
printk(KERN_INFO "in wrapfs_writepage");
BUG_ON(!PageUptodate(page));
inode = page->mapping->host;
/* if no lower inode, nothing to do */
if (!inode || !WRAPFS_I(inode) || WRAPFS_I(inode)->lower_inode) {
err = 0;
goto out;
}
lower_inode = wrapfs_lower_inode(inode);
lower_mapping = lower_inode->i_mapping;
mask = mapping_gfp_mask(lower_mapping) & ~(__GFP_FS);
lower_page = find_or_create_page(lower_mapping, page->index, mask);
if (!lower_page) {
err = 0;
set_page_dirty(page);
goto out;
}
/* copy page data from our upper page to the lower page */
copy_highpage(lower_page, page);
flush_dcache_page(lower_page);
SetPageUptodate(lower_page);
set_page_dirty(lower_page);
if (wbc->for_reclaim) {
unlock_page(lower_page);
goto out_release;
}
BUG_ON(!lower_mapping->a_ops->writepage);
wait_on_page_writeback(lower_page); /* prevent multiple writers */
clear_page_dirty_for_io(lower_page); /* emulate VFS behavior */
err = lower_mapping->a_ops->writepage(lower_page, wbc);
if (err < 0)
goto out_release;
if (err == AOP_WRITEPAGE_ACTIVATE) {
err = 0;
unlock_page(lower_page);
}
out_release:
/* b/c find_or_create_page increased refcnt */
page_cache_release(lower_page);
out:
/*
* We unlock our page unconditionally, because we never return
* AOP_WRITEPAGE_ACTIVATE.
*/
unlock_page(page);
return err;
}
我已正确声明了address_space_operation对象。