文件系统

来源:互联网 发布:边伯贤直播软件 编辑:程序博客网 时间:2024/06/15 08:06

为什么要有文件系统?——文件系统的意义

  应用程序都需要储存与检索信息,而信息虽然可以放在进程地址空间中,但是若文件大小大于虚拟地址空间,就不可行了(大量信息)。同时进程终止时,它保存的信息就丢失了(信息的长期保存)。而且多个进程可能都访问同一个数据,只有拥有该数据的进程才可调用,或要使用繁杂的IPC,不能满足并发的调用(多进程并发)。
  所以需要使信息本身独立与任何一个进程。
  基本功能:创建、删除文件、组织文件
  管理目录
  提供对文件的各种操作
  管理储存文件的空间
  保护文件

文件是解决信息存储问题的一个抽象

  文件提供了一种在磁盘上保留信息而且方便以后读取的方法。
  文件是一个逻辑上的概念,需要操作系统的文件系统进行逻辑概念与实际的物理空间的转换。
  ###文件的命名###
  ###文件的结构###
  有字节序列、记录序列和树
  ###文件类型###
  Unix与Linux系统的文件类型有c字符文件,b块文件,d目录文件,s套接口文件,-普通文件,l符号链接软连接文件,p管道文件。
  普通文件分为ASCII文件和二进制文件。ASCII文件可以很好的进行显示阅读与编辑,而二进制文件比较复杂。二进制文件有可执行文件和存档文件。

硬链接:在多个目录中出现同一个文件,这种类型的连接,增加了该文件inode节点计数器的计数。
符号连接:所建立的文件名指向了命名另一个文件的小文件,能够跨越磁盘的界限,甚至可以命名在远程计算机上的文件。

文件的管理与实现

  磁盘区分与文件系统布局:
  一个磁盘划分为多个分区,0号扇区:主引导记录(master boot record),用来引导计算机。
  接着是分区表:每个分区的起始与结束地址。表中的一个分区被标记为活动分区。
  接着就是不同磁盘分区了,在每个磁盘分区,都有引导款,超级快,空闲空间管理,i节点,根目录,文件和目录分块。不同分区对应着不同的文件系统。
  计算机被引导时,BIOS读入并执行MBR,MBR确定活动分区,读入它的引导块,并执行。引导块中的程序将装载该分区的操作系统。
  超级块包含文件系统的所有关键参数,确定文件系统类型用的魔数,数据块的数量等,在该计算机启动时,把超级块读入内存。
  超级块的作用解密
  在超级块中保存了如下有用的信 息。一是保存了文件系统的大小以及所用块的大小;二是保存了可用数据库的数量和部分可以及时分配的空闲数据块列表;三是最近一次的更新时间与文件系统的 状态;四是空闲Inode结点的个数和部分可以及时使用的inode结点列表。有时候在Unix操作系统上进行应用程序开发也需要用到这些信息。
  在超级块中保存了全局文件信息,如硬盘已用空间、数据块可用空间、inode结 点信息等等。
  当操作系统启动后,系统内核会把超级块中的内容复制到内存中,并周期性的利用内存里的最新内容去更新硬盘上的超级块中的内容。由于这个更新存在 一个时间差,为此内存中的超级块信息与硬盘中的超级块信息往往只有在开机与关机的某个特定时刻是同步的;而在其他时间都是不同步的。假设当操作系统意外当 机或者因为断电而造成的意外事故时,内存中的超级块信息没有及时保存到硬盘中,此时文件系统的完整性就会受到破坏。

  空闲块用位图或指针列表的形式给出。一组inode节点,数据结构数组,包含文件的很多信息。

  文件的储存即记录每个文件分别用了哪些磁盘块。
  1.有连续分配,存在碎片问题。
  2.链表分配:每块的头部的前几个字节用来存指向下一个磁盘块的指针。
  3.在内存中采用表的链表分配:FAT file allocation table 文件分配表。这种方法能使随机读取其中某一块所要的指针移动在内存中进行,不需要磁盘引用。但它对于大磁盘是不太适合的。
  而且整个磁盘块可以来存放数据,不需要再由保存指针信息的字节了。
  4.inode : 给每个文件赋予一个inode数据结构,其中列出了文件属性和文件块的磁盘位置地址。只有在对应文件打开时,其i节点才在内存中。最后一个磁盘地址不指向数据块,指向一个包含地址块地址的块的地址,以表征含比较多磁盘块的文件。
  inode结构属性:mode,nlinks,uid,gid,size,atime,mtime,ctime,zone

