Linux文件系统是怎么工作的?( 二 )

  • 第三类是网络文件系统,也就是用来访问其他计算机数据的文件系统,比如 NFS、SMB、iSCSI 等 。
  • 这些文件系统,要先挂载到 VFS 目录树中的某个子目录(称为挂载点),然后才能访问其中的文件 。拿第一类,也就是基于磁盘的文件系统为例,在安装系统时,要先挂载一个根目录(/),在根目录下再把其他文件系统(比如其他的磁盘分区、/proc 文件系统、/sys 文件系统、NFS 等)挂载进来 。
    文件系统I/O把文件系统挂载到挂载点后,你就能通过挂载点,再去访问它管理的文件了 。VFS 提供了一组标准的文件访问接口 。这些接口以系统调用的方式,提供给应用程序使用 。
    就拿 cat 命令来说,它首先调用 open() ,打开一个文件;然后调用 read() ,读取文件的内容;最后再调用 write(),把文件内容输出到控制台的标准输出中:
    int open(const char *pathname, int flags, mode_t mode);ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fd, const void *buf, size_t count);文件读写方式的各种差异,导致 I/O 的分类多种多样 。最常见的有,缓冲与非缓冲 I/O、直接与非直接 I/O、阻塞与非阻塞 I/O、同步与异步 I/O 等 。接下来,我们就详细看这四种分类 。
    第一种,根据是否利用标准库缓存,可以把文件 I/O 分为缓冲 I/O 与非缓冲 I/O 。
    缓冲 I/O,是指利用标准库缓存来加速文件的访问,而标准库内部再通过系统调度访问文件 。非缓冲 I/O,是指直接通过系统调用来访问文件,不再经过标准库缓存 。
    注意,这里所说的“缓冲”,是指标准库内部实现的缓存 。比方说,你可能见到过,很多程序遇到换行时才真正输出,而换行前的内容,其实就是被标准库暂时缓存了起来 。
    无论缓冲 I/O 还是非缓冲 I/O,它们最终还是要经过系统调用来访问文件 。
    第二,根据是否利用操作系统的页缓存,可以把文件 I/O 分为直接 I/O 与非直接 I/O 。
    直接 I/O,是指跳过操作系统的页缓存,直接跟文件系统交互来访问文件 。非直接 I/O 正好相反,文件读写时,先要经过系统的页缓存,然后再由内核或额外的系统调用,真正写入磁盘 。
    想要实现直接 I/O,需要你在系统调用中,指定 O_DIRECT 标志 。如果没有设置过,默认的是非直接 I/O 。
    不过要注意,直接 I/O、非直接 I/O,本质上还是和文件系统交互 。如果是在数据库等场景中,你还会看到,跳过文件系统读写磁盘的情况,也就是我们通常所说的裸 I/O 。
    第三,根据应用程序是否阻塞自身运行,可以把文件 I/O 分为阻塞 I/O 和非阻塞 I/O:
    所谓阻塞 I/O,是指应用程序执行 I/O 操作后,如果没有获得响应,就会阻塞当前线程,自然就不能执行其他任务 。所谓非阻塞 I/O,是指应用程序执行 I/O 操作后,不会阻塞当前的线程,可以继续执行其他的任务,随后再通过轮询或者事件通知的形式,获取调用的结果 。
    比方说,访问管道或者网络套接字时,设置 O_NONBLOCK 标志,就表示用非阻塞方式访问;而如果不做任何设置,默认的就是阻塞访问 。
    第四,根据是否等待响应结果,可以把文件 I/O 分为同步和异步 I/O:
    所谓同步 I/O,是指应用程序执行 I/O 操作后,要一直等到整个 I/O 完成后,才能获得I/O 响应 。所谓异步 I/O,是指应用程序执行 I/O 操作后,不用等待完成和完成后的响应,而是继续执行就可以 。等到这次 I/O 完成后,响应会用事件通知的方式,告诉应用程序 。
    举个例子,在操作文件时,如果你设置了 O_SYNC 或者 O_DSYNC 标志,就代表同步I/O 。如果设置了 O_DSYNC,就要等文件数据写入磁盘后,才能返回;而 O_SYNC,则是在 O_DSYNC 基础上,要求文件元数据也要写入磁盘后,才能返回 。
    再比如,在访问管道或者网络套接字时,设置了 O_ASYNC 选项后,相应的 I/O 就是异步I/O 。这样,内核会再通过 SIGIO 或者 SIGPOLL,来通知进程文件是否可读写 。
    你可能发现了,这里的好多概念也经常出现在网络编程中 。比如非阻塞 I/O,通常会跟select/poll 配合,用在网络套接字的 I/O 中 。
    你也应该可以理解,“Linux 一切皆文件”的深刻含义 。无论是普通文件和块设备、还是网络套接字和管道等,它们都通过统一的 VFS 接口来访问 。
    性能观测学了这么多文件系统的原理,你估计也是迫不及待想上手,观察一下文件系统的性能情况了 。
    接下来,打开一个终端,SSH 登录到服务器上,然后跟我一起来探索,如何观测文件系统的性能 。


    推荐阅读