第三章 LINUX 文件系统
第一节 文件系统管理
文件系统类型
支持多种不同类型的文件系统是 LINUX 操作系统的一大特色。目前支持的有 ext, ext2, minix, umsdos, ncp, iso9660, hpfs,msdos, xia, vfat, proc,nfs, smb, sysv, affs, ntfs 以及ufs 等,
参见 include/linux/autoconf.h 。
文件系统类型的注册
• 一种是在编译核心系统时确定,并在系统初始化时通过内嵌的函数调用向注册表登记。
• 另一种则利用 LINUX 的模块( module )特征,把某个文件系统当作一个模块。装入该模块时(通过 kerneld 或用 insmod 命令 )向注册表登记它的类型,卸装该模块时则从注册表注销。
操作函数
• int register_filesystem(struct file_system_type * fs) ;
• Int unregister_filesystem(struct file_system_type * fs) ;
管理文件系统 类型的结构
stati c struct fi l e_system_type *fi l e_systems = (struct fi l e_system_type *) NULL;
struct fi l e_system_type { struct super_bl ock *(*read_super)(struct super_bl ock *, voi d *, i nt); / * read_super 所指的函数用于读出该文件系统在外存的超级块 */ const char *name; / * 文件系统的类型名,如 ext2 */ i nt requi res_dev; / * 支持文件系统的设备,proc文件系统不需要任何设备 */ struct fi l e_system_type * next; / * 文件系统类型链表的后续指针 */};
fi l e_systems fi l e_system_type next next next=0
文件系统实例的管理
LINUX 文件系统管理首先是关于“文件系统” 层的管理。系统启动时,必首先装入“根”文件系统(由全程变量 ROOT_DEV 指示),然后根据 /etc/fstab 中指定,逐个建立文件系统。
此外,用户也可以通过 mount 、 umount 操作,随时安装或卸装文件系统。
当装入一个文件系统时,应首先向操作系统核心注册该文件系统。当卸装一个文件系统时,应向操作系统核心申请注销该文件系统。
文件系统实例的注册操作
• struct vfsmount *add_vfsmnt( kdev_t dev, const char * dev_name, const char * dir_name) ;
• void remove_vfsmnt(kdev_t dev) ;
• struct vfsmount *lookup_vfsmnt(kdev_t dev) ;
文件系统实例的数据结构
stati c struct vf smount *vf smntl i st = (struct vf smount *) NULL; / * 头 */stati c struct vf smount *vf smnttai l = (struct vf smount *) NULL; / * 尾 */stati c struct vf smount *mru_vf smnt = (struct vf smount *) NULL; / * 当前 */struct vf smount{ kdev_t mnt_dev; / * 文件系统所在设备的主设备号、次设备号 */ char *mnt_devname; / * 设备名,如/ dev/ hda1 */ char *mnt_di rname; / * 安装目录名称 */ unsi gned i nt mnt_fl ags; / * 设备标志,如 ro */ struct semaphore mnt_sem; / * 对设备 I / O操作时的信号量 */ struct super_bl ock *mnt_sb; /* 指向超级块 */ struct fi l e *mnt_quotas[MAXQUOTAS]; /* 指向配额文件的指针 */ t i me_t mnt_i exp[MAXQUOTAS]; / * expi reti me for i nodes */ t i me_t mnt_bexp[MAXQUOTAS]; / * expi reti me for bl ocks */ struct vf smount *mnt_next; / * 已注册文件系统链表的后续指针 */};
文件系统类型和实例示意图
vfsmount super_block file_system_typevfsmntlist file_systems
inodevfsmnttail
inode
mnt_sb s_type
s_covered
s_mountedmnt_sb
第三章 LINUX 文件系统
第二节 虚拟文件系统 VFS
VFS
• VFS 对 LINUX 的每个文件系统的所有细节进行抽象,使得不同的文件系统在 LINUX 核心以及系统中运行的其他进程看来,都是相同的。
• VFS 并不是一种实际的文件系统。它只存在于内存中,不存在于任何外存空间。
• VFS 在系统启动时建立,在系统关闭时消亡。• VFS 拥有关于各种特殊文件系统的公共界面,如超
级块、 inode 、文件操作函数入口等。
VFS 的作用
VFS
MINIX FS EXT FS EXT2 FS MSDOS FS
I/O设备驱动
VFS inode cache
VFS directory cache
buffer cache
VFS 超级块
• VFS 描述系统文件使用超级块和 inode 的方式。• 在系统初启时,所有被初始化的文件系统 ( fil
e_system_type )都要向 VFS ( file_systems )登记。• 每种文件系统类型的读超级块函数( read_super )必
须识别该文件系统的结构并且将其信息映射到一个 VFS 的超级块数据结构上。
• 参见文件 super.doc
树型目录与 VFS 超级块
安装点 inode 下挂文件系统 文件系统的超级块
root
i_mount i_sb s_covered
s_mounted
VFS inode
• 文件系统由子目录和文件构成。• 每个子目录或文件只能由唯一的 inode 结
构描述。• VFS inode 的内容取自物理设备上的文件系
统,由文件系统指定的操作函数( i_op 属性指定)填写。
• 参见文件 inode.doc
第三章 LINUX 文件系统
第三节 EXT2 文件系统
LINUX 的磁盘文件系统
引导块:在文件系统的开头,通常为一个扇区,存放引导程序,用于读入并启动操作系统。
超级块:用于记录文件系统的管理信息。特定的文件系统定义了特定的超级块。
inode区:一个文件(或目录〕占据一个索引节点。第一个索引节点是该文件系统的根节点。利用根节点,可以把一个文件系统挂在另一个文件系统的非叶节点上。
数据区:存放文件数据或者管理数据 ( 如一级间址块,二级间址块等〕。
EXT2体系结构
Group 0 Group 1 ............ Group N
SuperBlock
File SystemDescriptors
blockbitmap
inodebitmap
inodetable
datablocks
块组( block group )
保存关于文件系统的备份信息(超级块和所有组描述符)。当某个组的超级块或 inode受损时,这些信息用来恢复文件系统。
块位图 (block bitmap) 记录本组内各个数据块的使用情况,每一位 (bit) 对应于一个数据块, 0 表示空闲,非 0 表示已分配。
inode位图 (inode bitmap) 的作用类似于块位图,它记录 inode 表中 inode 的使用情况。
块组( block group )
inode 表 (inode table)保存本组所有的 inode。 EXT2 应用 inode 描述文件,一个 inode对应一个文件,每个 inode 对应一个唯一的inode号。 inode既定义文件内容在外存空间的位置,也定义了对文件的存取权限、文件修改时间、文件类型等信息。
数据块 (data blocks) 则是真正的文件数据区。为文件分配存储空间以块为单位。
EXT2 超级块
每个块组( Block Group )均包含一个相同的超级块。一般,只有块组 0 的超级块才读入内存,其它块组的超级块仅作为备份。
外存中的超级块,参见文件 ext2_super.doc
内存中的超级块,参见文件 ext2_super.doc
EXT2 组描述符( group discriptor)
每个块组 (Block Group) 都有一个组描述符来描述它
所有的组描述符在每个块组中都有备份
组描述符一个挨一个存放,构成了组描述符表。
组描述符的结构
struct ext2_group_desc{
__u32 bg_block_bitmap; /* 该块组的块位图位置 */__u32 bg_inode_bitmap; /* 该块组的 inode位图位置 */__u32 bg_inode_table; /* 该块组的 inode表的位置 */__u16 bg_free_blocks_count; /* 该块组的空闲块数 */__u16 bg_free_inodes_count; /* 该块组的 inode数 */__u16 bg_used_dirs_count; /* Directories count */__u16 bg_pad;__u32 bg_reserved[3];
}
EXT2 的 inode
文件系统的每个文件或目录(看作一种特殊文件)由一个 inode 描述,且只能由一个 inode 描述。
属于同一块组 (Block Group) 的 inode保存在同一 inode 表中,与该组的 inode位图一一对应。
外存中的 inode ,参见文件 ext2_inode.doc内存中的 inode ,参见文件 ext2_inode.doc
inode 关于数据块的寻址
ext2_inode
12个直接块
一次间接块
二次间接块
三次间接块 数据块
数据块
数据块
数据块
数据块
数据块
EXT2 的目录
目录是关于文件的存取路径的特殊文件一个目录文件就是一个目录项的列表,每
一个目录项都有一个数据结构来描述:struct ext2_dir_entry {
__u32 inode; /* 该目录项的 inode号, 用它可以查找 inode 表中对应的 inode */
__u16 rec_len; /* 目录项的长度 */
__u16 name_len; /* 文件名长度,最长 255 */
char name[EXT2_NAME_LEN]; /* 文件名 */
}
例:在 EXT2 文件系统中查找 /usr/include/stdio.h 文件
根据 ROOT_DEV ,从 vfsmntlist链表、 file_systems链表找到文件系统的超级块,继而找出“/” 的 inode号( VFS 的 super_block.s_mounted)。
到块组 0的 inode 表中读取文件系统的根的 inode 。
根文件是一个目录文件(由“ i_mode” 识别),包含了根目录下子目录和文件的由 ext2_dir_entry 描述的目录项。可以在其中找到 ext2_dir_entry .name=“usr” 的目录项,从该目录项的 ext2_dir_entry.inode 读出代表 /usr 目录的inode号。
Recommended