在linux操作系統中,我們最常見的文本,圖片,可執行二進制文件這些是最為常見的文件。除此之外文件夾也是一種特殊的文件,軟鏈接、硬鏈接依然是文件。不僅如此,就連我們/dev下面的硬件設備、套接字、管道這些東西在Linux中統統都是文件。
索引節點和目錄項
Linux中所有文件都有一個唯一與之對應的索引節點(Index Node),索引節點記錄了文件的元數據,操作系統並不通過文件名,而是通過索引節點來管理文件,用目錄項(Directory Entry)來描述文件之間的關系。
-
索引節點,簡稱為 inode,用來記錄文件的元數據,比如 inode 編號、文件大小、訪問權限、修改日期、數據的位置等。索引節點和文件一一對應,它跟文件內容一樣,都會被持久化存儲到磁盤中。所以記住,索引節點同樣占用磁盤空間。
-
目錄項,簡稱為 dentry,用來記錄文件的名字、索引節點指針以及與其他目錄項的關聯關系。多個關聯的目錄項,就構成了文件系統的目錄結構。不過,不同於索引節點,目錄項是由內核維護的一個內存數據結構,所以通常也被叫做目錄項緩存。
簡言之,索引節點相當於文件的指針,目錄項維護着文件的樹型關系。
磁盤的存儲區域
-
扇區:磁盤最小讀寫單位為扇區,每個扇區大小為512B
-
邏輯塊:如果操作系統以最小單位讀寫磁盤,效率無疑是非常底下的,因此將8個連續扇區組成一個4k大小的邏輯塊作為數據單元來進行管理
在進行文件系統格式化時,會將磁盤划分為三個區域:
-
超級塊,存儲整個文件系統的狀態。
-
索引節點區,用來存儲索引節點。
-
數據塊區,則用來存儲文件數據。
磁盤、索引節點、目錄項、邏輯塊的關系如下圖所示:

目錄項本身是一個內存緩存,索引節點則是存儲在磁盤中,但是為了加快文件訪問速度,索引節點和文件內容也會被讀入到緩存中。
虛擬文件系統
索引節點、目錄項、邏輯塊、超級塊是構成文件系統的四大基本要素。但是,為了能夠使用各種不同的文件系統,在用戶進程和內核之間引入了一個抽象層——虛擬文件系統VFS。

VFS定義了一組所有文件系統都支持的數據結構和標准接口。因此用戶進程只需要和VFS交互即可,無需針對每一種文件系統開發不同的應用程序。
文件系統按照存儲位置不同,可分為三類:
-
基於磁盤的文件系統:Ext4、XFS、OverlayFS 等, 直接將數據存儲在本地掛在的磁盤。
-
基於內存的文件系統:如/proc、/sys等目錄,無需分配磁盤空間,但是占用內存。
-
網絡文件系統:訪問遠程其他主機的文件系統,如NTFS、SMB等。
文件系統的IO類型
根據文件系統的讀寫差異,可以將IO分為四種類型:
-
緩沖 I/O,是指利用標准庫緩存來加速文件的訪問,而標准庫內部再通過系統調度訪問文件。
-
非緩沖 I/O,是指直接通過系統調用來訪問文件,不再經過標准庫緩存。
此處標准庫緩存指的是利用棧、隊列等一些數據結構進行的資源調度,而不是頁緩存。無論是否緩沖IO,都會通過系統調用頁緩存來減少IO次數。
根據是否利用操作系統的頁緩存,可以把文件 I/O 分為直接 I/O 與非直接 I/O。
-
直接 I/O,是指跳過操作系統的頁緩存,直接跟文件系統交互來訪問文件。
-
非直接 I/O 正好相反,文件讀寫時,先要經過系統的頁緩存,然后再由內核或額外的系統調用,真正寫入磁盤。
通常情況下我們的IO都是非直接IO,在數據庫等場景中,你還會看到,跳過文件系統讀寫磁盤的情況,也就是我們通常所說的裸 I/O。
據應用程序是否阻塞自身運行,可以把文件 I/O 分為阻塞 I/O 和非阻塞 I/O:
-
所謂阻塞 I/O,是指應用程序執行 I/O 操作后,如果沒有獲得響應,就會阻塞當前線程,自然就不能執行其他任務。
-
所謂非阻塞 I/O,是指應用程序執行 I/O 操作后,不會阻塞當前的線程,可以繼續執行其他的任務,隨后再通過輪詢或者事件通知的形式,獲取調用的結果。
默認情況下IO都是阻塞的。網絡編程中非阻塞 I/O,通常會跟 select/poll 配合,用在網絡套接字的 I/O 中。
根據是否等待響應結果,可以把文件 I/O 分為同步和異步 I/O:
-
所謂同步 I/O,是指應用程序執行 I/O 操作后,要一直等到整個 I/O 完成后,才能獲得 I/O 響應。
-
所謂異步 I/O,是指應用程序執行 I/O 操作后,不用等待完成和完成后的響應,而是繼續執行就可以。等到這次 I/O 完成后,響應會用事件通知的方式,告訴應用程序。
文件系統的觀測
-
容量:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
jeeyshe@jeeyshe-PC:~$
df
文件系統 1K-塊 已用 可用 已用% 掛載點
udev 3997588 0 3997588 0%
/dev
tmpfs 805208 1868 803340 1%
/run
/dev/sda3
46631732 8521096 35712124 20% /
tmpfs 4026032 44240 3981792 2%
/dev/shm
tmpfs 5120 4 5116 1%
/run/lock
tmpfs 4026032 0 4026032 0%
/sys/fs/cgroup
/dev/sda1
306584 6668 299916 3%
/boot/efi
/dev/sda4
93266544 8084300 80401548 10%
/home
tmpfs 805204 40 805164 1%
/run/user/1000
/dev/sda5
93266544 57368 88428480 1%
/media/jeeyshe/_dde_data
/dev/sdb3
115272700 45983312 69289388 40%
/media/jeeyshe/500CEF460CEF25A6
|
索引節點的容量,(也就是 Inode 個數)是在格式化磁盤時設定好的,一般由格式化工具自動生成。當你發現索引節點空間不足,但磁盤空間充足時,很可能就是過多小文件導致的。
加入一下參數可以看到更加詳細和人性化的容量信息:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
jeeyshe@jeeyshe-PC:~$
df
-ih
文件系統 Inode 已用(I) 可用(I) 已用(I)% 掛載點
udev 976K 576 976K 1%
/dev
tmpfs 983K 890 983K 1%
/run
/dev/sda3
2.9M 239K 2.7M 9% /
tmpfs 983K 46 983K 1%
/dev/shm
tmpfs 983K 7 983K 1%
/run/lock
tmpfs 983K 17 983K 1%
/sys/fs/cgroup
/dev/sda1
0 0 0 -
/boot/efi
/dev/sda4
5.7M 98K 5.6M 2%
/home
tmpfs 983K 28 983K 1%
/run/user/1000
/dev/sda5
5.7M 11 5.7M 1%
/media/jeeyshe/_dde_data
/dev/sdb3
67M 503K 67M 1%
/media/jeeyshe/500CEF460CEF25A6
|
-
緩存:此處只觀測索引節點和目錄項

關於頁緩存、swap、buf等概念,將在其他篇章介紹。
