这个文件系统的介绍,已经尝试写过了几篇,总感觉不知道如何入门,如何讲起,如果从inode,超级块将其感觉有讲的不透彻,这样还是按照书的标准来,上一节介绍文件系统的几个重要的数据结构,我也不觉得看了上一节就会明白文件系统是什么了,所以这一章开始,尝试着分析一个最简单的文件系统的源码ramfs.
2.1 ramfs简介
ramfs是Linux下一种基于RAM做存储的文件系统。在使用过程中你就可以把ramfs理解为在普通的HDD上建立了一个文件系统,而现在HDD被替换成了RAM,因为是RAM做存储所以会有很高的存储效率。由于ramfs的实现就相当于把RAM作为最后一层的存储,所以在ramfs中不会使用swap。你什么时候听过会把HDD上的文件swap到哪里去吗?平常说的swap都是针对内存来说的,而ramfs底层的存储是RAM,虽然不是HDD,但是在Linux看来它就跟HDD一样。但是ramfs有一个很大的缺陷就是它会吃光系统所有的内存,即使你mount的时候指定了大小,同时它也只能被root用户访问。
概念这东西我也是百度,这里贴一下我百度的网址:Linux: 内存文件系统 ramfs
2.2 ramfs源码介绍
简介看完了,那剩下就直接上源码了,作为工程师都比较喜欢直接上源码的可能。
我们打开ramfs目录文件夹:(默认大家都是知道怎么下载,编译内核了)

看到这么少的文件系统就开心,因为可以自己分析了。
我们知道内核是一个高度模块化的内核,搞过驱动的也知道,我们先找到init函数,看看在那里注册了文件系统,就3个文件,很快就找到了,就在inode.c文件中

做过驱动的是不是很亲切。
2.3 ramfs源码解析
做了前面的铺垫工作之后,接下来就要到高潮部分了,源码分析,源码分析会分为多个二级标题,尽量保存注册的方式来讲解。
2.3.1 文件系统注册
首先我们来到我们初始化函数:
int __init init_ramfs_fs(void)
{
static unsigned long once;
if (test_and_set_bit(0, &once)) //是保证一个文件系统的,
return 0;
return register_filesystem(&ramfs_fs_type); //这个就是往内核中注册文件系统
}
fs_initcall(init_ramfs_fs);
我们往内核方向继续追,看看是怎么登记的:
int register_filesystem(struct file_system_type * fs)
{
int res = 0;
struct file_system_type ** p;
BUG_ON(strchr(fs->name, '.'));
if (fs->next)
return -EBUSY;
write_lock(&file_systems_lock);
p = find_filesystem(fs->name, strlen(fs->name));
if (*p)
res = -EBUSY;
else
*p = fs;
write_unlock(&file_systems_lock);
return res;
}
EXPORT_SYMBOL(register_filesystem);
函数register_filesystem的参数是一个文件类型的指针,比较重要,之后会说,现在先跳过,这个文件系统注册比较重要的是find_filesystem函数,要先在内核维护的文件系统中寻找是否有相同名字的文件系统,如果不存在相同名字的文件系统,就把ramfs加入到系统的文件系统链表。如果存在,则返回忙。
我们接下来看看find_filesystem函数:
static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
struct file_system_type **p;
for (p=&file_systems; *p; p=&(*p)->next)
if (strlen((*p)->name) == len &&
strncmp((*p)->name, name, len) == 0)
break;
return p;
}
file_systems是内核维护的一个全局变量,用来保存所有登记的文件系统,static struct file_system_type *file_systems。
find_filesystem这个函数我们就看到在遍历查找内核中的文件系统。内核的文件系统的链表是通过next连起来的。
2.3.2 file_system_type数据
static struct file_system_type ramfs_fs_type = {
.name = "ramfs",
.mount = ramfs_mount,
.kill_sb = ramfs_kill_sb,
.fs_flags = FS_USERNS_MOUNT,
};
也没什么内容,一个name标注名字,一个mount,表示着使用mount命令会调用这个函数,怎么调用的过程,这篇文章不讲,以后再讲,kill_sb,umount调用的。
2.3.3 ramfs_mount函数
我们都知道,要使用一个文件系统,就要先mount,然后才能使用,现在就看看这个mount究竟做了什么?
struct dentry *ramfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_nodev(fs_type, flags, data, ramfs_fill_super);
}
我们在上一节也讲到,mount一个文件系统,就是要申请一个超级块,然后再往超级块中填数

&spm=1001.2101.3001.5002&articleId=108807335&d=1&t=3&u=82895f4e05dd48c6b46da2ce74ce5a7c)
1064

被折叠的 条评论
为什么被折叠?



