我写了一个简单的FS,它只应该静态包含一个名为hello
的文件。该文件应包含字符串Hello, world!
。我这样做是出于教育目的。虽然安装了fs,但它实际上表现得像预期的那样。我可以很好地阅读该文件。
然而,在卸载后我总是得到
VFS: Busy inodes after unmount of dummyfs. Self-destruct in 5 seconds. Have a nice day...
如果我在安装fs的时候在rootdir上调用了ls,我得到了
BUG: Dentry (ptrval){i=2,n=hello} still in use (-1) [unmount of dummyfs dummyfs]
最重要的是。
这是什么意思,我该如何解决?
mount和kill_sb例程调用mount_nodev并为包含此FS使用的2个inode的结构分配空间。
static struct dentry *dummyfs_mount(struct file_system_type* fs_type,
int flags, const char* dev_name, void* data)
{
struct dentry *ret;
ret = mount_nodev(fs_type, flags, data, dummyfs_fill_super);
if (IS_ERR(ret)) {
printk(KERN_ERR "dummyfs_mount failed");
}
return ret;
}
static void dummyfs_kill_sb(struct super_block *sb) {
kfree(sb->s_fs_info);
kill_litter_super(sb);
}
fill superblock方法创建2个inode并将它们保存在mount:
分配的struct中static int dummyfs_fill_super(struct super_block *sb, void *data, int flags)
{
struct dummyfs_info *fsi;
sb->s_magic = DUMMYFS_MAGIC;
sb->s_op = &dummyfs_sops;
fsi = kzalloc(sizeof(struct dummyfs_info), GFP_KERNEL);
sb->s_fs_info = fsi;
fsi->root = new_inode(sb);
fsi->root->i_ino = 1;
fsi->root->i_sb = sb;
fsi->root->i_op = &dummyfs_iops;
fsi->root->i_fop = &dummyfs_dops;
fsi->root->i_atime = fsi->root->i_mtime = fsi->root->i_ctime = current_time(fsi->root);
inode_init_owner(fsi->root, NULL, S_IFDIR);
fsi->file = new_inode(sb);
fsi->file->i_ino = 2;
fsi->file->i_sb = sb;
fsi->file->i_op = &dummyfs_iops;
fsi->file->i_fop = &dummyfs_fops;
fsi->file->i_atime = fsi->file->i_mtime = fsi->file->i_ctime = current_time(fsi->file);
inode_init_owner(fsi->file, fsi->root, S_IFREG);
sb->s_root = d_make_root(fsi->root);
return 0;
}
如果父目录是根目录,则查找方法只会将fsi->file_inode
添加到dentry:
if (parent_inode->i_ino == fsi->root->i_ino) {
d_add(child_dentry, fsi->file);
}
迭代方法在调用时只发出点文件和hello
文件:
if (ctx->pos == 0) {
dir_emit_dots(file, ctx);
ret = 0;
}
if (ctx->pos == 2) {
dir_emit(ctx, "hello", 5, file->f_inode->i_ino, DT_UNKNOWN);
++ctx->pos;
ret = 0;
}
read方法只使用copy_to_user
编写静态字符串。正确计算偏移量,并且在EOF上,方法只返回0.但是,即使没有调用read方法也会出现问题,我认为这已经超出了这个已经太长的问题了。
对于实际运行它,我使用git master中的用户模式linux(4.15 + x commit d48fcbd864a008802a90c58a9ceddd9436d11a49
)。 userland是从头开始编译的,init进程是Rich Felker的最小init的派生,我为mount
,/proc
和/sys
(remount)添加了/
个调用。
我的命令行是./linux ubda=../uml/image root=/dev/ubda
对于更全面的文档的任何指示也表示赞赏。
答案 0 :(得分:1)
使用gdb观看dentry->d_lockref.count
我意识到umount中的kill_litter_super
调用实际上是导致dentry问题的原因。用kill_anon_super
替换它解决了这个问题。
繁忙的inode问题消失得太多了,除非我在安装后立即卸载。分配第二个inode懒惰地解决了这个问题。