《计算机操作系统 》课件-6.7Linux文件系统_第1页
《计算机操作系统 》课件-6.7Linux文件系统_第2页
《计算机操作系统 》课件-6.7Linux文件系统_第3页
《计算机操作系统 》课件-6.7Linux文件系统_第4页
《计算机操作系统 》课件-6.7Linux文件系统_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux文件系统概述

虚拟文件系统VFS

文件系统的注册、安装和卸载Linux文件系统对文件的操作Ext2文件系统6.7Linux文件系统

6.7.1

Linux文件系统概述1.Linux的文件类型(1)普通文件:又称为常规文件,存放用户及操作系统的程序代码、数据等信息。(2)目录文件:存放所有文件的目录项。(3)设备文件:所有的外部设备都当作文件来看待,每个设备都对应一个设备文件。(4)管道文件:为支持管道通信机制设置,又称为FIFO文件。(5)符号链接文件:实现基于符号链接的文件共享机制。(6)Socket文件:用于实现Socket通信机制的文件。

6.7Linux文件系统

6.7.1

Linux文件系统概述2.Linux的文件存取权限Linux系统把文件的用户分成3类:文件主、同组用户和其他普通用户,然后针对每个文件分别对3类用户设置访问权限,权限包括三种操作:可读R、可写W和执行X。

6.7Linux文件系统

6.7.2虚拟文件系统VFS1.VFS支持的文件系统类型VFS(VirtualFileSystem,简称VFS)作为一个通用文件系统模型(CommonFileModel),它把不同文件系统抽象后采用统一方式进行操作。(1)磁盘文件系统Linux使用的文件系统,例如Ext2、Ext3和ReiserFS。Unix家族的文件系统,例如sysv、UFS、MINIX和VERITASVxFS。

微软公司的文件系统,例如MS-DOS、VFAT和NTFS。

其它文件系统,例如HPFS、HFS、AFFS和ADFS。(2)网络文件系统

NFS、Coda、AFS、CIFS以及NCP。(3)特殊文件系统

/proc6.7Linux文件系统

6.7.2虚拟文件系统VFS2.VFS的实现模型6.7Linux文件系统

6.7.2虚拟文件系统VFS3.VFS的主要对象类型(1)超级块对象(superblockobject)存放系统中已安装文件系统的有关信息,每个文件系统一个,是各种具体文件系统在安装时建立的,只存在于内存中。(2)索引节点对象(inodeobject)存放关于具体文件的一般信息。每个打开文件都有一个索引节点对象。(3)目录项对象(dentryobject)存放目录项与对应文件进行链接的信息。(4)文件对象(fileobject)存放打开文件与进程之间进行交互的有关信息。这类信息仅当进程访问文件期间存在于内存中。6.7Linux文件系统

6.7.2虚拟文件系统VFS3.VFS的主要对象类型

进程和以上VFS对象之间的关系6.7Linux文件系统

6.7.2虚拟文件系统VFS4.VFS主要对象的数据结构,主要参考linux2.6.24内核版本。

(1)超级块对象超级块对象由super_block结构来描述(定义在文件/include/linux/fs.h中),主要数据结构如下:structsuper_block{s_list:超级块链表的指针s_dev:超级块所在的设备描述符s_blocksize和s_blocksize_bits:指定磁盘文件系统的块大小s_dirt:超级块的“脏”位s_maxbytes:文件的最大长度s_type:指向文件系统类型的指针s_op:指向超级块操作集的指针s_root:指向根目录的dentry对象s_dirty:表示“脏”(内容被修改但尚未被刷新到磁盘)的inode节点的链表s_fs_info:指向该文件系统私有数据,一般是各文件系统对应的超级块信息。}6.7Linux文件系统

6.7.2虚拟文件系统VFS4.VFS主要对象的数据结构,主要参考linux2.6.24内核版本。

(1)超级块对象超级块操作集由一组对超级块进行的相关操作的函数指针组成,使用super_operations结构来描述,定义在文件/include/linux/fs.h中:structsuper_operations{viod(*read_inode)(structinode*);//读取文件inodeviod(*write_inode)(structinode*,int);//写回inodeviod(*put_inode)(structinode*);//逻辑上释放inodeviod(*delete_inode)(structinode*);//物理上释放inodeviod(*put_super)(structsuper_block*);//释放超级块对象viod(*write_super)(structsuper_block*);//把超级块信息写回磁盘

…}6.7Linux文件系统

