Linux存储栈(一)
Linux存储栈(一)
系统调用
这里推荐《Linux系统编程》,里面有非常具体的参数介绍和注意事项。
最常用的有以下几个。
write
,open
,close
open字面意思为打开文件,文件加载到内存中以文件描述符号的形式存在,通过文件描述符这个中间人完成所有对文件的操作,文件描述符在内存中代表文件,通过操作文件描述符间接操作文件。
malloc
,mmap
malloc用来进行用户空间的内存申请。mmap可以将文件从offset的位置开始长度为length的一个块映射到内存区域,程序可以通过访问内存的方式访问文件。因为他们都建立了内存的实际映射,用户空间的地址都是虚拟地址,虚拟地址和物理地址的转换的时间不可避免,但与read/write相比,使用mmap的方式对文件进行访问,带来的一个显著好处就是可以减少一次用户空间到内核空间的复制,在某些场景下,如访问音频、视频等大文件,可以带来性能的提升。
文件系统
Linux中文件的概念并不局限于普通的磁盘文件,而是指由字节序列构成的信息载体,I/O设备、socket等也被包括在内。因为有了文件的存在,所以需要衍生出文件系统去进行组织和管理文件,而为了支持各种各样不同的文件系统,所以有了虚拟文件系统的出现。
虚拟文件系统屏蔽了不同文件系统的差异,提供统一的接口。用户空间可以直接使用函数调用而不需要考虑文件系统的实现差异。
文件系统的抽象概念:文件(file),索引节点(inode),目录项(dentry),安装节点(mount point)
准确的说文件+索引节点才是真正的文件,为什么这么说,因为文件本身的数据记录在文件file,而相关信息如(访问权限,大小,拥有者,创建时间)这些信息记录在索引节点inode,数据和控制信息分开存放。
超级块
所有文件系统都需要实现超级块对象,该对象存储文件系统的信息。而文件系统会在系统初始化时就构建好,mkfs制作文件系统的,第一步就是构建超级块,超级块记录了文件系统的原始的重要信息。
文件,目录项,文件索引
索引节点(inode)本质上是用来存储文件,是作为存储文件的基本单位,其结构体中自然包含文件的相关信息(访问权限,大小,创建时间等)。目录项是用来索引文件。文件加载到内存中一般是以文件描述符号的形式存在,通过操作文件描述符间接操作文件,而不是直接操作文件。
内核API定义为
1 | struct file_operations { |
inode数据结构的定义在<linux/fs.h>,一个索引节点代表一个文件(仅当索引节点仅当文件被访问时,才会在内存创建),万物皆文件,当然也可以代表pipe,cdev,bdev
1 | union { |
对于索引节点的操作,都是控制信息类,在Xv6内核实验中就有一个实现symlink
,涉及对inode中信息的判断,为了添加链接,需要判断类型,确保链接到文件上,而不是目录。以及连接不能成环。
目录项本质上也是文件,那么目录+索引节点,为了方便查找查找,其数据结构体定义在<linux/dcache.h>,如果遍历时再读入并解析,会浪费时间,所以一般都将目录项对象缓存在目录项缓存(dcache).
与进程相关的数据结构
file_struct,定义在<linux/fdtable.h>
1 | /* |
这里面有一个成员 file 里面存储了所有代开文件对象。