前情提要

探索檔案系統

檢視現有檔案系統例項

檢視目錄掛載的檔案系統用量

檢視檔案系統掛載配置

檢視核心支援的檔案系統

開發檔案系統為什麼難?

核心檔案系統

FUSE 檔案系統

總結

原創不易,更多幹貨,歡迎關注公眾號:奇伢雲端儲存

前情提要

來一個硬核系列,得益於 Linux 一切皆檔案的哲學,把檔案系統玩轉的飛起。檔案系統所有人都聽過,都用過,但是就很少有人深究。

對於檔案系統,大家的態度可能是兩個極端,要麼就是覺得好深奧,好牛,你竟然懂這玩意!要麼就是,檔案系統是什麼鬼?不就是那個。。。我在 Linux 用過無數次的。這玩意還用得著講? 這兩種態度可能都不合適,檔案系統作為一個深入我們生活的事物,我們不應去忽略它,也不要去抬高或者貶低。我們應該要去了解它,打破對它的恐懼,因為恐懼是對未知事物產生的一種情緒。平視它,瞭解清楚脈絡,從而掌握它。 小孩在為什麼總是學習東西很快?因為他們都是從形到意,先直觀的摸到,看到,嗅到,吃到,先感受到“形”,然後我們教導他這些東西是的含義。他們很快就接受了。 我們這個自制檔案系統,就是想從形意結合,讓讀者朋友能夠跟隨著筆者一起經歷一次檔案系統由 0 到 1 的過程,構建好知識框架,後續的深造將會得心應手。 好,話不多說,我們先從什麼是檔案系統講起,簡單介紹一些探索檔案系統的基礎知識。

探索檔案系統

檢視現有檔案系統例項

Linux 檔案系統相比大家都使用過。大家在自己的 Linux 上機器上執行

mount

命令就能看到當前系統上掛載的所有檔案系統:

mount

示例如下:

root@localhost:~# mount

sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel)

proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,seclabel)

/dev/mapper/cl-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

。。。。

比如透過這一行資訊我們能看出來:

sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)

資訊拆解分析:

sysfs

:檔案系統

名稱

/sys

:檔案系統目錄

掛載點

sysfs

:檔案系統

型別

(ro,nosuid,nodev,noexec,relatime)

:掛載引數

這裡蘊含的重要資訊:

同一個檔案系統型別是可以建立多個例項的,掛載在不同的掛載點,就跟面向物件裡的類和例項的關係;

基礎知識點:掛載點必須是目錄

其實,

mount

這個命令很強大,不僅能 list 所有的檔案系統,還能掛載檔案系統。如下:

掛載檔案系統

# 把已經格式化好的 /dev/sdb1 盤掛到 /mnt 目錄上

mount -t ext4 /dev/sdb1 /mnt/

對應解除安裝檔案系統命令

# 解除安裝 /mnt 的掛載點

umount /mnt

檢視目錄掛載的檔案系統用量

mount

命令能看到所有的掛載列表,但是如果你想要看到所有檔案系統的使用情況,則需要另一個命令:

df

df

命令用來檢視當前作業系統掛載的檔案系統和

使用情況

df -Tha

-T 引數能夠讓你看到所有的檔案系統例項的型別;

-h 引數能夠以更符合人類的友好的形式展示資料;

-a 引數展示所有的檔案系統,包括 0 Blocks 的檔案系統(預設是會過濾掉的);

示例如下:

root@localhost:~# df -ahT

Filesystem Type Size Used Avail Use% Mounted on

sysfs sysfs 0 0 0 - /sys

proc proc 0 0 0 - /proc

/dev/mapper/cl-root xfs 17G 11G 7。0G 60% /

。。。

注意,如果

df

沒有加

-a

引數,類似於上面 sysfs,proc 這種用量 0 的會被過濾掉。這也是

mount

df

兩個命令預設顯式資訊的區別。

檢視檔案系統掛載配置

檔案系統掛載可以透過

mount

命令直接掛載,但是

mount

命令掛載並沒有持久化,關機重啟就沒了。所以想要關機重啟之後,還能自動掛載到指定目錄,那麼就要把掛載規則寫到

/etc/fstab

檔案中,

fstab

就是 fs table 的縮寫,很容易理解。

作業系統在啟動的時候,就會解析這個檔案,並按照這個檔案裡的配置,自動掛載檔案系統了。

如下:

root@localhost:~# cat /etc/fstab

/dev/mapper/cl-root / xfs defaults 0 0

UUID=600e3771-af4a-48ca-a557-02204c9a48a5 /boot ext4 defaults 1 2

/dev/mapper/cl-swap swap swap defaults 0 0

fstab 的檔案格式:

<裝置標識> <掛載目錄> <檔案系統型別> <掛載引數>

從左到右引數拆解:

裝置標識:能夠標識到唯一的檔案系統所在的裝置,這裡可以是裝置路徑,也可以是 LABEL,或者 UUID;