6.7.2虚拟文件系统VFS4.VFS主要对象的数据结构,主要参考linux2.6.24内核版本。

(2)索引节点对象索引节点对象由inode结构来描述,定义在文件/include/linux/fs.h中:structinode{i_hash:已经分配好的inode双向链表i_list:未分配的inode资源的双向链表i_dentry:dentry的链表,当多个dentry指向同一个inode时,通过identry将这些dentry连接起来。i_ino:inode的编号i_count:当前inode的引用计数器i_blksize和i_blocks:表明文件系统块的大小以及当前的文件占用多少个块i_version:版本块i_op:指向inode的操作i_fop:inode所代表的文件的操作函数i_sb:指向当前的超级块i_flock:对当前的文件所加的文件锁i_state:当前inode的状态,当i_state为I_DIRTY时,表示inode已“脏”,也就是数据已经被修改过,那么磁盘的inode需要写回至磁盘中更新。…}6.7Linux文件系统

6.7.2虚拟文件系统VFS4.VFS主要对象的数据结构,主要参考linux2.6.24内核版本。

(3)目录项对象目录项对象由dentry结构描述,定义在文件/include/linux/dcache.h中:structdentry{d_count:当前dentry的引用数d_flags:dentry的标志,用来标识出dentry的状态d_inode:与此dentry相对应的inode,可以为空d_hash:作为接口链入dentry的哈希表d_parent:父目录的dentry结构。但对于根节点,该指针指回自己d_name:包含了该dentry的名称以及hash值d_lru:作为接口为引用数为零的dentry结构构成一个双向链表。d_child:该双向链表包含所有该dentry的d_parent的儿子,也就是该dentry的所有兄弟。d_subdirs:该双向链表包含所有该dentry的儿子d_alias:在文件系统中可以通过硬连接使几个不同的文件名指向同一个文件,这就使多个dentry指向同一个inode。d_time:为d_revalidate使用,作时间记录d_op:一组dentry的操作函数d_sb:指向该dentry所在的超级块d_mounted:当前的目录项被mount的次数,由于内核允许一个目录被mount多次,所以需要记录当前目录被mount的情况d_iname:保存文件名的前36个字符,适合短名字的目录项。}6.7Linux文件系统

6.7.2虚拟文件系统VFS4.VFS主要对象的数据结构,主要参考linux2.6.24内核版本。

(4)文件对象文件对象由file结构描述,定义在文件/include/linux/fs.h中:structfile{fu_list:文件对象链表指针f_dentry:文件相对应的dentry结构f_vfsmnt:文件相对应的vfsmount结构f_op:文件操作函数集的指针f_count:文件打开的引用计数f_flags:文件标志,如O_RDONLY、O_NONBLOCK、O_SYNCf_mode:文件的读写权限,在打开文件的时候根据这个属性来判断是否进程有读写该文件的能力f_ops:文件指针的位置f_owner:进程id和发送给该进程的信号f_uid,f_gid:打开文件的进程的uid和gidprivate_data:每个文件的私有数据区,为文件系统或设备驱动程序使用。}6.7Linux文件系统