目录的实现:

  目录系统的作用:利用用户给出的路径名找到相应的目录项,目录项中提供了查找文件磁盘块所需要的信息。进行一个映射。
  目录文件维护一个目录项列表,每个目录项存放文件信息以及inode号。
  在目录中对文件名进行查找:散列表方法。线性查找方法。高速缓存方法。
  
  ..是父节点的硬链接:硬链接一般是不对目录的 ,否则会破坏树状结构 这是系统产生的,不是用户产生的,所以每个目录的硬链接数至少为2
类型是目录,目录文件不能直接打开,读写。否则会破坏树结构,是目录项的集合或序列。
每个目录项用来管理文件和解析路径名,借助于目录文件,得到物理定位,取得文件的inode号码。
目录项:文件名、文件属性、文件数据在磁盘上的地址:包括直接储存和间接寻址。Linux系统中只有文件名和inode号。
目录的操作:

CP/M 中的目录:系统中只有一个目录,目录项直接包含文件的多个磁盘块号, 一个文件可以有多个目录项组成
MS-DOS中的目录 FAT : 文件采用带索引的链接表分配方案

inode:2byte 块号:4bytes
文件的类型号可以直接放在目录项中来实现,可以提高速度
不需要提取文件的inode来查看
目录项至少要有文件名和inode号
挂载安装的文件子系统 会引起异常

  共享文件:
  使用连接机制。
  符号连接。LINK,只包含它所连接的文件的路径名,系统去找到那个文件,去读那个文件。
  *符号连接与硬链接的优缺点分析。*
  实现:系统调用:link和symlink
  命令行工具 ln 与ln -s
  符号连接:删除文件时不会产生问题,而且能连接到任何机器的文件上,但需要额外的开销包括inode与磁盘块,对这个文件的读取需要额外的磁盘存取。
  硬链接:目录项增加一项,内容为所连接目标文件的inode,inode中的计数器加1. 则在删除时,若删去文件磁盘块与inode,那么它的硬链接都失效了,之后可能会指向错误。只能删去对应的目录项,将inode计数减1.只有使count为0的删除,才可以删除其磁盘块与inode。
  硬链接不能连向目录,不能跨设备,不能产生U盘的硬链接文件与磁盘相连。
  
  为什么硬链接不能连向目录?
  如果引入了对目录的硬连接就有可能在目录中引入循环,那么在目录遍历的时候系统就会陷入无限循环当中。也许您会说,符号连接不也可以引入循环吗,那么为什么不限制目录的符号连接呢?原因就在于在linux系统中,每个文件(目录也是文件)都对应着一个inode结构,其中inode数据结构中包含了文件类型(目录,普通文件,符号连接文件等等)的信息,也就是说操作系统在遍历目录时可以判断出符号连接,既然可以判断出符号连接当然就可以采取一些措施来防范进入过大的循环了,系统在连续遇到8个符号连接后就停止遍历,这就是为什么对目录符号连接不会进入死循环的原因了。但是对于硬连接,由于操作系统中采用的数据结构和算法限制,目前是不能防范这种死循环的。
  
  为什么硬链接不能跨设备呢?
因为硬连接需要记录的是文件的inode号,在不同的文件系统中这个号码是可能相同的。
要确定一个目录是不是文件系统,你可以使用df命令来判断:
df -vh 可以看到有几个文件系统

  如何检测是否跨设备 ?mount命令可以查看文件系统分区的挂载信息:包括mount模式(r/w/rw) 挂载设备 mount到某一目录下。
  也可以对新的iso文件,移动硬盘,U盘进行任意位点的挂载。

  连接相关的系统调用:link 产生一个硬链接 ,目标文件的链接数加一,目录的目录项加1
  unlink :删除目录相并减少一个连接数,如果链接数为0并且没有任何进程打开该文件,该文件内容才能被真正删除,但是若又进程打开了该文件,则文件暂时不删除直到所有打开该文件的进程都结束时文件才能被删除。
  rm 也是去掉一个硬链接数,并删除本目录下的目录项

  其他文件相关的系统调用
  stat 系统调用 查看文件的基本信息
  fstat
  lstat函数类似于stat.但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用文件的信息。