掛載目錄:檔案系統掛載的目錄點;

檔案系統型別:比如 ext4,ext2,xfs 之類的;

掛載引數:可以填 defaults,也可以精細化配置,比如只讀還是可寫(rw/ro),同步刷盤還是非同步(async/sync),等等;

dump選項:讓你能控制檔案系統備份的頻率,0 表示不備份;

fsck選項:讓你控制是否開機用 fsck 自檢,0 表示不要;

檢視核心支援的檔案系統

這個直接去看核心模組即可:

ls /lib/modules/${kernel_version}/kernel/fs/

不同的 Linux 發行版略有不同,比如,centos 一般為:

ls -l /lib/modules/4。18。0-80。el8。x86_64/kernel/fs/

ubuntu 一般為:

ls -l /lib/modules/4。4。0-142-generic/kernel/fs/

在對應的目錄找到對應的 。ko 模組,比如

ext4。ko

,如果想看核心已經載入的核心模組,可以呼叫

lsmod

看到。

簡單普及一下 .ko 模組的知識:

ko

其實是

kernel object

的縮寫,這類檔案存在的意義其實和使用者態的 。so 庫類似,都是為了模組化的程式設計實踐。核心把核心主幹框架之外的功能拆解成模組,需要的時候就載入 ko 模組,不需要的時候解除安裝即可。這樣帶來的好處就是方便開發和使用,保持核心的核心程式碼極度精煉。

類似於檔案系統,硬體驅動等等,都是以這種形式來載入使用的。

開發檔案系統為什麼難?

為什麼檔案系統的開發大家會覺得非常難?原因其實不在於實現,而在於除錯和排障,因為早期檔案系統的開發只能在核心之中,這個帶來了非常高的門檻。

核心檔案系統

因為在此之前我們看到了檔案系統是位於核心之中, vfs 之下,塊儲存模組之上的一個位置。對外呈現檔案儲存實現,對下管理裸塊裝置。劃重點,檔案系統是位於核心的一個模組,那就可以理解了,核心模組的開發之所以艱難就是難在除錯和排障,使用者態的程式你可以隨意 debug,出問題最多也就是 panic,coredump,核心態的程式出了檔案就是宕機,所有現場都丟失,你只能透過日誌,kdump 等手段來排查。並且核心態程式的編寫是要注意非常多的規範的,比如記憶體分配,比使用者態的要謹慎的多。

自制檔案系統 — 01 檔案系統的樣子

那怎麼辦?我們本次的目標是要自制實現一個極簡的檔案系統,但總不能帶大家趟一次核心開發的坑吧!那可是要嚇退 99% 的小夥伴。

有辦法的,核心開發者考慮到了這個問題,又考慮到檔案系統的需求是千變萬化的,所以提供了一種手段,把 IO 路徑導向使用者態,由使用者態程式捕獲到 IO ,從而實現檔案的儲存,這個機制就叫 FUSE 機制。

FUSE 檔案系統

作為系列第一篇,我們不講 FUSE 的實現,而是透過一個動畫來演示 IO 的旅途:

自制檔案系統 — 01 檔案系統的樣子

這裡的路徑做了一些簡化,簡化了使用者態之上的邏輯處理,以後詳細解釋。

原創不易,更多幹貨,歡迎關注公眾號:奇伢雲端儲存

總結

本篇文章是為後續鋪墊一些基礎知識,從

的方面,系統介紹了一些命令,告訴你檔案系統怎麼配置,怎麼掛載,怎麼檢視,怎麼獲取到使用詳情。這些基礎知識在後面自制檔案系統的時候,都要用上。這些 Linux 命令

都是幫助我們從檔案系統的外圍去用,去摸,去嗅,從而再去深入理解

我們目標不止如此,我們是要親手做一個檔案系統,動手做過一遍的東西,你對它理解也將會突飛猛進,更加深刻。

下面總結一下上面的基礎以上的知識:

mount

用來列舉檢視當前所有檔案系統例項,也能支援掛載命令(但

mount

掛載不會持久化,重啟就沒了),

umount

用來解除安裝;

/etc/fstab

是用來配置檔案系統掛載規則的,是持久化的配置,重啟不丟;

df -aTh

用來檢視每個檔案系統掛載目錄的詳情,包括空間使用量,總量,掛載點等資訊;

核心模組的功能以

ko

檔案的形式體現,在

/lib/modules/${kernel_version}/kernel/fs/

目錄可以看到支援的核心檔案系統模組,

lsmod

命令可以看到已經載入的核心模組;

檔案系統開發之所以難?是因為之前在核心中開發,核心開發最難的在於除錯和排障手段不方便。那檔案系統還有出路嗎?有,奇伢帶你

自制一個極簡的檔案系統

,基於 Linux 系統使用純 Go 語言來做哦,敬請期待後續,自己動手,理解更深;

原創不易,更多幹貨,歡迎關注公眾號:奇伢雲端儲存