1、Linux操作系统分析,中国科学技术大学计算机系 陈香兰(051287161312) Autumn 2010,2019/6/1,Linux OS analysis,2/92,文件系统,Unix文件系统概述 Linux的虚拟文件系统 Ext2文件系统简介,Unix文件系统概述,2019/6/1,Linux OS analysis,4/92,提纲,文件 硬链接和软链接 文件类型 文件描述符与索引节点 访问权限和文件模式 文件操作的系统调用,2019/6/1,Linux OS analysis,5/92,文件,Unix文件是以字节序列组成的信息载体 内核不解释文件的内容 文件的组织,2019/6/
2、1,Linux OS analysis,6/92,文件、目录和目录树,文件被组织成一个树状的命名空间 文件:叶结点 目录:根节点(根目录“/”)和中间节点 目录使用一个目录名标识。 目录节点包含它下面的文件及子目录的所有信息 文件名和目录名 不能使用“/”和字符“0”,其他ASCII字符都OK 长度:不同的文件系统有不同的限制, 通常256个字符 同一个目录下,不允许文件重名;不同目录下无妨,2019/6/1,Linux OS analysis,7/92,当前工作目录 Unix的每个进程都有一个当前工作目录,current working directory,属于进程的执行上下文 绝对路径:用
3、来在命名空间中指定一个特定的文件,以“/”打头,表示以根目录作为起点, 形如 “/home/chenxl/sample/test.c” 相对路径:以当前工作目录作为起点 例如当前目录为“/home/chenxl”,则上述文件的相对路径可以是“sample/test.c”,2019/6/1,Linux OS analysis,8/92,“.”和“” 前者表示当前工作目录 后者表示当前工作目录的父目录 若当前工作目录是根目录“/”,那么“.”和“”相等 例如,当前目录是“/home/chenxl”,则上述文件的相对路径还可以表示为 “./sample/test.c” “./chenxl/sampl
4、e/test.c” “/home/chenxl/sample/test.c”,2019/6/1,Linux OS analysis,9/92,硬链接和软链接,硬链接(hard link) 一般情况下,一个常见的文件名代表了到对应文件的一个硬链接 一个文件可以有不同的硬链接,他们可以在同一个目录下,也可以在不同的目录下,因此一个文件可以有不同的文件名 下面的命令可以创建一个硬链接$ ln p1 p2 其中p1指明一个现有的文件的路径名 p2指明新建立的硬链接的路径名,2019/6/1,Linux OS analysis,10/92,硬链接的限制 不允许用户给目录创建硬链接 只有在同一个文件系统的
5、文件之间才能创建硬链接 软链接(symbolic link) 符号链接是一种特殊的文件(短文件),它包含另一个文件的任意一个路径名 可以指向任意一个文件系统的任意文件,甚至一个不存在的文件 下面的命令可以创建一个软链接 $ ln -s p1 p2 p2指明新建立的软连接的路径名。在实现上,文件系统抽出p2的目录部分,在此目录下创建一个符号链接文件,2019/6/1,Linux OS analysis,11/92,文件类型,Unix文件的类型可以是 常规文件(regular file) 目录 符号链接 面向块的设备文件 面向字符的设备文件 管道和命名管道 套接字,基本类型,设备和驱动相关,用于进
6、程间通信,2019/6/1,Linux OS analysis,12/92,文件描述符和索引节点,文件系统处理文件所需要的所有信息都包含在索引节点inode中 每个文件都有自己的inode 一般而言,inode应当包含如下信息 文件类型 与文件相关的硬链接的个数 以字节为单位的文件的长度 设备标识符(即包含文件的设备的标识符) 在文件系统中标识文件的inode号 文件拥有者的UID 文件的GID 一些时间戳:inode状态的改变时间、文件的最后访问时间、最后修改时间 访问权限和文件模式,2019/6/1,Linux OS analysis,13/92,访问权限和文件模式,文件潜在的用户分为3种
7、类型 文件所有者 同组用户 其他用户 访问权限:读、写、执行 每类用户都有这三种权限 文件的访问权限使用9个不同的bit来表示此外还有三种附加标记 suid、sgid、sticky,2019/6/1,Linux OS analysis,14/92,关于suid、sgid、sticky,Suid 执行某个可执行文件的时候,进程通常具有进程拥有者的UID,但是若可执行文件设置了SUID标记,则进程将拥有文件所有者的UID 危险:若文件所有者是root? Sgid 类似,进程的GID将不是进程拥有者的GID,而是文件所有者所在组的GID Sticky 告诉内核,就算一个程序运行结束了,也暂时将程序保
8、留在内存中,2019/6/1,Linux OS analysis,15/92,在一个文件被创建的时候: 一个文件的属主UID就是创建这个文件的进程的UID 一个文件的属主GID可能是 创建这个文件的进程的GID 若文件的父目录设置了SGID标记,则该文件将继承父目录的GID,2019/6/1,Linux OS analysis,16/92,文件操作的系统调用,创建/删除 打开/关闭 读/写 定位 更名,#include #include #include int open(const char *pathname, int flags); int open(const char *pathna
9、me, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); #include ssize_t write(int fd, const void *buf, size_t count); int unlink(const char *pathname);#include #include off_t lseek(int fildes, off_t offset, int whence); #include int rename(const char *oldpath, const char *newpath
10、);,Linux的虚拟文件系统,2019/6/1,Linux OS analysis,18/92,提纲,虚拟文件系统VFS的作用 VFS的数据结构 文件系统类型 文件系统安装 路径名查找 VFS系统调用的实现 文件加锁,2019/6/1,Linux OS analysis,19/92,虚拟文件系统VFS的作用,虚拟文件系统 Virtual Filesystem Virtual Filesystem Switch VFS是一个软件层,用来处理与Unix标准文件系统相关的所有系统调用。 是用户应用程序与文件系统实现之间的抽象层 能为各种文件系统提供一个通用的、统一的接口 Linux与其他类Unix
11、系统一样,采用虚拟文件系统VFS来达到支持多种文件系统格式的目标,2019/6/1,Linux OS analysis,20/92,VFS在一个简单文件复制操作中的作用,假设用户输入以下shell命令 $ cp /floppy/TEST /tmp/test 其中, /floppy是MS-DOS的磁盘的一个挂载点(安装点) /tmp是Ext2文件系统中的一个目录 对于cp命令而言,它不需要知道/floppy/TEST和/tmp/test分别是什么文件系统类型 在cp命令中,它通过VFS提供的系统调用接口进行文件操作,2019/6/1,Linux OS analysis,21/92,2019/6/
12、1,Linux OS analysis,22/92,VFS支持的文件系统类型,VFS支持的文件系统可以划分为三种主要类型 基于磁盘的文件系统:它们管理在本地磁盘分区中可用的存储空间 Linux使用的文件系统:ext2、ext3、ReiserFS Unix家族的文件系统:SYSV文件系统,UFS,MINIX文件系统以及VERITAS VxFS 微软公司的文件系统:MS-DOS、VFAT以及NTFS ISO9660CD-ROM文件系统和通用磁盘格式的DVD文件系统 其他有专利权的文件系统,如HPFS、HFS、AFFS、ADFS 起源于非Linux系统的其他日志文件系统,JFS,XFS,2019/6
13、/1,Linux OS analysis,23/92,网络文件系统:用于访问属于其他网络计算机的文件系统所包含的文件 NFS、Coda、AFS、SMB、NCP 特殊文件系统 不同于上述两大类 不管理具体的磁盘空间 /proc 各种不同的文件系统通过mount(挂载、安装)到根文件系统中 在Linux中,根文件系统即根目录所代表的文件系统 通常是ext2文件系统,2019/6/1,Linux OS analysis,24/92,VFS中通用文件模型概念,VFS的基本思想:引入一个通用文件模型,这个模型能够表示所有支持的文件系统 对于一个具体实现的文件系统,在处理时,需要将其进行概念上的转换 例如
14、,在通用文件模型中,目录被看成是普通文件 在实现上,read()sys_readfile数据结构f_opMS_DOS文件操作指针(其中的read操作) 类似面向对象的概念,2019/6/1,Linux OS analysis,25/92,通用文件模型有下列对象类型组成 超级块对象(superblock object) 存放文件系统相关信息:例如文件系统控制块 索引节点对象(inode object) 存放具体文件的一般信息:文件控制块/inode 文件对象(file object) 存放已打开的文件和进程之间交互的信息 目录项对象(dentry object) 存放目录项与文件的链接信息,20
15、19/6/1,Linux OS analysis,26/92,三个不同的进程打开同一个文件,两个不同的硬链接,同一个 硬链接,2019/6/1,Linux OS analysis,27/92,VFS所处理的系统调用,mount、umount:挂载/卸载文件系统 sysfs :获取文件系统信息 statfs、fstatfs、ustat :获取文件系统统计信息 chroot :更改根目录 chdir、fchdir、getcwd :操纵当前工作目录 mkdir、rmdir :创建/删除目录 getdents、readdir 、link 、unlink 、rename :对目录项进行操作 readli
16、nk 、symlink :对软链接进行操作 chown 、fchown 、lchown :更改文件所有者 chmod 、fchmod 、utime :更改文件属性 open、close、create ,2019/6/1,Linux OS analysis,28/92,上述大部分操作之需要与通用文件模型中的一些对象打交道,而不需要真正操作具体的文件系统和文件,因此可以把VFS看成是一个“通用”的文件系统,在必要时依赖某种具体的文件系统,2019/6/1,Linux OS analysis,29/92,VFS的数据结构,每个VFS对象都对应一定的数据结构,在这个数据结构中包含对象的属性及其方法一个
17、具体的文件系统:超级块对象:super_block 所有超级块链表:super_blocks :s_list域 文件系统特有信息:s_fs_info域,例如ext2_sb_info 脏标志:s_dirt域 文件系统特有方法s_op:super_operations数据结构及域,例如ext2_sops,include/linux/fs.h,2019/6/1,Linux OS analysis,30/92,Super_block,s_fs_info,Xxx_sb_info,s_op,Xxx_super_operations,2019/6/1,Linux OS analysis,31/92,2019
18、/6/1,Linux OS analysis,32/92,每种文件系统具有自己的super_block结构 每个文件系统具有一个所属文件系统类型的super_block实例,2019/6/1,Linux OS analysis,33/92,一个具体的文件:Inode对象:inode Inode特有的方法 inode_operations 文件特有的方法 file_operations目录项对象:dentry 目录项操作:dentry_operations一个打开文件:文件对象:file 文件操作指针f_pos 文件对象特有的方法专用高速缓存:“filp”,filp_cachep,include
19、/linux/fs.h,include/linux/dcache.h,include/linux/fs.h,Xxx_inode_info,Vfs_inode,2019/6/1,Linux OS analysis,34/92,inode data in memory,2019/6/1,Linux OS analysis,35/92,Structure of an inode on the disk,2019/6/1,Linux OS analysis,36/92,与进程相关的文件,文件系统相关信息fs_struct 打开文件相关信息files_struct,include/linux/fs_st
20、ruct.h,include/linux/path.h,2019/6/1,Linux OS analysis,37/92,include/linux/fdtable.h,include/linux/fdtable.h,include/linux/types.h,include/linux/posix_types.h,2019/6/1,Linux OS analysis,38/92,2019/6/1,Linux OS analysis,39/92,文件系统类型,特殊文件系统 用来为系统程序员、系统管理员等提供一种容易的方式来操作内核的数据结构并实现操作系统的特殊特征 常用的特殊文件系统,2019
21、/6/1,Linux OS analysis,40/92,2019/6/1,Linux OS analysis,41/92,文件系统类型的注册,文件系统类型:file_system_type在系统初始化期间,register_filesystem()用来注册编译时指定的每个文件系统 相应的文件系统对象被插入到file_systems链表中 unregister_filesystem(),2019/6/1,Linux OS analysis,42/92,文件系统的挂载,根文件系统 在系统初始化过程中被直接mount 提供系统初始化脚本以及基本命令 每个文件系统都有自己的根目录 如果一个文件系统的
22、根目录是系统目录树的根目录,那个这个文件系统就是根文件系统 其他文件系统可以挂载到系统的目录树上 这样的目录称为挂载点(mount点,安装点) 文件系统之间的挂载关系对应文件系统之间的父子关系,2019/6/1,Linux OS analysis,43/92,例如,放在软盘/dev/fd0上的ext2文件系统,可通过下列命令安装在/flp上mount -t ext2 /dev/fd0 /flp 一般情况下,只允许挂载一次 在umount之前,其他对/dev/fd0的挂载命令会失败 在2.4中,可以挂载多次 不管被挂载多少次,只有一个真实的文件系统,因此只有一个超级块对象,2019/6/1,Li
23、nux OS analysis,44/92,已挂载文件系统描述符vfsmount挂载根文件系统 第一阶段:安装一个特殊的文件系统,该文件系统仅提供一个作为初始安装点的空目录:init_mount_tree 第二阶段:mount_root 挂载一个文件系统 sys_mount 卸载一个文件系统 sys_umount,2019/6/1,Linux OS analysis,45/92,路径名查找,VFS是如何从文件路径名找到相应的索引节点的? 分析路径名,将它拆分成一个文件名序列 除了最后一个文件名之外,其他所有文件名必定都是目录名搜索的起点: 绝对路径:currentfsroot 相对路径:cur
24、rentfspwd,2019/6/1,Linux OS analysis,46/92,首先找到起点目录的索引节点 在这个索引节点的目录文件中,找到第一个目录名(文件名)所对应的索引节点 在第一个目录名的索引节点的目录文件中找到第二个目录名(文件名)所对应的索引节点 反复,直到文件名序列的最后一项,2019/6/1,Linux OS analysis,47/92,在上述查找过程中要处理的其他问题: 对每个目录的访问权限必须进行检查 若是符号链接,需要进行扩展 要考虑符号链接的循环引用(进行处理) 目录名可能是一个文件系统的安装点,必须扩展到一个新的文件系统中路径名查找 数据结构:struct n
25、ameidata 在需要进行路径名查找的时候,依此调用如下函数:path_init, path_walk, path_release,2019/6/1,Linux OS analysis,48/92,2019/6/1,Linux OS analysis,49/92,查找操作的标志,2019/6/1,Linux OS analysis,50/92,标准查找操作,要处理的问题 跳过第一个路径名分量前的任何/ 考虑符号链接的查找 检查权限 考虑“.” 考虑“” 考虑普通目录,要在目录项高速缓存中查找 ,2019/6/1,Linux OS analysis,51/92,父路径名的查找,在很多情况下,查
26、找操作的真正目的不是路径名的最后一个分量,而是最后分量的前一个分量 例如创建一个文件时 此时,路径解析的结果中存放最后一个分量所在目录对应的对象,2019/6/1,Linux OS analysis,52/92,符号链接的查找,关于符号链接的解析由内核来完成如何识别这是一个符号链接? 如何处理符号链接的循环情况?,2019/6/1,Linux OS analysis,53/92,VFS系统调用的实现,仍然考虑 $ cp /floppy/TEST /tmp/test 假定cp执行下列代码片段(实际要更复杂) inf = open(“/floppy/TEST“, O_RDONLY, 0); out
27、f = open(“/tmp/test“, O_WRONLY | O_CREAT | O_TRUNC, 0600); do len = read(inf, buf, 4096); write(outf, buf, len); while (len); close(outf); close(inf);,2019/6/1,Linux OS analysis,54/92,open()系统调用 sys_open read和write系统调用 sys_write sys_read close系统调用 sys_close,2019/6/1,Linux OS analysis,55/92,文件加锁,当多个进
28、程访问同一个文件时,会出现同步问题 写同一个文件的同一个位置 对同一个文件的同一个位置,1读1写 或者更复杂的情况 Unix提供对文件的加锁机制,可避免上述冲突 POSIX标准规定了基于fcntl()系统调用的文件加锁机制,2019/6/1,Linux OS analysis,56/92,强制锁 vs 劝告锁 劝告锁(advisory lock):需要进程主动参与 Fcntl、flock、lockf 强制锁(mandatory lock):内核强制检查 读锁 vs 写锁 读锁:多个进程可以读共享 写锁:只能一个进程写,并且与读锁互斥,2019/6/1,Linux OS analysis,57/
29、92,Linux文件加锁,Linux支持所有的文件加锁方式 强制锁、劝告锁 fcntl、flock、lockf(库接口) 利用mount系统调用的MS_MANDLOCK标志,fcntl可以在每个文件系统的基础上打开或者关闭强制锁(缺省) 关闭情况下,fcntl产生劝告锁 否则根据文件的组信息 若组设置位为1并且组执行位为0,则产生强制锁 否则劝告锁,Ext2文件系统简介,2019/6/1,Linux OS analysis,59/92,EXT2文件系统是EXT文件系统的升级,在Linux中得到了广泛的使用。介绍EXT2文件系统的 磁盘组织 目录项和支持的文件类型,2019/6/1,Linux
30、OS analysis,60/92,(一)EXT2文件系统的磁盘组织,除了引导扇区之外,EXT2磁盘分区被顺序划分为若干个磁盘块组(Block Group)。 每个块组由若干个磁盘块,按照相同的方式组织,具有相同的大小。 EXT2磁盘块组中的磁盘块按顺序被组织成: 一个用作超级块的磁盘块。 在这个磁盘块里,存放了文件系统超级块的一个拷贝; N个记录组描述符的磁盘块; 1个记录数据块位图的磁盘块; 1个记录索引结点位图的磁盘块; N个用作索引结点表的磁盘块; N个用作数据块的磁盘块。,2019/6/1,Linux OS analysis,61/92,EXT2的超级块,每个块组的第一个磁盘块用来保
31、存所在EXT2 fs的超级块 多个块组中的超级块形成冗余 在某个或少数几个超级块被破坏时,可用于恢复被破坏的超级块信息。,2019/6/1,Linux OS analysis,62/92,超级块,2019/6/1,Linux OS analysis,63/92,2019/6/1,Linux OS analysis,64/92,在内存中记录ext2超级块的数据结构,2019/6/1,Linux OS analysis,65/92,组描述符,组描述符用来描述一个磁盘块组的相关信息,2019/6/1,Linux OS analysis,66/92,索引结点,EXT2中所有的索引结点大小相同,都是12
32、8个字节。,2019/6/1,Linux OS analysis,67/92,2019/6/1,Linux OS analysis,68/92,索引节点表,EXT2的一个磁盘块组中的索引结点存储在一组连续的磁盘块中,形成一个索引结点表。 这组磁盘块中的第一个磁盘块的块号存储在超级块的bg_inode_table数据项中。根据磁盘块的大小,可以计算出每个磁盘块能容纳多少个索引结点 根据索引结点的总个数,可以计算出索引结点表所需要占用的磁盘块的个数。,2019/6/1,Linux OS analysis,69/92,关于索引节点中的i_block,ext2的索引结点中使用了组合索引方式。 前12项
33、用作直接索引 第13项用作间接索引 第14项用作二次间接索引 第15项用作三次间接索引,2019/6/1,Linux OS analysis,70/92,数据块位图和索引结点块位图,EXT2的空闲盘块分配算法采用了位图法 位图: 为便于查找数据块或索引结点的分配信息 每个位(bit)都对应了一个磁盘块: 0,表示对应的磁盘块(或索引结点)空闲 1,表示占用。 2个位图分别占用一个专门的磁盘块。 根据磁盘块的大小,可以计算出每个块组中最多能容纳的数据块个数和索引节点块个数。,2019/6/1,Linux OS analysis,71/92,(二)EXT2中的目录项和文件类型,在EXT2中,目录是
34、一种特殊的文件,这种文件的数据块中存放了该目录下的所有目录项,2019/6/1,Linux OS analysis,72/92,新版的目录项结构,2019/6/1,Linux OS analysis,73/92,EXT2支持的文件类型,EXT2在目录项中存放了文件的类型信息。文件类型可以是07中的任意一个整数。它们分别代表如下含义: 0:文件类型未知; 1:普通文件类型; 2:目录; 3:字符设备; 4:块设备; 5:有名管道FIFO; 6:套接字; 7:符号链接。,2019/6/1,Linux OS analysis,74/92,注意:,2019/6/1,Linux OS analysis,
35、75/92,(三)创建一个ext2文件系统,在磁盘上创建文件系统通常有两个步骤: 格式化磁盘 Linux中:superformat或者fdformat 创建文件系统 Ext2:mke2fs mke2fs的缺省参数 磁盘块大小:1024字节 分片:目前不支持,因此与磁盘块一样 分配inode的个数:1/8192B 永久保留的块的个数:5,2019/6/1,Linux OS analysis,76/92,创建流程,初始化超级块和组描述符 Optionally, 检查是否有坏块,若有创建坏块列表 对每个块组,保留所有用来存放超级块、组描述符、inode表、2个位图的磁盘块 初始化每个块组中的位图 初
36、始化每个块组中的inode表 创建 /root 目录 创建 lost+found 目录(供e2fsck 使用,与坏块相关) 为上述两个目录而更新位图信息 若有坏块,则将其在 lost+found 目录中组织起来,2019/6/1,Linux OS analysis,77/92,以1.44MB的软盘为例,创建ext2文件系统后,2019/6/1,Linux OS analysis,78/92,(四)Ext2提供的各种对象方法,超级块对象方法,2019/6/1,Linux OS analysis,79/92,索引节点对象方法,2019/6/1,Linux OS analysis,80/92,201
37、9/6/1,Linux OS analysis,81/92,2019/6/1,Linux OS analysis,82/92,文件对象方法,2019/6/1,Linux OS analysis,83/92,2019/6/1,Linux OS analysis,84/92,(五)管理ext2的磁盘空间,存储在磁盘上的文件与用户所“看到”的文件有所不同: 用户感觉,文件在逻辑上是连续的 而在磁盘上,存储文件数据的磁盘块可能分散在磁盘各处用户感觉,文件可能比较大 而在磁盘上,由于文件空洞的存在,分配给文件的磁盘空间可能小于用户感觉到的文件大小。,2019/6/1,Linux OS analysis,
38、85/92,涉及到如下操作: 创建/删除一个索引节点 数据块的寻址 文件空洞 分配/释放一个数据块,2019/6/1,Linux OS analysis,86/92,创建/删除一个索引节点,创建一个磁盘索引节点删除一个索引节点,2019/6/1,Linux OS analysis,87/92,关于数据块的寻址,任何一个常规文件都会包含一系列数据块 文件内块号 vs. 逻辑块号 根据数据在文件中的偏移可以计算逻辑块号: 首先计算出文件内块号 (偏移f1)/块大小的商 1 根据索引信息,查询到逻辑块号,2019/6/1,Linux OS analysis,88/92,混合索引示意图,2019/6/
39、1,Linux OS analysis,89/92,文件大小限制,2019/6/1,Linux OS analysis,90/92,关于文件空洞,A file hole is a portion of a regular file that contains null characters and is not stored in any data block on disk. 这是UNIX文件一直以来都有的一个特性例如命令: 创建一个大小为102461字节的文件,这个文件有一个102466144个字节大小的空洞。只有最后一个字节存放了字母“X”文件空洞可以节省磁盘空间 Ext2通过数据块的动态分配来实现这一点: 当且仅当一个进程要写数据到文件中的时候才真正分配磁盘块,2019/6/1,Linux OS analysis,91/92,分配/释放一个数据块,当一个文件需要新的数据块来存放数据时当一个文件被删除或者被截断时,Thanks!,The end.,