操作系统学习笔记 ----文件系统

1 基本组成

基本数据单位是 文件

Linux 最经典的一句话是:「一切皆文件」,不仅普通的文件和目录,就连块设备、管道、socket 等,也都是统一交给文件系统管理的。

Linux 文件系统会为每个文件分配两个数据结构:索引节点(index node)和目录项(directory entry),用来记录文件的元信息目录层次结构

  • 索引节点( inode),用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识。同样占用磁盘空间

  • 目录项(dentry),用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。

目录也是文件,也是用索引节点唯一标识,和普通文件不同的是,普通文件在磁盘里面保存的是文件数据,而目录文件在磁盘里面保存子目录或文件。

目录是个文件,持久化存储在磁盘,而目录项是内核一个数据结构,缓存在内存。

磁盘读写的最小单位是扇区,扇区的大小只有 512B 大小,文件系统把多个扇区组成了一个逻辑块,每次读写的最小单位就是逻辑块(数据块),大小为 4KB(相当于一次性读写8个扇区)

索引节点、目录项以及文件数据的关系如下图:
在这里插入图片描述

磁盘进行格式化的时候,会被分成超级块、索引节点区和数据块区。

· 超级块,用来存储文件系统的详细信息,比如块个数、块大小、空闲块等等。
· 索引节点区,用来存储索引节点;
· 数据块区,用来存储文件或目录数据;

超级块 与 索引节点区 进内存的时机不同:

· 超级块:当文件系统挂载时进入内存;
· 索引节点区:当文件被访问时进入内存;

2 文件系统

位于用户层与文件系统层中间,该中间层被称为虚拟文件系统(Virtual File System,VFS),如下图:
在这里插入图片描述
Linux 支持的文件系统也不少,根据存储位置的不同,可以把文件系统分为三类:

  • 磁盘的文件系统,它是直接把数据存储在磁盘中,比如 Ext 2/3/4、XFS 等都是这类文件系统。

  • 内存的文件系统,这类文件系统的数据不是存储在硬盘的,而是占用内存空间,我们经常用到的 /proc 和 /sys 文件系统都属于这一类,读写这类文件,实际上是读写内核中相关的数据。

  • 网络的文件系统,用来访问其他计算机主机数据的文件系统,比如 NFS、SMB 等等。

读文件和写文件的过程:

  • 当用户进程从文件读取 1 个字节大小的数据时,文件系统则需要获取字节所在的数据块,再返回数据块对应的用户进程所需的数据部分。

  • 当用户进程把 1 个字节大小的数据写进文件时,文件系统则找到需要写入数据的数据块的位置,然后修改数据块中对应的部分,最后再把数据块写回磁盘。

所以说文件系统的基本操作单位是数据块。

文件存储

包括:连续空间存放、非连续空间存放(链表方式、索引方式)

2.1 连续空间存放

文件存放在磁盘「连续的」物理空间中,读写效率很高,前提是必须先知道一个文件的大小。文件头里需要指定「起始块的位置」和「长度」

问题: 有「磁盘空间碎片」和「文件长度不易扩展」的缺陷。

2.2 非连续空间存放

1、链表方式

链表的方式存放是离散的,不用连续的,于是就可以消除磁盘碎片,可大大提高磁盘空间的利用率,同时文件的长度可以动态扩展。

1.1、隐式链表

实现的方式是文件头要包含「第一块」和「最后一块」的位置,并且每个数据块里面留出一个指针空间,用来存放下一个数据块的位置

缺点:

无法直接访问数据块,只能通过指针顺序访问文件,以及数据块指针消耗了一定的存储空间。
隐式链接分配的稳定性较差,系统在运行过程中由于软件或者硬件错误导致链表中的指针丢失或损坏,会导致文件数据的丢失。

1.2、显式链接

实现的方式是把用于链接文件各数据块的指针,显式地存放在内存的一张链接表中,该表在整个磁盘仅设置一张,每个表项中存放链接指针,指向下一个数据块号。内存中的这样一个表格称为文件分配表(File Allocation Table,FAT)。

优点:不仅显著地提高了检索速度,而且大大减少了访问磁盘的次数。
缺点:

由于整个表都存放在内存中的关系,不适用于大磁盘。

2、索引方式

实现方式是为每个文件创建一个「索引数据块」,里面存放的是指向文件数据块的指针列表(像书的目录一样),文件头需要包含指向「索引数据块」的指针。

在这里插入图片描述

优点:

  • 文件的创建、增大、缩小很方便;
  • 不会有碎片的问题;
  • 支持顺序读写和随机读写;

缺点:存储索引带来的开销

如果文件很大,大到一个索引数据块放不下索引信息,该如何处理?

