|
小弟用fist工具开发了一个堆叠式的加密文件系统,但在mount的时候不成功,然后dmesg显示,“kcfs_read_super: missing data argument”错误,kcfs为文件系统模块名:找该函数的代码如下:
kcfs_read_super(super_block_t *sb, void *raw_data, int silent)
{
struct dentry *lower_root = NULL;
struct vfsmount *lower_mount = NULL;
int err = 0;
print_entry_location();
#ifdef FIST_MALLOC_DEBUG
atomic_set(&kcfs_malloc_counter, 0); /* for malloc debugging */
#endif /* FIST_MALLOC_DEBUG */
if (!raw_data) {
printk(KERN_WARNING "kcfs_read_super: missing data argument\n");
err = -EINVAL;
goto out_no_raw;
}
/*
* Allocate superblock private data
*/
SUPERBLOCK_TO_PRIVATE_SM(sb) = KMALLOC(sizeof(struct kcfs_sb_info), GFP_KERNEL);
if (!SUPERBLOCK_TO_PRIVATE(sb)) {
printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
err = -ENOMEM;
goto out;
}
memset(SUPERBLOCK_TO_PRIVATE(sb), 0, sizeof(struct kcfs_sb_info));
if ((err = kcfs_parse_options(sb, raw_data, &lower_root, &lower_mount))) {
goto out_free;
}
if (IS_ERR(lower_root)) {
printk(KERN_WARNING "kcfs_read_super: lookup_dentry failed (err = %ld)\n", PTR_ERR(lower_root));
err = PTR_ERR(lower_root);
goto out_free;
}
if (!lower_root->d_inode) {
printk(KERN_WARNING "kcfs_read_super: no directory to interpose on\n");
goto out_dput;
}
SUPERBLOCK_TO_LOWER(sb) = lower_root->d_sb;
sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
sb->s_op = &kcfs_sops;
/*
* we can't use d_alloc_root if we want to use
* our own interpose function unchanged,
* so we simply replicate *most* of the code in d_alloc_root here
*/
sb->s_root = d_alloc(NULL, &(const struct qstr){hash: 0, name: "/", len: 1});
if (IS_ERR(sb->s_root)) {
printk(KERN_WARNING "kcfs_read_super: d_alloc failed\n");
err = -ENOMEM;
goto out_dput;
}
sb->s_root->d_op = &kcfs_dops;
sb->s_root->d_sb = sb;
sb->s_root->d_parent = sb->s_root;
/* link the upper and lower dentries */
DENTRY_TO_PRIVATE_SM(sb->s_root) = (struct kcfs_dentry_info *) KMALLOC(sizeof(struct kcfs_dentry_info), GFP_KERNEL);
if (!DENTRY_TO_PRIVATE(sb->s_root)) {
err = -ENOMEM;
goto out_dput2;
}
DENTRY_TO_LOWER(sb->s_root) = lower_root;
DENTRY_TO_LVFSMNT(sb->s_root) = lower_mount;
if ((err = kcfs_interpose(lower_root, sb->s_root, sb, 0)) != 0)
goto out_dput2;
fist_print_dentry("kcfs_read_super OUT lower_dentry", lower_root);
fist_print_inode("kcfs_read_super OUT lower_inode", lower_root->d_inode);
// next line causes null ptr deref at mount(2) time
// fist_print_dentry("%s OUT sb->s_root", __FUNCTION__, sb->s_root);
goto out;
out_dput2:
dput(sb->s_root);
out_dput:
dput(lower_root);
out_free:
// XXX: HL: is that mntput necessary? There is some relation to the path_walk in parse_options -
// there the path_release is "missing"
mntput(lower_mount);
KFREE(SUPERBLOCK_TO_PRIVATE(sb));
SUPERBLOCK_TO_PRIVATE_SM(sb) = NULL;
out:
fist_print_sb("OUT sb", sb);
if (SUPERBLOCK_TO_PRIVATE(sb))
fist_print_sb("OUT lower_sb", SUPERBLOCK_TO_LOWER(sb));
out_no_raw:
print_exit_location();
return err;
}
请各位前辈帮帮忙,怎么解决? |
|