对于命令行来说,只有stat命令
stat数据结构内容:mode,inode,device,num of link,uid , gid,size,atime,mtime,ctime,blksize(best IO block size),blocks

  还有:create,delete,open,close,read,write,append,seek,get attributes,set attributes,rename,lock等等

  日志结构文件系统与日志文件系统:

  虚拟文件系统:

文件系统管理和优化

  磁盘空间管理:
  块大小问题:太大:浪费空间;太小:浪费时间(大文件跨越多个块,需要多次寻道和旋转延迟才能读出)。合适的大小如何获得:现在考虑到磁盘空间都很大,可以包容一些浪费,使得块大小从4KB提到64KB

  记录空闲块:
  1.磁盘块链表
  磁盘块中包含空闲磁盘块号:如32位磁盘块号,在1KB的块中能存255个,剩下一个指向下一个保存空闲块号的磁盘块。
  2.位图表示法
  n个块的磁盘需要n位的位图,在位图中,空闲块用1表示,已分配块用0表示。
  位图表示法所需的空间比较少。
  也可以再加一个计数,来表示连接空闲块的数目。但是碎片很多的情况,这种做法更浪费空间。
  
  空闲表可以存放一个块在内存中,在临界状态时可能会引起多次的磁盘IO操作。替代策略就是,指针块满时,若磁盘中没有半满指针块,则拆分成两个半满指针块,若有,则存入满指针块,跳入半满指针块。
  在分页式内存系统中,位图可以保存在虚拟内存内,需要时将位图的页面调入。
  
  记录空间的inode结构
  1.堆栈:存放在超级块中。是读在内存里的。
2.位图方法

  文件系统备份:

  性能的优化:
  1.高速缓存
  减少磁盘访问次数:块高速缓存(block cache)或者缓冲区高速缓存(buffer cache)。逻辑上属于磁盘的,实际上基于性能的考虑被保存在内存中。
  不在高速缓存中的块,要先从磁盘上读到高速缓存中,再复制到所需的地方。
  高速缓存中有许多块。要进行快速检索,一般使用哈希表散列操作。对于有相同哈希值的块号,可以用链表相互连接。在这之外,还有一个双向链表把所有空闲块按照使用时间的先后次序连接起来,进来使用最少的在最前面,使用最多的在最后面。getblk 从LRU里拿,释放缓存块,后使位置插到队尾。可以维护一种准确的LRU顺序。散列表中不在空闲链中的块表示其正在使用。
  如果高速缓存已满:内存分页管理中的页面置换算法都可用:LRU: 最久没被用的页面要淘汰掉 ;MRU:用过后在链的最后添加;第二次机会算法;FIFO算法。
  但是,inode块读进高速缓存并更改过,不及时写入磁盘后果很严重。所以要改良:关系到文件系统一致性,可以马上写回磁盘。

带缓存表后的文件读写以及预读后写

文件块的写回:对齐问题
刷新缓存块内容:刷新大小小于文件缓存块大小
延迟写的问题:超块,inode块需要立刻写
数据块可以延迟写:

  高速缓存:优缺点
  优点:减少访盘次数
  提供了统一的磁盘存取方法
  系统对进行io的进程没有数据对齐的限定
  缓存快管理算法有主与文件系统的完整性
  缺点:延迟写在系统发生瘫痪时会引起很多问题
  当IO数据的传输量很大时,缓存机制会降低速度。
  2.块提前读
  对于顺序读取的文件,能增加速度。
  3.减少磁盘臂的运动
  使用inode的系统,读取很短的文件也需要两次磁盘访问:一次是访问inode,一次是访问块。改进:才磁盘中部放inode,或将磁盘分为柱面组。

