您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > Linux文件系统原理
Linux文件系统原理第1章概述要理解linux的文件系统,要从理解虚拟文件系统(VFS,VirtualFilesystem)开始。其结构可以用图表1来描述。图表1第2章虚拟文件系统2.1它到底是什么?虚拟文件系统是Linux内核中的一个软件层,用于给用户空间的程序提供文件系统接口。它也提供了内核中的一个抽象功能,允许不同的文件系统共存。2.2工作方式概述2.2.1注册和安装一个文件系统如果你想在内核中支持一种新的文件系统的话,你所需要做的仅仅是调用函数register_filesystem()。你向内核中传递一个描述文件系统实现的结构(structfilesystem),此结构将被加入到内核的支持文件系统表中去。你可以运行下面的命令:%cat/proc/filesystems这样可以看到你的系统支持哪些文件系统。内核模块必须提供两个用于加载和卸载时调用的接口,这两个接口由两个固定的宏引出,分别为module_init(),module_exit()。文件系统在作为模块被加载到内核时,调用register_filesystem(),把自己注册为一种文件系统。在模块被卸载时,调用unregister_filesystem()从内核中注消。以JFFS为例://定义一种文件系统jffs_fs_type,其名称为“JFFS”staticDECLARE_FSTYPE_DEV(jffs_fs_type,jffs,jffs_read_super);staticint__initinit_jffs_fs(void){printk(KERN_INFOJFFSversionJFFS_VERSION_STRING,(C)1999,2000AxisCommunicationsAB\n);#ifdefCONFIG_JFFS_PROC_FSjffs_proc_root=proc_mkdir(jffs,proc_root_fs);#endiffm_cache=kmem_cache_create(jffs_fm,sizeof(structjffs_fm),0,SLAB_HWCACHE_ALIGN,NULL,NULL);node_cache=kmem_cache_create(jffs_node,sizeof(structjffs_node),0,SLAB_HWCACHE_ALIGN,NULL,NULL);//注册文件系统returnregister_filesystem(&jffs_fs_type);}staticvoid__exitexit_jffs_fs(void){//注消文件系统unregister_filesystem(&jffs_fs_type);kmem_cache_destroy(fm_cache);kmem_cache_destroy(node_cache);}//引出模块的加载和卸载时调用的接口module_init(init_jffs_fs)module_exit(exit_jffs_fs)当一个mount请求出现时,VFS将会为特定的文件系统调用相应的方法。安装点的dentry结构将会被改为指向新文件系统的根i节点。2.2.2打开一个文件VFS实现了open系统调用。路径参数被VFS用来在目录入口缓存(dentrycacheordcache)。这提供了一个将路径名转化为特定的dentry的一个快的查找机制。一个单独的dentry通常包含一个指向i节点(inode)的指针。i节点存在于磁盘驱动器上,它可以是一个规则文件,目录,FIFO文件,等等。Dentry存在于RAM中,并且永远不会被存到磁盘上:它们仅仅为了提高系统性能而存在。i节点存在于磁盘上,当需要时被拷入内存中,之后对它的任何改变将被写回磁盘。存在于RAM中的i节点就是VFS的i节点,dentry所包含的指针指向的就是它。dcache是你的整个文件空间的观察点。大多数情况下不可能有足够的RAM空间来放我们的文件空间的所有文件的目录入口缓存(dentry),所以我们的dcache会有缺少的项。为了将路径名转换为一个dentry,VFS不得不采取创建dentry的方式,并在创建dentry时将指针指向相应的i节点。这是通过对i节点的查找完成的。为了查找一个文件的i节点(通常从磁盘上读),VFS需要调用该文件的父目录的lookup()方法,此方法是特定的文件系统所设置的。后面对此将会有更详尽的描述。一旦VFS得到了所需要的dentry(同时也得到了相应的i节点),我们就能够对文件做想要的操作:打开文件,或者用stat来看i节点中的数据。stat的操作非常简单:在VFS得到dentry之后,它取得inode中的一些数据并将其中的一部分送回用户空间。打开一个文件需要其它的操作:分配一个structfile(定义于linux/fs.h,这是内核中的文件描述)结构。新分配的structfile结构被指向dentry的指针和对文件进行操作的函数集合所初始化,这些都是从i节点中得到的。通过这种方式,特定的文件系统实现才能起作用。文件结构(structfile)被放在进程的文件描述符表中。读,写和关闭文件(或者其它的VFS操作)是通过使用用户空间的文件描述符找到相应的文件结构(structfile),然后调用所需要的方法函数来实现的。当文件处于打开状态时,系统保持相应的dentry为open状态(正在使用),这表示相应的i节点在被使用。2.3主要结构说明2.3.1structfile_system_type此结构描述了文件系统。在内核2.4.18中,此结构的定义如下:structfile_system_type{constchar*name;intfs_flags;structsuper_block*(*read_super)(structsuper_block*,void*,int);structmodule*owner;structfile_system_type*next;structlist_headfs_supers;};其中各个域的意义:name:文件系统的类型名称,如vfat,ext2,等等。fs_flags:变量标志,如FS_REQUIRES_DEV,FS_NO_DCACHE,等等。read_super:当此种文件系统的一个新的实例要被安装时,此方法会被调用。owner:实例所在的模块,通常默认为THIS_MODULE。next:被内部的VFS实现所使用,你只需要将其初始化为NULL。fs_supers:超级块链表,初始化为NULL即可。函数read_super具有以下的参数:structsuper_block*sb:超级块结构。此结构的一部分被VFS初始化,余下的部分必须被函数read_super初始化。void*data:任意的安装选项,通常是ASCII的字符串。在JFFS中没有使用。intsilent:表示当出现错误时是否保持安静。(不报警?)在JFFS中没有使用。read_super方法必须确定指定的块设备是否包含了一个所支持的文件系统。当成功时返回超级块结构的指针,错误时返回NULL。read_super方法填充进超级块结构(structsuper_block)的最有用的域是s_op域。这是一个指向structsuper_operations的指针,此结构描述了文件系统实现的下一层细节。2.3.2structsuper_operations此结构描述了VFS对文件系统的超级块所能进行的操作。在内核2.4.18中,此结构的定义如下:structsuper_operations{void(*read_inode)(structinode*);void(*read_inode2)(structinode*,void*);void(*dirty_inode)(structinode*);void(*write_inode)(structinode*,int);void(*put_inode)(structinode*);void(*delete_inode)(structinode*);void(*put_super)(structsuper_block*);void(*write_super)(structsuper_block*);void(*write_super_lockfs)(structsuper_block*);void(*unlockfs)(structsuper_block*);int(*statfs)(structsuper_block*,structstatfs*);int(*remount_fs)(structsuper_block*,int*,char*);void(*clear_inode)(structinode*);void(*umount_begin)(structsuper_block*);structdentry*(*fh_to_dentry)(structsuper_block*sb,__u32*fh,intlen,intfhtype,intparent);int(*dentry_to_fh)(structdentry*,__u32*fh,int*lenp,intneed_parent);int(*show_options)(structseq_file*,structvfsmount*);};除非特别提出,所有的方法都在未加锁的情况下被调用,这意味着大多数方法都可以安全的被阻塞。所有的方法都仅仅在进程空间被调用(例如,在中断处理程序和底半部中不能调用它们)read_inode:从一个文件系统中读取一个特定的i节点时调用此方法。i节点中的域i_ino被VFS初始化为指向所读的i节点,其余的域被此方法所填充。read_inode2:专为reiserfs留的,其它文件系统现在用不到。write_inode:当VFS需要向磁盘上的一个i节点写时调用。put_inode:当VFS的i节点被从i节点缓冲池移走时被调用。此方法是可选的。delete_inode:当VFS想删除一个i节点时调用次方法。notify_change:当VFS的i节点的属性被改变时调用。若此域为NULL则VFS会调用rite_inode。此方法调用时需要锁住内核。put_super:当VFS要释放超级块时调用(umount一个文件系统)。此方法调用时需要锁住内核。write_super:当VFS超级块需要被写入磁盘时被调用。此方法为可选的。statfs:当VFS需要得到文件系统的统计数据时调用。此方法调用时需要锁住内核。remount_fs:当文件系统被重新安装时调用。此方法调用时需要锁住内核。clear_inode:当VFS清除i节点时调用。可选项。以上方法中,read_inode需要填充i_op域,此域为一个指向structinode_operations结构的指针,它描述了能够对一个单独的i节点所能进行的操作。其它的一些域在很多文件系统里都没有使用,可以不用关心。2.3.3structinode_operations此结构描述了VFS能够对文件系统的一个i节点所能进行的操作。在内核2.4.18中,此结构的定义如下:structinode_operations{int(*create)(structinode*,structdentry*,int);structdentry*(*lookup)(structinode*,structdentry*);int(*link)(structdentry*,structinode*,structdentry*);int(*unlink)(structinode*,structdentry*);int(*symlink)(structinode*,structdentry*,constchar*);int(*mkdir)(structinode*,structdentry*,int);int(*rmdir)(stru
本文标题:Linux文件系统原理
链接地址:https://www.777doc.com/doc-6147235 .html