Linux操作系统分析与实践_第1页
Linux操作系统分析与实践_第2页
Linux操作系统分析与实践_第3页
Linux操作系统分析与实践_第4页
Linux操作系统分析与实践_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

Linux操作系统分析与实践第五讲:文件管理,Linux操作系统分析与实践课程建设小组北京大学二零零八年春季*致谢:感谢Intel对本课程项目的资助,本讲主要内容,虚拟文件系统VFSExt2文件系统,文件管理器,设备驱动,磁盘,设备API,文件API,传统文件系统,文件管理器,设备驱动,磁盘,POSIX文件API,POSIX文件API,Linux文件系统,设备独立转换器,虚拟文件系统,内核软件层,在内核中提供一个文件系统框架(接口函数集、管理用的数据结构、各种缓存机制)为各种文件系统提供通用接口,Linux文件管理系统调用接口,VFS开关,Ext2文件系统,VFAT文件系统,NFS文件系统,Proc文件系统,虚拟文件系统(续),支持的文件系统可分为三类基于磁盘的文件系统e.gVFAT、NTFS、ISO9660CDROM网络文件系统e.gNFS、Coda特殊文件系统不管理磁盘空间,e.g/proc所有的文件系统都可以安装到根系统的子目录中,通用文件模型,用于表示所有支持的文件系统,由以下对象类型组成超级块对象:存放已安装文件系统信息索引节点对象:存放文件信息,每个索引节点对象的索引节点号唯一地标识了文件系统中的文件文件对象:存放打开文件与进程间交互的信息目录项对象:存放目录项与文件进行链接的信息同时VFS还使用了磁盘高速缓存(软件机制),将常用的目录项对象放在目录项高速缓存中,通用文件模型(续),这个模型是对要支持的文件系统的一种抽象,对于UNIX系列的,直接就可以很好地支持;对于没有目录文件的文件系统,比如FAT系列,Linux需要能够快速建立对应于目录的文件可以将VFS看成一种通用文件系统,它位于应用程序和具体文件系统之间,提供了一层通用的接口,它在必要时依赖具体的文件系统,通用文件模型(续),VFS数据结构,描述各对象的数据结构超级块对象super_block索引节点对象inode文件对象file目录项对象dentry,超级块对象,超级块对象structsuper_blockstructlist_heads_list;/*Keepthisfirst*/kdev_ts_dev;unsignedlongs_blocksize;unsignedchars_blocksize_bits;unsignedchars_dirt;unsignedlonglongs_maxbytes;/*Maxfilesize*/structfile_system_type*s_type;structsuper_operations*s_op;structdquot_operations*dq_op;.structlist_heads_files/*分配给超级块的文件对象链表*/;所有超级块对象由循环双链表组成,首元素s_list超级块操作在s_op中,超级块对象(续),structsuper_operationsvoid(*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*);主要的操作对象:i节点、超级块、文件系统,索引节点对象,structinodestructlist_headi_hash;structlist_headi_list;structlist_headi_dentry;.unsignedlongi_ino;/*索引节点号*/atomic_ti_count;/*引用计数器*/unsignedlongi_nrpages/*包含文件数据的页数*/.structinode_operations*i_op;/*索引节点的操作*/wait_queue_head_ti_wait;/*索引节点等待队列*/structfile_lock*i_flock;/*指向文件锁链表的指针*/structaddress_space*i_mapping;/*共享内存中使用的address_space指针*/structaddress_spacei_data;/*块设备的address_space对象*/.structpipe_inode_info*i_pipe;.structblock_device*i_bdev;/*指向块设备驱动程序*/structchar_device*i_cdev;/*指向字符设备驱动程序*/.unsignedchari_sock;/*文件是否是套接字*/;,索引节点对象(续),分为三类,每一类均组织成双向循环链表,由inode.i_list连接未使用的索引节点正在使用的索引节点脏索引节点索引节点对象组织成inode_hashtable散列表,冲突的节点组成链表,由inode.i_hash连接,索引节点对象(续),structinode_operationsint(*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)(structinode*,structdentry*);int(*mknod)(structinode*,structdentry*,int,int);int(*rename)(structinode*,structdentry*,structinode*,structdentry*);int(*readlink)(structdentry*,char*,int);int(*follow_link)(structdentry*,structnameidata*);void(*truncate)(structinode*);int(*permission)(structinode*,int);int(*revalidate)(structdentry*);int(*setattr)(structdentry*,structiattr*);int(*getattr)(structdentry*,structiattr*);int(*setxattr)(structdentry*,constchar*,void*,size_t,int);ssize_t(*getxattr)(structdentry*,constchar*,void*,size_t);ssize_t(*listxattr)(structdentry*,char*,size_t);int(*removexattr)(structdentry*,constchar*);目录项对象相关的文件的索引节点的创建、查找、修改、删除,文件对象,文件对象在磁盘上没有映像,在文件被打开时创建文件对象也分为三类,每类是双向循环链表,由file.f_list连接未使用的文件对象,首元素free_list还未分配给超级块的在使用的文件对象,首元素anon_list分配给超级块的在使用的文件对象,首元素为super_block.s_files,文件对象(续),structfilestructlist_headf_list;/*Pointersforgenericfileobjectlist*/structdentry*f_dentry;/*dentryobjectassociatedwiththefile*/structvfsmount*f_vfsmnt;/*Mountedfilesystemcontainingthefile*/structfile_operations*f_op;/*Pointertofileoperationtable*/atomic_tf_count;/*Fileobjectsusagecounter*/.loff_tf_pos;/*Currentfileoffset(filepointer)*/.void*private_data;/*Neededforttydriver*/.structkiobuf*f_iobuf;/*Descriptorfordirectaccessbuffer*/longf_iobuf_lock;/*LockfordirectI/Otransfer*/;,文件对象(续),structfile_operationsstructmodule*owner;loff_t(*llseek)(structfile*,loff_t,int);ssize_t(*read)(structfile*,char*,size_t,loff_t*);ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);int(*readdir)(structfile*,void*,filldir_t);unsignedint(*poll)(structfile*,structpoll_table_struct*);int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);/*Sendsacommandtoanunderlyinghardwaredevice*/int(*mmap)(structfile*,structvm_area_struct*);int(*open)(structinode*,structfile*);int(*flush)(structfile*);int(*release)(structinode*,structfile*);int(*fsync)(structfile*,structdentry*,intdatasync);int(*fasync)(int,structfile*,int);int(*lock)(structfile*,int,structfile_lock*);ssize_t(*readv)(structfile*,conststructiovec*,unsignedlong,loff_t*);ssize_t(*writev)(structfile*,conststructiovec*,unsignedlong,loff_t*);ssize_t(*sendpage)(structfile*,structpage*,int,size_t,loff_t*,int);unsignedlong(*get_unmapped_area)(structfile*,unsignedlong,unsignedlong,unsignedlong,unsignedlong);,目录项对象,目录项用于建立与索引节点的联系,在磁盘上没有映像目录项对象的四种状态空闲:未关联索引节点未使用:关联索引节点,但未被内核使用正在使用:关联索引节点,且正被使用negative:关联的索引节点不存在,目录项对象(续),structdentryatomic_td_count;unsignedintd_flags;structinode*d_inode;/*Wherethenamebelongsto-NULLisnegative*/structdentry*d_parent;/*parentdirectory*/structlist_headd_hash;/*lookuphashlist*/structlist_headd_lru;/*d_count=0LRUlist*/structlist_headd_child;/*childofparentlist*/structlist_headd_subdirs;/*ourchildren*/structlist_headd_alias;/*inodealiaslist*/intd_mounted;structqstrd_name;unsignedlongd_time;/*usedbyd_revalidate*/structdentry_operations*d_op;structsuper_block*d_sb;/*Therootofthedentrytree*/unsignedlongd_vfs_flags;void*d_fsdata;/*fs-specificdata*/unsignedchard_inameDNAME_INLINE_LEN;/*smallnames*/;,目录项对象(续),structdentry_operationsint(*d_revalidate)(structdentry*,int);int(*d_hash)(structdentry*,structqstr*);int(*d_compare)(structdentry*,structqstr*,structqstr*);int(*d_delete)(structdentry*);void(*d_release)(structdentry*);void(*d_iput)(structdentry*,structinode*);目录项对象的管理、目录项高速缓存的维护,目录项高速缓存,包括:在使用、未使用和negative状态的目录项对象,组织成最近最少使用的双向链表在使用:dentry.d_alias未使用:dentry.d_lrunegative:内核维护散列表dentry_hashtable,文件名和目录名到目录项对象的hash表,各元素指向冲突元素链表目录项对象通过dentry.d_hash连接各冲突元素,与进程相关的文件,structtask_struct.structfs_struct*fs;/*文件系统信息*/structfiles_struct*files;/*当前打开的文件信息*/.;structfiles_structstructfile*fd;/*文件对象数组,索引就是文件描述符*/structfile*fd_arrayNR_OPEN_DEFAULT;,特殊文件系统,给用户提供一种容易的方式操作内核数据结构并实现操作系统的特殊特征,文件系统注册,用file_system_type结构表示文件系统类型链表,首元素为file_systems读/写自旋锁为file_system_lock相关的操作register_filesystem()unregister_filesystem()get_fs_type(),文件系统注册,name“ext2”fa_flagsread_supernext,name“proc”fa_flagsread_supernext,name“iso9660”fa_flagsread_supernext,file_systems,文件系统注册(续),structfile_system_typeconstchar*name;intfs_flags;structsuper_block*(*read_super)(structsuper_block*,void*,int);structmodule*owner;structfile_system_type*next;structlist_headfs_supers;/linklistheadofsuperblocks;,文件系统安装,文件系统可以安装在系统的任意目录下e.gmountttypedevdir多个文件系统可以安装到同一个目录结构类型为vfsmount的数据结构描述每个已安装文件描述符,内核中是一个双向链表,首指针为mnt_list可使用的操作alloc_vfsmnt():分配并初始化已安装文件系统描述符free_vfsmnt():释放指定的已安装文件系统描述符lookup_mnt():在散列表中查找描述符并返回它的地址,文件系统安装(续),根文件系统的安装:1、安装特殊文件系统rootfs,用来提供作为初始安装点的空目录,主要由函数init_mount_tree()完成2、在空目录上安装一个真正的根目录,由函数mount_root()完成whyrootfs?Linux允许根文件系统存放在很多不同的地方,因此内核在启动时可能会安装和卸载多个根文件系统,使用rootfs可以很容易改变实际的根目录,文件系统安装(续),安装一般文件系统,系统调用mount()-sys_mount()-do_mount():1、查找要安装到的目录的目录项2、优先针对三种安装标志参数值执行相应的操作MS_REMOUNT:do_remount()重新安装改变了安装标志的文件系统MS_BIND:调用do_loopback()完成“绑定安装”,使系统目录树中的另一个目录能看见MS_MOVE:调用do_move_mount()改变已安装文件系统的目录3、否则,调用do_add_mount()安装普通系统,文件系统安装(续),卸载文件系统,系统调用umount()-sys_umount():1、查找文件系统目录的目录项对象2、以下情况返回出错:传入的目录参数不是文件系统的目录文件系统没有安装在目录下用户不具有卸载文件系统的特权3、调用do_umount()卸载文件系统,文件加锁,多个进程访问同一个文件时必须要解决同步问题read()、write()等操作:原子性的文件加锁机制允许对整个文件或它的某一部分进行加锁,同一个文件不同部分可以保持多个锁,文件加锁(续),Linux中的文件锁分类:POSIX标准规定的两种锁:劝告锁(建议锁)只有当其他进程显式检查文件锁时,这个文件锁才起作用强制锁每次调用open()、read()、write()系统调用时,内核要检查确保这些系统调用不违背在所访问文件上加的强制锁强制锁的两种变种:共享模式强制锁:进程打开文件的时候不能锁设置的访问模式相冲突租借锁:打开受租借锁保护的文件的进程必须被阻塞,直到在一定时间间隔内拥有锁的进程更新文件并释放锁,否则,由内核自动删除,文件加锁(续),FL_POSIX与进程和索引节点相关联,可指定具体区段FL_LOCK与文件对象相关联,锁整个文件,文件加锁(续),描述文件锁的数据结构:structfile_lockwait_queue_head_tfl_wait;/*processesblockedatthislock*/structfile*fl_file;unsignedcharfl_flags;unsignedcharfl_type;loff_tfl_start;loff_tfl_end;void(*fl_notify)(structfile_lock*);/*unblockcallback*/void(*fl_insert)(structfile_lock*);/*lockinsertioncallback*/void(*fl_remove)(structfile_lock*);/*lockremovalcallback*/;所有的file_lock组织成双链表,首元素为file_lock_list同一文件的file_lock结构也是一个链表,首元素为索引节点对象中的i_flock字段,路径名查找,要考虑的问题:1、进程是否有权限读取目录的内容2、目录是否为符号链接3、符号链接导致的循环引用问题4、文件名是否是已安装文件系统的安装点,VFS的系统调用,open()、read()、write()、close()填相应的数据结构需要注意的地方:1、读写的时候注意检查文件锁,读写都是调用具体注册的文件系统的操作来实现2、关闭的时候注意释放文件锁、调flush()同步,Ext2文件系统,ext21993年创建,是ext的改进版本,具有如下的特点:支持UNIX所有标准的文件特征可管理大硬盘,一个分区的容量最大可达4TB它使用变长的目录项,支持255个字符的长文件名,可扩展到1012个字符使用位图来管理数据块和节点的使用情况使用了块组的概念,从而使数据的读和写更快,更有效,也使系统变得更安全可靠,Ext2:磁盘数据结构,Ext2将磁盘分区看成是由块组组成,每个块组包含一个或多个块每个块组大小相同,且顺序存放,structext2_super_block_u32s_inodes_count;/*索引节点总数*/_u32s_blocks_count;/*文件系统的块数*/_u32s_r_blocks_count;/*保留给内核使用的块数*/_u32s_free_blocks_count;/*空闲块计数器*/_u32s_free_inodes_count;/*空闲索引节点计数器*/_u32s_first_data_block;/*第一个数据块的块号*/_u32s_log_block_size;/*块大小*/._u32s_blocks_per_group;/*#每组的块数*/._u32s_inodes_per_group;/*#每组的节点数*/.;,structext2_group_desc_u32bg_block_bitmap;/*块位图的块号*/_u32bg_inode_bitmap;/*索引节点位图的块号*/_u32bg_inode_table;/*第一个索引节点表块的块号*/_u16bg_free_blocks_count;/*组中空闲块的个数*/_u16bg_free_inodes_count;/*组中索引点的个数*/_u16bg_used_dirs_count;/*组中目录的个数*/;注:各位图存放在一个单独的块中,1、索引节点表由多个块组成,每个块存放多个大小相同的索引节点2、ext2_super_block.bg_inode_table指向第一个块的块号structext2_inode_u16i_mode;/*描述的是什么及用户应具有的权限*/._u32i_size;/*文件的有效长度*/._u32i_blocks;/*已分配给文件的数据块数*/._u32i_blockEXT2_N_BLOCKS;/*指针数组,各元素指向分配给文件的数据块*/.;i_size最高位没有使用,因此文件大小限制为2GB块组和索引节点表的使用,可以快速得到索引节点的磁盘地址,文件类型为目录时,数据块存放目录项数据结构:structext2_dir_entry_u32inode;/*索引节点号*/_u16rec_len;/*目录项长度*/_u8name_len;/*文件名长度*/_u8name_len;/*文件名类型*/charnameEXT2_NAME_LEN;/*文件名*/;删除目录项:inode置0,并增长前一个有效目录项的rec_len长度,这样在计算下一个有效目录项时,就可以跳过该已删除的目录项,文件类型普通文件目录字符设备特殊文件块设备特殊文件命名管道Socket符号连接,文件查找,/usr/include/stdio.h从当前进程的根目录

温馨提示

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

评论

0/150

提交评论