歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux - EXT2文件系統詳述

Linux - EXT2文件系統詳述

日期:2017/2/28 13:59:24   编辑:Linux教程

文件系統特性

舉例來說,Windows 98 以前的微軟操作系統主要利用的文件系統是 FAT (或 FAT16),Windows 2000 以後的版本有所謂的 NTFS 文件系統,至於 Linux 的正統文件系統則為 Ext2 (Linux second extended file system, ext2fs)這一個。此外,在默認的情況下,Windows 操作系統是不會認識 Linux 的 Ext2 的。

那麼文件系統是如何運行的呢?這與操作系統的文件數據有關。較新的操作系統的文件數據除了文件實際內容外, 通常含有非常多的屬性,例如 Linux 操作系統的文件權限(rwx)與文件屬性(擁有者、群組、時間參數等)。 文件系統通常會將這兩部份的數據分別存放在不同的區塊,權限與屬性放置到 inode 中,至於實際數據則放置到 data block 區塊中。 另外,還有一個超級區塊 (superblock) 會記錄整個文件系統的整體信息,包括 inode 與 block 的總量、使用量、剩余量等。

每個 inode 與 block 都有編號,至於這三個數據的意義可以簡略說明如下:

superblock:記錄此 filesystem 的整體信息,包括inode/block的總量、使用量、剩余量, 以及文件系統的格式與相關信息等;

inode:記錄文件的屬性,一個文件占用一個inode,同時記錄此文件的數據所在的 block 號碼;

block:實際記錄文件的內容,若文件太大時,會占用多個 block 。

我們將 inode 與 block 區塊用圖解來說明一下,如下圖所示,文件系統先格式化出 inode 與 block 的區塊,假設某一個文件的屬性與權限數據是放置到 inode 4 號(下圖較小方格內),而這個 inode 記錄了文件數據的實際放置點為 2, 7, 13, 15 這四個 block 號碼,此時我們的操作系統就能夠據此來排列磁盤的閱讀順序,可以一口氣將四個 block 內容讀出來! 那麼數據的讀取就如同下圖中的箭頭所指定的模樣了。

這種數據存取的方法我們稱為索引式文件系統(indexed allocation)。那有沒有其他的慣用文件系統可以比較一下啊? 有的,那就是我們慣用的閃盤(閃存),閃盤使用的文件系統一般為 FAT 格式。FAT 這種格式的文件系統並沒有 inode 存在,所以 FAT 沒有辦法將這個文件的所有 block 在一開始就讀取出來。每個 block 號碼都記錄在前一個 block 當中, 他的讀取方式有點像底下這樣:

上圖中我們假設文件的數據依序寫入1->7->4->15號這四個 block 號碼中, 但這個文件系統沒有辦法一口氣就知道四個 block 的號碼,他得要一個一個的將 block 讀出後,才會知道下一個 block 在何處。 如果同一個文件數據寫入的 block 分散的太過厲害時,則我們的磁盤讀取頭將無法在磁盤轉一圈就讀到所有的數據, 因此磁盤就會多轉好幾圈才能完整的讀取到這個文件的內容!

data block (數據區塊)

data block 是用來放置文件內容數據地方,在 Ext2 文件系統中所支持的 block 大小有 1K, 2K 及 4K 三種而已。在格式化時 block 的大小就固定了,且每個 block 都有編號,以方便 inode 的記錄啦。 不過要注意的是,由於 block 大小的差異,會導致該文件系統能夠支持的最大磁盤容量與最大單一文件容量並不相同。 因為 block 大小而產生的 Ext2 文件系統限制如下:

除此之外 Ext2 文件系統的 block 還有什麼限制呢?有的!基本限制如下:

原則上,block 的大小與數量在格式化完就不能夠再改變了(除非重新格式化);

每個 block 內最多只能夠放置一個文件的數據;

承上,如果文件大於 block 的大小,則一個文件會占用多個 block 數量;

承上,若文件小於 block ,則該 block 的剩余容量就不能夠再被使用了(磁盤空間會浪費)。

inode table (inode 表格)

再來討論一下 inode 這個玩意兒吧!如前所述 inode 的內容在記錄文件的屬性以及該文件實際數據是放置在哪幾號 block 內! 基本上,inode 記錄的文件數據至少有底下這些:

該文件的存取模式(read/write/excute);

該文件的擁有者與群組(owner/group);

該文件的容量;

該文件創建或狀態改變的時間(ctime);

最近一次的讀取時間(atime);

最近修改的時間(mtime);

定義文件特性的旗標(flag),如 SetUID...;

