c语言sscanf函数的用法是什么
260
2022-11-15
linux 虚拟文件可以系统实现
虚拟文件系统本身是linux内核的一部分,是纯软件的东西,并不需要任何硬件的支持。
1. 虚拟文件系统的作用
虚拟文件系统(VFS)是linux内核和存储设备之间的抽象层,主要有以下好处。
- 简化了应用程序的开发:应用通过统一的系统调用访问各种存储介质
- 简化了新文件系统加入内核的过程:新文件系统只要实现VFS的各个接口即可,不需要修改内核部分
2. 虚拟文件系统的4个主要对象
虚拟文件中的4个主要对象,具体每个对象的含义参见如下的详细介绍。
2.1 超级块
超级块(super_block)主要存储文件系统相关的信息,这是个针对文件系统级别的概念。
它一般存储在磁盘的特定扇区中,但是对于那些基于内存的文件系统(比如proc,sysfs),超级块是在使用时创建在内存中的。
超级块的定义在:
2.2 索引节点
索引节点是VFS中的核心概念,它包含内核在操作文件或目录时需要的全部信息。
一个索引节点代表文件系统中的一个文件(这里的文件不仅是指我们平时所认为的普通的文件,还包括目录,特殊设备文件等等)。
索引节点和超级块一样是实际存储在磁盘上的,当被应用程序访问到时才会在内存中创建。
索引节点定义在:
2.3 目录项
和超级块和索引节点不同,目录项并不是实际存在于磁盘上的。
在使用的时候在内存中创建目录项对象,其实通过索引节点已经可以定位到指定的文件,
但是索引节点对象的属性非常多,在查找,比较文件时,直接用索引节点效率不高,所以引入了目录项的概念。
每个目录项对象都有3种状态:被使用,未使用和负状态
- 被使用:对应一个有效的索引节点,并且该对象由一个或多个使用者
- 未使用:对应一个有效的索引节点,但是VFS当前并没有使用这个目录项
- 负状态:没有对应的有效索引节点(可能索引节点被删除或者路径不存在了)
目录项的目的就是提高文件查找,比较的效率,所以访问过的目录项都会缓存在slab中。
slab中缓存的名称一般就是 dentry,可以通过如下命令查看:
[wangyubin@localhost kernel]$ sudo cat /proc/slabinfo | grep dentrydentry 212545 212625 192 21 1 : tunables 0 0 0 : slabdata 10125 10125 0
目录项定义在:
2.4 文件对象
文件对象表示进程已打开的文件,从用户角度来看,我们在代码中操作的就是一个文件对象。
文件对象反过来指向一个目录项对象(目录项反过来指向一个索引节点)
其实只有目录项对象才表示一个已打开的实际文件,虽然一个文件对应的文件对象不是唯一的,但其对应的索引节点和目录项对象却是唯一的。
文件对象的定义在:
/* * 文件对象结构中定义的字段非常多, * 这里只介绍一些重要的属性 */struct file { union { struct list_head fu_list; /* 文件对象链表 */ struct rcu_head fu_rcuhead; /* 释放之后的RCU链表 */ } f_u; struct path f_path; /* 包含的目录项 */ const struct file_operations *f_op; /* 文件操作函数 */ atomic_long_t f_count; /* 文件对象引用计数 */};/* * 其中的 f_op 中定义了文件对象的操作方法 * 这里只介绍一些相对重要的函数 */struct file_operations { /* 用于更新偏移量指针,由系统调用lleek()调用它 */ loff_t (*llseek) (struct file *, loff_t, int); /* 由系统调用read()调用它 */ ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); /* 由系统调用write()调用它 */ ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); /* 由系统调用 aio_read() 调用它 */ ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); /* 由系统调用 aio_write() 调用它 */ ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); /* 将给定文件映射到指定的地址空间上,由系统调用 mmap 调用它 */ int (*mmap) (struct file *, struct vm_area_struct *); /* 创建一个新的文件对象,并将它和相应的索引节点对象关联起来 */ int (*open) (struct inode *, struct file *); /* 当已打开文件的引用计数减少时,VFS调用该函数 */ int (*flush) (struct file *, fl_owner_t id);};
2.5 四个对象之间关系图
上面分别介绍了4种对象分别的属性和方法,下面用图来展示这4个对象的和VFS之间关系以及4个对象之间的关系。
3. 文件系统相关的数据结构
处理上面4个主要的对象之外,VFS中还有2个专门针对文件系统的2个对象,
- struct file_system_type: 用来描述文件系统的类型(比如ext3,ntfs等等)
- struct vfsmount : 描述一个安装文件系统的实例
file_system_type 结构体位于:
每种文件系统,不管由多少个实例安装到系统中,还是根本没有安装到系统中,都只有一个 file_system_type 结构。
当文件系统被实际安装时,会在安装点创建一个 vfsmount 结构体。
结构体代表文件系统的实例,也就是文件系统被安装几次,就会创建几个 vfsmount
vfsmount 的定义参见:
4. 进程相关的数据结构
以上介绍的都是在内核角度看到的 VFS 各个结构,所以结构体中包含的属性非常多。
而从进程的角度来看的话,大多数时候并不需要那么多的属性,所有VFS通过以下3个结构体和进程紧密联系在一起。
- struct files_struct :由进程描述符中的 files 目录项指向,所有与单个进程相关的信息(比如打开的文件和文件描述符)都包含在其中。
- struct fs_struct :由进程描述符中的 fs 域指向,包含文件系统和进程相关的信息。
- struct mmt_namespace :由进程描述符中的 mmt_namespace 域指向。
struct files_struct 位于:
struct files_struct { atomic_t count; /* 使用计数 */ struct fdtable *fdt; /* 指向其他fd表的指针 */ struct fdtable fdtab;/* 基 fd 表 */ spinlock_t file_lock ____cacheline_aligned_in_smp; /* 单个文件的锁 */ int next_fd; /* 缓存下一个可用的fd */ struct embedded_fd_set close_on_exec_init; /* exec()时关闭的文件描述符链表 */ struct embedded_fd_set open_fds_init; /* 打开的文件描述符链表 */ struct file * fd_array[NR_OPEN_DEFAULT]; /* 缺省的文件对象数组 */};
struct fs_struct 位于:
struct fs_struct { int users; /* 用户数目 */ rwlock_t lock; /* 保护结构体的读写锁 */ int umask; /* 掩码 */ int in_exec; /* 当前正在执行的文件 */ struct path root, pwd; /* 根目录路径和当前工作目录路径 */};
struct mmt_namespace 位于:
但是在2.6内核之后似乎没有这个结构体了,而是用 struct nsproxy 来代替。
以下是 struct task_struct 结构体中关于文件系统的3个属性。
struct task_struct 的定义位于:
/* filesystem information */ struct fs_struct *fs;/* open file information */ struct files_struct *files;/* namespaces */ struct nsproxy *nsproxy;
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~