6.7.2虚拟文件系统VFS5.进程中与文件相关的数据结构进程描述符task_struct结构中与文件相关的字段有fs_struct和files_struct两项信息,其中fs_struct结构用来记录进程工作时的文件系统信息,files_struct结构用来记录进程打开的文件信息。structtask_struct(定义在文件/include/linux/sched.h中){structfs_struct*fs;//文件系统信息structfiles_struct*files;//打开文件信息};structfs_struct//定义在文件/include/linux/fs_struct.h中{atomic_tcount;//用户数目rwlock_tlock;//保护该结构体的锁intumask;//文件权限掩码intin_exec;//当前正在执行的文件structdentry*root;//根目录的dentrystructdentry*pwd;//当前工作目录的dentrystructvfsmount*rootmnt;//根目录mount的文件系统信息umask=0022//初始打开文件的权限};6.7Linux文件系统

6.7.2虚拟文件系统VFS5.进程中与文件相关的数据结构structfiles_struct//用户打开表,定义在文件/include/linux/file.h中{atomic_tcount;//结构的使用计数/structfdtable*fdt;//文件表指针structfdtablefdtab;//文件表spinlockfile_lock;//单个文件的锁intnext_fd;//下一个可用的文件描述符fdstructembedded_fd_setopen_fds_init;//当前已打开文件的文件描述符的位图,//1024位structembedded_fd_setclose_on_exec_init;//执行exec()时需关闭的文件描述符的//位图structfile*fd_arry[NR_OPEN_DEFAULT];//系统打开文件表数组,默认64个};6.7Linux文件系统

6.7.2虚拟文件系统VFS6.主要数据结构之间的关系

进程和文件系统主要数据结构之间的关系6.7Linux文件系统

6.7.3文件系统的注册、安装和卸载1.注册文件系统实际上是为该文件系统在内存中生成一个file_system_type结构,该结构包含了所注册文件系统的类型名称以及读取该文件系统超级块的服务例程的指针,定义在文件/include/linux/fs.h中structfile_system_type{constchar*name;//文件系统类型名intfs_flags;//文件系统的具体特性int(*get_sb)(structfile_system_type*,int,constchar*,void*,structvfsmount*);//读入相应文件系统的超级块的服务例程structmodule*owner;//具体可安装模块的module结构structfile_system_type*next;//文件系统类型链表的下一个指针structlist_headfs_supers;//该类型文件系统所安装的所有超级块链表

…}

6.7Linux文件系统

6.7.3文件系统的注册、安装和卸载1.注册文件系统

内核注册文件系统有以下两种方式:系统引导时在VFS中注册,系统关闭时注销。把文件系统作为内核可装载的模块,在实际安装时进行注册,并在模块卸载时注销。系统把当前所有已经注册到内核的文件系统的file_system_type结构组织成一个链表。

6.7Linux文件系统

6.7.3文件系统的注册、安装和卸载2.安装文件系统

(1)基本原理安装文件系统的主要工作是为该文件系统在内存中建立一个VFS超级块,并生成一个vfsmount结构,该结构定义在文件/include/linux/mount.h中。structvfsmount{structlist_headmnt_hash;//哈希表的指针structvfsmount*mnt_parent;//安装点所隶属的文件系统

structdentry*mnt_mountpoint;//该文件系统安装点目录的dentrystructdentry*mnt_root;//该文件系统根目录的dentrystructsuper_block*mnt_sb;//该文件系统的超级块对象

structlist_headmnt_mounts;//该安装点安装的所有文件系统链表structlist_headmnt_child;//已安装文件系统链表mnt_mounts的指针atomic_tmnt_count;//该vfsmount结构被引用的次数intmnt_flags;//安装选项char*mnt_devname;//设备文件名structlist_headmnt_list;//在vfsmount结构链表中的位置}6.7Linux文件系统

6.7.3文件系统的注册、安装和卸载2.安装文件系统

(1)基本原理超级块、安装点和具体的文件系统的关系6.7Linux文件系统

6.7.3文件系统的注册、安装和卸载2.安装文件系统

(2)安装命令mount文件系统的安装由mount命令完成,命令格式是:mount[-tvfstype][-ooptions]devicedir例如命令:mount-tiso9660/dev/hdc/mnt/cdrom其中iso9660是文件系统的类型名,/dev/hdc是包含待安装文件系统的物理设备,/mnt/cdrom是将要安装到的目录,即安装点。安装一个文件系统实际上是安装一个物理设备,即将不同分区中的单独的文件系统作为可装卸模块按一定方式形成整个树形目录结构中的一个分支。若指定的安装目录中原本就存在文件或下级子目录,则安装新的文件系统后,该目录下原有的文件和子目录将被掩盖,直到所安装的文件系统卸载后,安装目录中原来的文件会再次出现。6.7Linux文件系统

6.7.3文件系统的注册、安装和卸载2.安装文件系统

6.7Linux文件系统

6.7.3文件系统的注册、安装和卸载3.卸载文件系统卸载一个文件系统主要应完成如下工作:

如果文件系统中的文件当前正在使用,则卸载失败返回;

如果该文件系统的VFS超级块标志为“脏”,则必须将超级块信息写回磁盘;

释放该文件系统的VFS超级块;

从vfsmntlist链表中断开vfsmount数据结构,并将其释放。6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作1.open操作在linux中,open操作是由open系统调用完成的;而open系统调用的服务例程是sys_open()(在文件/fs/open.c中实现)。longdo_sys_open(intdfd,constchar__user*filename,intflags,intmode){ char*tmp=getname(filename); intfd=PTR_ERR(tmp); if(!IS_ERR(tmp)){ fd=get_unused_fd_flags(flags); if(fd>=0){ structfile*f=do_filp_open(dfd,tmp,flags,mode); if(IS_ERR(f)){ put_unused_fd(fd); fd=PTR_ERR(f); }else{ fsnotify_open(f->f_path.dentry); fd_install(fd,f); } } putname(tmp); } returnfd;}6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作1.open操作asmlinkagelongsys_open(constchar__user*filename,intflags,intmode){ longret; if(force_o_largefile()) flags|=O_LARGEFILE; ret=do_sys_open(AT_FDCWD,filename,flags,mode); prevent_tail_call(ret); returnret;}主要算法步骤:getname()函数做路径名的合法性检测。getname()在检查名字合法性的同时要把filename从用户数据区拷贝到内核数据区。它会检验给出的地址是否在当前进程中的虚存段内;在内核空间中申请一页;并把filename字符的内容拷贝到该页中去。get_unused_fd_flags()根据flag得到空的文件描述符指针。do_filp_open()按照指定的读写方式和用户权限打开文件,并返回文件描述符指针f。

如果所获file结构有错误,则释放文件描述符,设置fd为返回出错信息。fd_install()将打开文件的文件描述符指针f装入当前进程打开文件表中。

返回打开的文件描述符。6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作1.open操作staticstructfile*do_filp_open(intdfd,constchar*filename,intflags,intmode){ intnamei_flags,error; structnameidatand; namei_flags=flags; if((namei_flags+1)&O_ACCMODE) namei_flags++; error=open_namei(dfd,filename,namei_flags,mode,&nd); if(!error) returnnameidata_to_filp(&nd,flags); returnERR_PTR(error);}下面是sys_oepn流程中重要函数do_filp_open函数实现的分析主要算法步骤:

根据参数flags计算namei_flagsopen_namei()通过路径名获取其相应的dentry和vfsmount结构。

如果open_namei正常返回,则调用nameidata_to_filp(),通过open_namei()得到的dentry和vfsmount来得到file结构。否则返回错误信息。6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作2.close操作在Linux中,close操作是由close系统调用完成的。close系统调用的服务例程是sys_close()(在文件/fs/open.c中实现)。下面是对sys_close函数实现的分析。6.7Linux文件系统rcu_assign_pointer(fdt->fd[fd],NULL);FD_CLR(fd,fdt->close_on_exec);__put_unused_fd(files,fd);spin_unlock(&files->file_lock);retval=filp_close(filp,files);if(unlikely(retval==-ERESTARTSYS||retval==-ERESTARTNOINTR||retval==-ERESTARTNOHAND||retval==-ERESTART_RESTARTBLOCK))retval=-EINTR;returnretval;out_unlock:spin_unlock(&files->file_lock);return-EBADF;}asmlinkagelongsys_close(unsignedintfd){ structfile*filp;structfiles_struct*files=current->files; structfdtable*fdt; intretval; spin_lock(&files->file_lock); fdt=files_fdtable(files); if(fd>=fdt->max_fds)gotoout_unlock; filp=fdt->fd[fd]; if(!filp)gotoout_unlock;

6.7.4

Linux文件系统对文件的操作2.close操作主要算法步骤:

检查所要关闭的fd的合法性,是否小于进程可使用最大文件max_fds。如果不合法,则跳转到out_unlock段释放file_lock并返回。

根据fd获得文件描述符filp指针并对filp的合法性进行检查。如果不合法,同样跳转到out_unlock段释放file_lock并返回。

将当前进程使用文件结构files中文件描述符指针数组fd的对应指针置为空,清除对应文件描述符的索引位。put_unused_fd将对应的文件描述符的索引位重新置为可用。filp_close释放文件描述符,关闭文件。6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作3.read操作在linux中,read操作是通过sys_read系统调用实现的(在文件/fs/read_write.c中实现)。下面是sys_read函数asmlinkagessize_tsys_read(unsignedintfd,char__user*buf,size_tcount){ structfile*file; ssize_tret=-EBADF; intfput_needed; file=fget_light(fd,&fput_needed); if(file){loff_tpos=file_pos_read(file);ret=vfs_read(file,buf,count,&pos);file_pos_write(file,pos); fput_light(file,fput_needed); } returnret;}6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作3.read操作ssize_tvfs_read(structfile*file,char__user*buf,size_tcount,loff_t*pos){ssize_tret;

if(!(file->f_mode&FMODE_READ))return-EBADF; if(!file->f_op||(!file->f_op->read&&!file->f_op->aio_read))return-EINVAL; if(unlikely(!access_ok(VERIFY_WRITE,buf,count)))return-EFAULT; ret=rw_verify_area(READ,file,pos,count); if(ret>=0){count=ret;ret=security_file_permission(file,MAY_READ);if(!ret){ if(file->f_op->read) ret=file->f_op->read(file,buf,count,pos); else ret=do_sync_read(file,buf,count,pos); if(ret>0){ fsnotify_access(file->f_path.dentry); add_rchar(current,ret); }inc_syscr(current); } } returnret;}6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作3.read操作主要算法步骤:根据文件描述符fd调用fget_light()函数获得要读取文件的file结构变量指针。fget_light()会判断打开文件表是否多个进程共享,如果不是的话,没有必要增加对应file结构的引用计数。得到读文件开始时候的文件偏移量。调用vfs_read()函数判断访问模式是否为读模式在vfs_read()函数中,rw_verify_area()以读模式READ访问区域,返回负数表示不能访问。如果file->f_op->read函数不为空,则调用read,从文件位置指针file开始读取count个字节的内容到用户缓冲区buf。File->f_op->read就是具体文件系统的read函数的实现。调用fsnotify_access()通知感兴趣的进程,该文件已经被访问过。vfs_read()函数结束返回。重新写文件偏移量。执行fput_light(),如果需要会释放file结构的引用计数。6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作4.write操作在linux中,write操作是通过sys_write系统调用实现(在文件/fs/read_write.c中实现)。下面是对sys_write函数实现的分析。asmlinkagessize_tsys_write(unsignedintfd,constchar__user*buf,size_tcount){ structfile*file; ssize_tret=-EBADF; intfput_needed; file=fget_light(fd,&fput_needed); if(file){ loff_tpos=file_pos_read(file); ret=vfs_write(file,buf,count,&pos); file_pos_write(file,pos); fput_light(file,fput_needed); } returnret;}6.7Linux文件系统

6.7.4

Linux文件系统对文件的操作4.write操作6.7Linux文件系统ssize_tvfs_write(structfile*file,constchar__user*buf,size_tcount,loff_t*pos){ ssize_tret; if(!(file->f_mode&FMODE_WRITE)) return-EBADF; if(!file->f_op||(!file->f_op->write&&!file->f_op->aio_write)) return-EINVAL; if(unlikely(!access_ok(VERIFY_READ,buf,count))) return-EFAULT; ret=rw_verify_area(WRITE,file,pos,count); if(ret>=0){ count=ret; ret=security_file_permission(file,MAY_WRITE); if(!ret){ if(file->f_op->write) ret=file->f_op->write(file,buf,count,pos); else ret=do_sync_write(file,buf,count,pos); if(ret>0){ fsnotify_modify(file->f_path.dentry); add_wchar(current,ret); } inc_syscw(current); } }returnret;}

6.7.4

Linux文件系统对文件的操作4.write操作文件write操作和read操作非常类似,主要算法步骤:

根据fd调用fget_light()函数得到要写文件的file结构变量指针。fget_light()会判断打开文件表是否多个进程共享,如果不是的话,没有必要增加对应file结构的引用计数。

得到写文件开始时候的文件偏移量。

调用vfs_write()函数。判断访问模式是否为写模式在vfs_write()函数中,rw_verify_area()以写模式WRITE访问区域,返回负数表示不能访问。如果file->f_op->write函数不为空,则调用write,把用户缓冲区buf中的count个字节的内容写入文件偏移量位置。调用fsnotify_modify()通知感兴趣的进程,该文件已经被修改过。vfs_write()函数

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论