該文件真正內容的指向 (pointer);

inode 的數量與大小也是在格式化時就已經固定了,除此之外 inode 還有些什麼特色呢?

每個 inode 大小均固定為 128 bytes;

每個文件都僅會占用一個 inode 而已;

承上,因此文件系統能夠創建的文件數量與 inode 的數量有關;

系統讀取文件時需要先找到 inode,並分析 inode 所記錄的權限與用戶是否符合,若符合才能夠開始實際讀取 block 的內容。

我們約略來分析一下 inode / block 與文件大小的關系好了。inode 要記錄的數據非常多,但偏偏又只有 128bytes 而已, 而 inode 記錄一個 block 號碼要花掉 4byte ,假設我一個文件有 400MB 且每個 block 為 4K 時, 那麼至少也要十萬筆 block 號碼的記錄呢!inode 哪有這麼多可記錄的信息?為此我們的系統很聰明的將 inode 記錄 block 號碼的區域定義為12個直接,一個間接, 一個雙間接與一個三間接記錄區。這是啥?我們將 inode 的結構畫一下好了。

上圖最左邊為 inode 本身 (128 bytes),裡面有 12 個直接指向 block 號碼的對照,這 12 筆記錄就能夠直接取得 block 號碼啦! 至於所謂的間接就是再拿一個 block 來當作記錄 block 號碼的記錄區,如果文件太大時, 就會使用間接的 block 來記錄編號。如上圖 1.3.2 當中間接只是拿一個 block 來記錄額外的號碼而已。 同理,如果文件持續長大,那麼就會利用所謂的雙間接,第一個 block 僅再指出下一個記錄編號的 block 在哪裡, 實際記錄的在第二個 block 當中。依此類推,三間接就是利用第三層 block 來記錄編號!

Superblock (超級區塊)

Superblock 是記錄整個 filesystem 相關信息的地方, 沒有 Superblock ,就沒有這個 filesystem 了。他記錄的信息主要有:

block 與 inode 的總量;

未使用與已使用的 inode / block 數量;

block 與 inode 的大小 (block 為 1, 2, 4K,inode 為 128 bytes);

filesystem 的掛載時間、最近一次寫入數據的時間、最近一次檢驗磁盤 (fsck) 的時間等文件系統的相關信息;

一個 valid bit 數值,若此文件系統已被掛載,則 valid bit 為 0 ,若未被掛載,則 valid bit 為 1 。

[root@www ~]# dumpe2fs [-bh] 裝置文件名

選項與參數:

-b :列出保留為壞軌的部分(一般用不到吧!?)

-h :僅列出 superblock 的數據,不會列出其他的區段內容!

范例:找出我的根目錄磁盤文件名,並觀察文件系統的相關信息

[root@www ~]# df

Filesystem 1K-blocks Used Available Use% Mounted on

/dev/hdc2 9920624 3822848 5585708 41% /

/dev/hdc3 4956316 141376 4559108 4% /home

/dev/hdc1 101086 11126 84741 12% /boot

tmpfs 371332 0 371332 0% /dev/shm

[root@www ~]# dumpe2fs /dev/hdc2

dumpe2fs 1.39 (29-May-2006)

Filesystem volume name: /1

Filesystem features: has_journal ext_attr resize_inode dir_index

filetype needs_recovery sparse_super large_file

Default mount options: user_xattr acl

Filesystem state: clean

Errors behavior: Continue

Filesystem OS type: Linux

Inode count: 2560864

Block count: 2560359

Free blocks: 1524760

Free inodes: 2411225

First block: 0

Block size: 4096

Filesystem created: Fri Sep 5 01:49:20 2008

Last mount time: Mon Sep 22 12:09:30 2008

Last write time: Mon Sep 22 12:09:30 2008

Last checked: Fri Sep 5 01:49:20 2008

First inode: 11

Inode size: 128

Journal inode: 8

Journal backup: inode blocks

Journal size: 128M

Group 0: (Blocks 0-32767)

Primary superblock at 0, Group descriptors at 1-1

Reserved GDT blocks at 2-626

Block bitmap at 627 (+627), Inode bitmap at 628 (+628)

Inode table at 629-1641 (+629)

0 free blocks, 32405 free inodes, 2 directories

Free blocks:

Free inodes: 12-32416

Group 1: (Blocks 32768-65535)

....(底下省略)....

# 由於數據量非常的龐大,因此將一些信息省略輸出了!

# 前半部在秀出 supberblock 的內容,包括標頭名稱(Label)以及inode/block的相關信息

