Linux tmpfs的使用问题解析
在不同的版本系统查看tmpfs分区的情况,有的可以查询到,有的则不行且不报错。如df命令,对于正常的结果如下:
tmpfs 15360 96 15264 1% /var
异常情况,则不会有该条目。
尝试编译测试程序利用statfs获取挂载点的空间使用情况,在异常的情况下空间数据为0。
测试程序过程为:
1)stat获取挂载点文件类型 if ((s.st_mode & S_IFMT) == S_IFBLK) mountDevice = s.st_rdev; else mountDevice = s.st_dev;
2)通过setmntent、getmntent、endmntent组合函数从/proc/mounts下找寻匹配的mntent节点,确定挂载点是在合法范围的
3)statfs通过挂载点路径,获取挂载分区的属性数据测试程序本身应该没有问题,在正常版本下可以获取正确的数据。跟踪statfs的调用流程:SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs__user *, buf)->static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf)->int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)->retval = dentry->d_sb->s_op->statfs(dentry, buf);
从这里,有理由怀疑异常版本的tmpfs实现有问题,实现在shmem.c中,打开会发现其中有很多宏,有些实现是按宏区分为2份,比如与本问题相关的shmem_ops,
``` C
1)static const struct super_operations shmem_ops;/*只是1个定义未初始化*/
2)/*statfs被实现且被CONFIG_TMPFS管理*/
static const struct super_operations shmem_ops = {
.alloc_inode = shmem_alloc_inode,
.destroy_inode = shmem_destroy_inode,
#ifdef CONFIG_TMPFS
.statfs = shmem_statfs,
.remount_fs = shmem_remount_fs,
.show_options = shmem_show_options,
#endif
.delete_inode = shmem_delete_inode,
.drop_inode = generic_delete_inode,
.put_super = shmem_put_super,
};
```
找到另外1个相关的宏CONFIG_SHMEM,并打开,重新编译版本,验证OK。shmem.c是被默认编入内核的,但其具体功能可能会由于控制宏开关的不同而表现不同。比如:在CONFIG_SHMEM和CONFIG_TMPFS均关闭的情况下,我们是可以使用tmpfs进行内存分区挂载的,但即使我们制定其挂载大小,对挂载分区的使用也是不会受限,会一致消耗内存直至无内存可用。