Linux 內核101:虛擬文件系統的使命

本文參考了:node

  • 《Understanding the Linux Kernel, Third Edition》12.1章

簡介

Linux 的成功有一部分緣由在於可以很好的支持不一樣的文件系統,你可以輕鬆透明地把 Windows、其餘 Unix 系統、甚至是佔有極小份額的 Amiga 使用的文件系統 mount 到Linux 的文件系統中。這是經過Virtual Filesystem(如下簡稱 VFS)實現的。bash

VFS 背後的 idea 是在 kernel 中抽象出不一樣文件系統,針對具體的文件系統,Linux kernel 實現具體的操做方法。當系統調用readwrite發生時,kernel 根據操做的具體文件系統,好比 native Linux文件系統、NTFS(Windows NT)等,調用相對應的函數。數據結構

實例:cp

要執行一個cp指令:ide

cp /floppy/TEST /tmp/test
複製代碼

其中/floppy是一個 mount 的MS-DOS文件系統,而/tmp是 ext2。VFS 就是應用程序和底層文件系統實現之間的一個抽象層cp不須要知道/floppy/TEST/tmp/test的文件系統類型,它只須要調用標準的系統調用,好比readwrite這些,把底層文件系統不一樣帶來的複雜度交給 kernel函數

示例的代碼以下:ui

inf = open("/floppy/TEST", O_RDONLY, 0);
outf = open("/tmp/test",
       O_WRONLY|O_CREAT|O_TRUNC, 0600);
do {
    i = read(inf, buf, 4096);
    write(outf, buf, i);
  } while (i);
close(outf);
close(inf);
複製代碼

示意圖:編碼

代碼和截圖來源於 《Understanding the Linux Kernel, Third Edition》 P457idea

VFS 支持的文件系統

VFS 支持嗯文件系統一共分爲下面三大類:spa

  1. Disk-based FS

本地的 disk。包括:翻譯

  • ext2, etx3, ext4
  • Unix 家族,好比 sysv 文件系統、UFS(BSD,solaris)、MINIX等
  • Microsoft 文件系統,好比 MS-DOS、NTFS
  • ISO9660 CD-ROM(以前的High Sierra Filesystem)
  • 其餘冷門
  1. Network FS

這一類支持訪問遠程的文件系統,好比 NFS、Coda、AFS 等。

  1. Special FS

/proc虛擬文件系統。

一般來講,root 目錄爲 Linux 原生的ext2ext3ext4,其餘類型的文件系統經過mount形式 mount 到某個特定子目錄。

Common File Model

VFS 背後的核心idea: 用common file model表示全部現實中的FS。這個模型嚴格使用原生Unix FS 模型,每一個特定的 FS 都須要將本身的硬件結構翻譯成 common file model。

好比在 common file model 中,目錄也被看作文件,包含其餘的文件盒目錄。然而,一些非 Unix 的 FS,使用的是 file allocation table(FAT),這種狀況下,目錄不是文件。可是爲了遵循 common file model的規則,Linux 對這種 FAT-based 的 FS,必須可以抽象出一個遵循common file model 的接口。

更加具體點,Linux kernel 在處理readioctl這些系統調用的時候,不能直接硬編碼,使用某個特定的底層函數。kernel實際上針對每個操做,使用的是一個指針,這個指針指向了針對此文件系統專門的處理函數。

讓咱們來看看kernel 是如何完成上面提到的cp操做的。

應用層調用read(),kernel 實際上會調用sys_read() service routine(其餘的系統調用也同樣)。MS-DOS FS 的文件被 kernel memory 中的一個數據結構表示,這個數據結構包含一個f_op字段,指向的是針對 MS-DOS 的 read 函數。sys_read()找到這個函數而後調用它。因此整個過程能夠看做是:

read() -> sys_read() -> file data structure -> f_op -> read_for_msdos()
複製代碼

調用write()也同樣,這個系統調用會觸發針對ext2 FS 的寫調用。

簡要來講,對於每一個 open()建立的 file object,kernel 須要負責正確賦值此 file object的指針,指向針對此文件系統的特定函數,而後調用這些函數。

CFM 包含哪些 object types

  • superblock object:包含的是 mounted FS 的數據。
  • indoe object:特定文件的數據。對於 disk-based FS,這個 object 通常對應一個 file control block。每一個 inode object 都有一個 inode number,惟一指定 FS 中的某一個文件。
  • file object:一個open file 和進程之間的交互信息。這個 object 只在進程打開文件的時候在kernel memory 中存在
  • dentry object:文件名到inode的映射,不一樣的 FS 有不一樣的底層實現。

總結一下

VFS 是應用和特定文件系統之間的一層抽象,有些操做可以直接在 VFS 層完成,不須要涉及到底層的具體文件系統。好比說,當進程close file的時候,disk 上的文件自己是不會改變的,因此 VFS 只要把對應的 file 對象釋放掉就好了。再好比說,lseek()系統調用,改變的也是內存中的 file 對象,而不須要設計底層的文件系統。

相關文章
相關標籤/搜索