# 後面則是每個 block group 的個別信息了!您可以看到各區段數據所在的號碼!

# 也就是說,基本上所有的數據還是與 block 的號碼有關就是了!很重要!

目錄

當我們在 Linux 下的 ext2 文件系統創建一個目錄時, ext2 會分配一個 inode 與至少一塊 block 給該目錄。其中,inode 記錄該目錄的相關權限與屬性,並可記錄分配到的那塊 block 號碼; 而 block 則是記錄在這個目錄下的文件名與該文件名占用的 inode 號碼數據。也就是說目錄所占用的 block 內容在記錄如下的信息:

[root@www ~]# ls -li

total 92

654683 -rw------- 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg

648322 -rw-r--r-- 1 root root 42304 Sep 4 18:26 install.log

648323 -rw-r--r-- 1 root root 5661 Sep 4 18:25 install.log.syslog

[root@www ~]# ll -d / /bin /boot /proc /lost+found /sbin

drwxr-xr-x 23 root root 4096 Sep 22 12:09 /

drwxr-xr-x 2 root root 4096 Sep 24 00:07 /bin

drwxr-xr-x 4 root root 1024 Sep 4 18:06 /boot

drwx------ 2 root root 16384 Sep 5 01:49 /lost+found

dr-xr-xr-x 96 root root 0 Sep 22 20:07 /proc

drwxr-xr-x 2 root root 12288 Sep 5 12:33 /sbin

文件:

當我們在 Linux 下的 ext2 創建一個一般文件時, ext2 會分配一個 inode 與相對於該文件大小的 block 數量給該文件。例如:假設我的一個 block 為 4 Kbytes ,而我要創建一個 100 KBytes 的文件,那麼 linux 將分配一個 inode 與 25 個 block 來儲存該文件! 但同時請注意,由於 inode 僅有 12 個直接指向,因此還要多一個 block 來作為區塊號碼的記錄。

目錄樹讀取:

由於目錄樹是由根目錄開始讀起,因此系統透過掛載的信息可以找到掛載點的 inode 號碼(通常一個 filesystem 的最頂層 inode 號碼會由 2 號開始喔!),此時就能夠得到根目錄的 inode 內容,並依據該 inode 讀取根目錄的 block 內的文件名數據,再一層一層的往下讀到正確的檔名。

[root@www ~]# ll -di / /etc /etc/passwd

2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /

1912545 drwxr-xr-x 105 root root 12288 Oct 14 04:02 /etc

1914888 -rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd

/ 的 inode:

透過掛載點的信息找到 /dev/hdc2 的 inode 號碼為 2 的根目錄 inode,且 inode 規范的權限讓我們可以讀取該 block 的內容(有 r 與 x) ;

/ 的 block:

經過上個步驟取得 block 的號碼,並找到該內容有 etc/ 目錄的 inode 號碼 (1912545);

etc/ 的 inode:

讀取 1912545 號 inode 得知 vbird 具有 r 與 x 的權限,因此可以讀取 etc/ 的 block 內容;

etc/ 的 block:

經過上個步驟取得 block 號碼,並找到該內容有 passwd 文件的 inode 號碼 (1914888);

passwd 的 inode:

讀取 1914888 號 inode 得知 vbird 具有 r 的權限,因此可以讀取 passwd 的 block 內容;

passwd 的 block:

最後將該 block 內容的數據讀出來。

EXT2/EXT3 文件的存取與日志式文件系統的功能

上一小節談到的僅是讀取而已,那麼如果是新建一個文件或目錄時,我們的 Ext2 是如何處理的呢? 這個時候就得要 block bitmap 及 inode bitmap 的幫忙了!假設我們想要新增一個文件,此時文件系統的行為是:

1.先確定用戶對於欲新增文件的目錄是否具有 w 與 x 的權限,若有的話才能新增;

2.根據 inode bitmap 找到沒有使用的 inode 號碼,並將新文件的權限/屬性寫入;

3.根據 block bitmap 找到沒有使用中的 block 號碼,並將實際的數據寫入 block 中,且升級 inode 的 block 指向數據;

4.將剛剛寫入的 inode 與 block 數據同步升級 inode bitmap 與 block bitmap,並升級 superblock 的內容。

一般來說,我們將 inode table 與 data block 稱為數據存放區域,至於其他例如 superblock、 block bitmap 與 inode bitmap 等區段就被稱為 metadata (中介數據) 啰,因為 superblock, inode bitmap 及 block bitmap 的數據是經常變動的,每次新增、移除、編輯時都可能會影響到這三個部分的數據,因此才被稱為中介數據的啦。

