一个文件系统类型的任务是执行用于映射相应高层VFS操作到物理介质(磁盘、网络等等)的低层任务。VFS接口有足够的灵活性来支持传统的Unix文件系统和外来的象msdos和umsdos文件系统类型。 每一个fs类型除了它自己的源代码目录以外,是由下列各项组成的: - file_systems[]数组中的一个条目(项)
(fs/filesystems.c); - 超级块(superblock)的include文件(include/linux/type_fs_sb.h);
- i节点(inode)的include文件(include/linux/type_fs_i.h);
- 普通自己专用的include文件(include/linux/type_fs.h);
- include/linux.fs.h中的两行#include,以及在结构super_block和inode中的条目。
对于特定fs类型自己的目录,包含有所有的实际代码、inode和数据的管理程序。 本手册中有关procfs的章节,揭示了所有有关那种fs类型的低层代码和VFS接口。在阅读过那个章节之后,fs/procfs中的源代码就显得非常容易理解了。 现在我们来观察VFS机制的内部工作情况,并以minix文件系统的代码作为一个实际例子。我选择minix类型是因为它比较短小但却是完整的;而且,Linux中的所有其它的fs类型都衍生于它。在最近Linux安装中的事实上的标准文件系统类型ext2,要比它复杂得多,对ext2这个文件系统的探索就留给聪明的读者作为一个练习了。 当一个minix-fs被加载后,minix_read_super就会把从被加载的设备中读取的数据添入super_block数据结构中。此时,该结构中的s_op域将保留有一个指向minix_sops的指针,该指针将被一般文件系统代码用于分派超级块的操作。 在全局系统树结构中链接新加载的fs依赖于下列各数据项(假设sb是超级块数据结构,而dir_i是指向加载点的inode的指针): - sb->s_mounted指向被加载文件系统的根目录i节点(MINIX_ROOT_INO);
- dir_i->i_mount保存有sb->s_mounted;
- sb->s_covered保存有dir_i
卸载操作将最终通过do_umount来执行,而它会依次调用minix_put_super。 每当访问一个文件时,minix_read_inode就会开始执行;它会使用minix_inode各字段中的数据填写系统范围的inode数据结构。inode->i_op字段是依照inode->i_mode来填写的,它将负责该文件的任何其它操作。上述minix函数的代码可以从fs/minix/inode.c中找到。 inode_operations数据结构是用于把inode操作分派给特定fs类型的内核函数;该数据结构的第一项是一个指向file_operations项的指针,它等同于数据管理的i_op。minix文件系统类型允许有inode操作集中的三种方式(用于目录、文件和符号链接)和文件操作集中的两种(符号链接不需要文件操作)。 目录操作(仅minix_readdir)位于fs/minix/dir.c中;文件操作(读read和写write)位于fs/minix/file.c中而符号操作(读取并跟随着链)位于fs/minix/symlink.c。 minix源代码目录中的其余部分用于实现以下任务: - bitmap.c用于管理i节点与块的分配和释放(而ext2文件系统却有两个不同的代码文件);
- fsynk.c用于fsync()系统调用--它管理直接、间接和双重间接块(我假定你是知道这些术语的,因为这是Unix的普通知识);
- namei.c内嵌有所有与名字有关的i节点的操作,比如象节点的创建和消除、重命名和链接;
- truncate.c执行文件的截断操作。
|