Unix文件系统概述

  Unix目录包含文件名和inode编号(2个字节,16位)。每个文件系统有2^16/2^10=64K个文件。
  对于大文件,不止有一次间接块,还可有二次、三次间接块。
  使用1KB的数据块,4字节的磁盘块地址,inode有10个直接磁盘块,1个一级,1个二级,1个3级,最大文件是多少。
  (10+1KB/4B+256*256+256*256*256)KB=16G

  对于一个文件名,如何找到其物理的磁盘号?
  对于文件/usr/ast/courses/os/handout.t
  要调入它的inode,需要多少个磁盘操作?假设根目录inode在内存中,其他路径均不在
  通过inode指示的块号找到磁盘上防止根目录文件的内容为第一次读取;
通过目录文件的内容找到usr文件的inode所在磁盘位置并读取inode信息为第二次读取;
通过usr目录文件的inode指示的块号找到磁盘上usr目录文件的内容为第三次读取;
通过目录文件的内容找到ast文件的inode所在磁盘位置并读取inode信息为第四次读取;
通过ast目录文件的inode指示的块号找到磁盘上ast目录文件的内容为第五次读取;
通过目录文件的内容找到course文件的inode所在磁盘位置并读取inode信息为第六次读取;
通过course目录文件的inode指示的块号找到磁盘上course目录文件的内容为第七次读取;
通过目录文件的内容找到os文件的inode所在磁盘位置并读取inode信息为第八次读取;
通过os目录文件的inode指示的块号找到磁盘上os目录文件的内容为第九次读取;
通过目录文件的内容找到handout.t文件的inode所在磁盘位置并读取inode信息为第十次读取,这时handout.t文件的inode就调入到内存中了,共需10次访问操盘操作。
  一般来说,根目录的inode存放在磁盘上的固定位置。

  文件相关系统调用:
  文件的内容改了吗 属性改了吗
rename对文件存在修改了多少:除了名字都没改
cp 对文件存在修改了多少:都改了,内容一样

Inode解析

 文件的管理:inode 是一个数据结构。
 inode区是在磁盘上的一个特定区块,用来保存所有文件的inode,每个inode都有其物理空间。每个文件的inode号码不一样。有一些映射表可以查询inode号可以定位inode区的位置,主要是定位inode中的具体的块。
 存放文件相关信息:文件本体的磁盘号,大小,权限,创建时间等等信息。也就是说文件的物理定位和基本属性都在inode里面。
  路径名解析:就是通过文件名与逻辑上的路径,借助各级的目录文件,找个这个文件名所对应文件的inode。顺着inode信息,能找到数据本体与其属性。
inode中的属性:文件名不是文件的属性,文件名是其逻辑视图中的内容
目录是一个文件:根目录文件的inode是知道的。
目录文件的内容下其下的文件及其inode号,是目录项的序列

FAT文件系统

全局索引表,放了所有文件的链接信息,直接查找表,不用访问磁盘中的块,可以常住内存。
大小很大,有多少个块,就有多少个表项,占用大量的内存空间
FATA NTFS 文件系统

打开文件的管理 :

内存映射文件:
mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read/write函数。
可以用memory-mapped portion file 实现文件的复制。 内存的共享(假共享,要实时同步才行)。

在进程地址空间中就有一个是打开文件表。
系统有打开文件表,inode表(内存),文件系统安装表,块高速缓存区。

打开文件的过程:1.系统为该文件分配一个内存i-node结构,将磁盘上的i-node结构的主要内容copy过来。
2.系统为该文件分配一个系统打开文件表项file,并使其f_ninode指向内存i-node结构
3.在进程的user结构中的打开文件表项u_ofile[ ]中,找到一个空闲项,记下file结构的地址。
4.将进程的user结构中打开文件表项u_ofile[ ]的该项下标值fd返回给打开文件的调用者。
一个进程可以打开多个文件,
打开文件被多次打开;如果有冲突可以得知
count+1 事件:dup , fork 系统调用
exec会将整个进程的,0,1,2

块高速缓存:延迟写和提前读 能加速
5次分别写 5次IO 内存写 1次IO 有风险的
对磁盘的数据块一次性读一大块下来,多次从缓存中读取
读取可以是异步的,不影响用户的使用体验。

其他重要的文件系统

LFS:日志结构的文件系统
跟踪文件系统的变化

VFS 虚拟文件系统 NFS
提供上层接口

1 0
原创粉丝点击