日志式文件系統 (Journaling filesystem)

為了避免上述提到的文件系統不一致的情況發生,因此我們的前輩們想到一個方式, 如果在我們的 filesystem 當中規劃出一個區塊,該區塊專門在記錄寫入或修訂文件時的步驟, 那不就可以簡化一致性檢查的步驟了?也就是說:

1.預備:當系統要寫入一個文件時,會先在日志記錄區塊中紀錄某個文件准備要寫入的信息;

2.實際寫入:開始寫入文件的權限與數據;開始升級 metadata 的數據;

3.結束:完成數據與 metadata 的升級後,在日志記錄區塊當中完成該文件的紀錄。

在這樣的程序當中,萬一數據的紀錄過程當中發生了問題,那麼我們的系統只要去檢查日志記錄區塊, 就可以知道哪個文件發生了問題,針對該問題來做一致性的檢查即可,而不必針對整塊 filesystem 去檢查, 這樣就可以達到快速修復 filesystem 的能力了!這就是日志式文件最基礎的功能.

Linux 文件系統的運行:

為了解決這個效率的問題,因此我們的 Linux 使用的方式是透過一個稱為異步處理 (asynchronously) 的方式。所謂的異步處理是這樣的:

當系統加載一個文件到內存後,如果該文件沒有被更動過,則在內存區段的文件數據會被配置為干淨(clean)的。 但如果內存中的文件數據被更改過了(例如你用 nano 去編輯過這個文件),此時該內存中的數據會被配置為髒的 (Dirty)。此時所有的動作都還在內存中運行,並沒有寫入到磁盤中! 系統會不定時的將內存中配置為『Dirty』的數據寫回磁盤,以保持磁盤與內存數據的一致性。 你也可以利用第五章談到的 sync命令來手動強迫寫入磁盤。

我們知道內存的速度要比硬盤快的多,因此如果能夠將常用的文件放置到內存當中,這不就會添加系統性能嗎? 沒錯!是有這樣的想法!因此我們 Linux 系統上面文件系統與內存有非常大的關系:

系統會將常用的文件數據放置到主存儲器的緩沖區,以加速文件系統的讀/寫;

承上,因此 Linux 的物理內存最後都會被用光!這是正常的情況!可加速系統效能;

你可以手動使用 sync 來強迫內存中配置為 Dirty 的文件回寫到磁盤中;

若正常關機時,關機命令會主動呼叫 sync 來將內存的數據回寫入磁盤內;

但若不正常關機(如跳電、死機或其他不明原因),由於數據尚未回寫到磁盤內, 因此重新啟動後可能會花很多時間在進行磁盤檢驗,甚至可能導致文件系統的損毀(非磁盤損毀)。

其他 Linux 支持的文件系統與 VFS

雖然 Linux 的標准文件系統是 ext2 ,且還有添加了日志功能的 ext3 ,事實上,Linux 還有支持很多文件系統格式的, 尤其是最近這幾年推出了好幾種速度很快的日志式文件系統,包括 SGI 的 XFS 文件系統, 可以適用更小型文件的 Reiserfs 文件系統,以及 Windows 的 FAT 文件系統等等, 都能夠被 Linux 所支持喔!常見的支持文件系統有:

傳統文件系統:ext2 / minix / MS-DOS / FAT (用 vfat 模塊) / iso9660 (光盤)等等;

日志式文件系統: ext3 / ReiserFS / Windows' NTFS / IBM's JFS / SGI's XFS

網絡文件系統: NFS / SMBFS

了解了我們使用的文件系統之後,再來則是要提到,那麼 Linux 的核心又是如何管理這些認識的文件系統呢? 其實,整個 Linux 的系統都是透過一個名為 Virtual Filesystem Switch 的核心功能去讀取 filesystem 的。 也就是說,整個 Linux 認識的 filesystem 其實都是 VFS 在進行管理,我們使用者並不需要知道每個 partition 上頭的 filesystem 是什麼~ VFS 會主動的幫我們做好讀取的動作呢~

假設你的 / 使用的是 /dev/hda1 ,用 ext3 ,而 /home 使用 /dev/hda2 ,用 reiserfs , 那麼你取用 /home/dmtsai/.bashrc 時,有特別指定要用的什麼文件系統的模塊來讀取嗎? 應該是沒有吧!這個就是 VFS 的功能啦!透過這個 VFS 的功能來管理所有的 filesystem, 省去我們需要自行配置讀取文件系統的定義啊~方便很多!整個 VFS 可以約略用下圖來說明:

Copyright © Linux教程網 All Rights Reserved