方式一:链表 + 索引的组合,这种组合称为「链式索引块」,它的实现方式是在索引数据块留出一个存放下一个索引数据块的指针
在这里插入图片描述
问题在于,一旦某一指针损坏,后面的数据也无法读取

方式二:索引 + 索引的方式,这种组合称为「多级索引块」,实现方式是通过一个索引块来存放多个索引数据块
在这里插入图片描述

在这里插入图片描述

2.3 空闲空间管理

1、空闲表法

为所有空闲空间建立一张表,表内容包括空闲区的第一个块号和该空闲区的块个数(连续分配)
在这里插入图片描述
这种方法仅当有少量的空闲区时才有较好的效果。适用于建立连续文件。

2、空闲链表法

每一个空闲块里有一个指针指向下一个空闲块。当创建文件需要一块或几块时,就从链头上依次取下一块或几块。反之,当回收空间时,把这些空闲块依次接到链头上。

在这里插入图片描述
简单,但不能随机访问,工作效率低,每当在链上增加或移动空闲块时需要做很多 I/O 操作,同时数据块的指针消耗了一定的存储空间。

3、位图法

位图是利用二进制的一位来表示磁盘中一个盘块的使用情况,磁盘上所有的盘块都有一个二进制位与之对应。
当值为 0 时,表示对应的盘块空闲,值为 1 时,表示对应的盘块已分配。它形式如下:
在这里插入图片描述

2.4 文件系统结构

Linux Ext2 整个文件系统的结构和块组的内容,文件系统都由大量块组组成,在硬盘上相继排布:
在这里插入图片描述
最前面的第一个块是引导块,在系统启动时用于启用引导,接着后面就是一个一个连续的块组了,块组的内容如下:

  • 超级块,包含的是文件系统的重要信息,比如 inode 总个数、块总个数、每个块组的 inode 个数、每个块组的块个数等等。
  • 块组描述符,包含文件系统中各个块组的状态,比如块组中空闲块和 inode 的数目等,每个块组都包含了文件系统中「所有块组的组描述符信息」。
  • 数据位图和 inode 位图, 用于表示对应的数据块或 inode 是空闲的,还是被使用中。
  • inode 列表,包含了块组中所有的 inode,inode 用于保存文件系统中与各个文件和目录相关的所有元数据。
  • 数据块,包含文件的有用数据。

目录的存储

普通文件的块里面保存的是文件数据,而目录文件的块里面保存的是目录里面一项一项的文件信息。
在目录文件的块中,最简单的保存格式就是列表,就是一项一项地将目录下的文件信息(如文件名、文件 inode、文件类型等)列在表里。通过这个 inode,就可以找到真正的文件。

软链接、硬链接

硬链接(Hard Link)是多个目录项中的「索引节点」指向一个文件(同一个inode)。

硬链接是不可用于跨文件系统的。由于多个目录项都是指向一个 inode,那么只有删除文件的所有硬链接以及源文件时,系统才会彻底删除该文件

在这里插入图片描述

软链接(Symbolic Link)相当于重新创建一个文件,这个文件有独立的 inode,文件内容是另外一个文件的路径。
软链接是可以跨文件系统的,甚至目标文件被删除了,链接文件还是在的,只不过指向的文件找不到了而已。

在这里插入图片描述

2.5 文件 I/O

2.5.1 缓冲与非缓冲 I/O

根据「是否利用标准库缓冲」

缓冲 I/O,利用的是标准库的缓存实现文件的加速访问,而标准库再通过系统调用访问文件。
非缓冲 I/O,直接通过系统调用访问文件,不经过标准库缓存。

2.5.2 直接与非直接 I/O

根据「是否利用操作系统的缓存」

直接 I/O,不会发生内核缓存和用户程序之间数据复制,而是直接经过文件系统访问磁盘。
非直接 I/O,读操作时,数据从内核缓存中拷贝给用户程序,写操作时,数据从用户程序拷贝给内核缓存,再由内核决定什么时候写入数据到磁盘。

几种场景会触发内核缓存的数据写入磁盘:

· 在调用 write 的最后,当发现内核缓存的数据太多的时候,内核会把数据写到磁盘上;
· 用户主动调用 sync,内核缓存会刷到磁盘上;
· 当内存十分紧张,无法再分配页面时,也会把内核缓存的数据刷到磁盘上;
· 内核缓存的数据的缓存时间超过某个时间时,也会把数据刷到磁盘上;

2.5.3 阻塞与非阻塞 I/O VS 同步与异步 I/O

在这里插入图片描述
阻塞 IO:阻塞等待的是「内核数据准备好」和「数据从内核态拷贝到用户态」这两个过程
非阻塞 IO:最后一次 read 调用,获取数据的过程,是一个同步的过程(同步指的是内核态的数据拷贝到用户程序的缓存区这个过程)
I/O 多路复用:用户可以在一个线程内同时处理多个 socket 的 IO 请求

以上均为同步调用

异步 IO
异步 I/O 是「内核数据准备好」和「数据从内核态拷贝到用户态」这两个过程都不用等待。
在这里插入图片描述

总结:

I/O 是分为两个过程的:

1、数据准备的过程
2、数据从内核空间拷贝到用户进程缓冲区的过程

阻塞IO 阻塞1、2;非阻塞IO 、IO多路复用只会阻塞 2 ,以此认为都是同步 IO;异步 IO不会阻塞 1、2

2.6 Page Cache

它是文件系统中用于缓存文件数据的缓冲。
文件传输过程,其中第一步都是先把磁盘文件数据拷贝「内核缓冲区」里,这个「内核缓冲区」实际上是磁盘高速缓存(PageCache)。

作用:

  • 缓存最近被访问的数据;
  • 预读功能;

page 是内存管理分配的基本单位, Page Cache 由多个 page 构成。
page 在操作系统中通常为 4KB 大小(32bits/64bits),而 Page Cache 的大小则为 4KB 的整数倍。

Linux 系统上供用户可访问的内存分为两个类型,即:

  • File-backed pages:文件备份页也就是 Page Cache 中的 page,对应于磁盘上的若干数据块;对于这些页最大的问题是脏页回盘

  • Anonymous pages:匿名页不对应磁盘上的任何磁盘数据块,它们是进程的运行是内存空间(例如方法栈、局部变量表等属性);

File-backed pages 与 Anonymous pages 在 Swap 机制下的性能比较:
File-backed pages(Page Cache)的内存回收代价较低。

Page Cache 通常对应于一个文件上的若干顺序块,因此可以通过顺序 I/O 的方式落盘。
如果 Page Cache 上没有进行写操作(所谓的没有脏页),甚至不会将 Page Cache 回盘,因为数据的内容完全可以通过再次读取磁盘文件得到。

Anonymous pages 的内存回收代价较高。

Anonymous pages 通常随机地写入持久化交换设备。
无论是否有写操作,为了确保数据不丢失,Anonymous pages 在 swap 时必须持久化到磁盘。

2.6.1 Swap、缺页中断

Swap 机制指的是当物理内存不够用,内存管理单元(Memory Mangament Unit,MMU)需要提供调度算法来回收相关内存空间,然后将清理出来的内存空间给当前内存申请方。

Swap 机制存在的本质原因是
Linux 系统提供了虚拟内存管理机制,所有进程的内存空间之和远远大于物理内存,超出物理内存的部分需要交换到磁盘上

缺页中断:操作系统以 page 为单位管理内存,当进程发现需要访问的数据不在内存时,操作系统可能会将数据以页的方式加载到内存中。通过页面替换解决缺页中断,替换操作触发swap机制

2.6.2 预读机制

操作系统为基于 Page Cache 的读缓存机制提供预读机制(PAGE_READAHEAD)
在这里插入图片描述

2.6.3 Page Cache 与文件持久化的一致性&可靠性

文件 = 数据 + 元数据。元数据用来描述文件的各种属性,也必须存储在磁盘上。即一致性表示数据一致性和元数据一致性

当前 Linux 下以两种方式实现文件一致性:

  • Write Through(写穿):向用户层提供特定接口,应用程序可主动调用接口来保证文件一致性;
  • Write back(写回):系统中存在定期任务(表现形式为内核线程),周期性地同步文件系统中文件脏数据块,这是默认的 Linux 一致性方案;

上述两种方式最终都依赖于系统调用,主要分为如下三种系统调用:
在这里插入图片描述

Write Through 与 Write back 在持久化的可靠性上有所不同:

  • Write Through 以牺牲系统 I/O 吞吐量作为代价,向上层应用确保一旦写入,数据就已经落盘,不会丢失;
  • Write back 在系统发生宕机的情况下无法确保数据已经落盘,因此存在数据丢失的问题。不过,在程序挂了,例如被 kill -9,Page Cache 中的数据操作系统还是会确保落盘;

2.6.4 Page Cache优劣势

优势:

  • 加快数据访问
  • 减少 I/O 次数,提高系统磁盘 I/O 吞吐量

劣势:

  • 需要占用额外物理内存空间
  • 对应用层并没有提供很好的管理 API,几乎是透明管理
  • 在某些应用场景下比 Direct I/O 多一次磁盘读 I/O 以及磁盘写 I/O
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Swing_zzZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值