理解格式化原理

2022-07-09 20:06:09 字數 3434 閱讀 1299

在前文《磁碟開篇:扒開機械硬碟堅硬的外殼!》和《拆解固態硬碟結構》中,我們了解到了硬碟基本單位是扇區。在《磁碟分割槽也是隱含了技術技巧的》中我們也了解了磁碟分割槽是怎麼回事,但剛分完區的硬碟也是不能直接被被作業系統使用的,必須還得要經過格式化。那麼今天我們就簡單聊一聊,linux下的格式化到底都幹了些啥。

linux下的格式化命令是mkfs,mkfs在格式化的時候需要制定分割槽以及檔案系統型別。該命令其實就是把我們的連續的磁碟空間進行劃分和管理。我在我的機器上執行了一下,輸出如下:

# mkfs -t ext4 /dev/vdb

mke2fs 1.42.9 (28-dec-2013)

檔案系統標籤=

os type: linux

塊大小=4096 (log=2)

分塊大小=4096 (log=2)

stride=0 blocks, stripe width=0 blocks

6553600 inodes, 26214400 blocks

1310720 blocks (5.00%) reserved for the super user

第乙個資料塊=0

maximum filesystem blocks=2174746624

800 block groups

32768 blocks per group, 32768 fragments per group

8192 inodes per group

superblock backups stored on blocks:

32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,

4096000, 7962624, 11239424, 20480000, 23887872

接下來讓我們深入理解一下上面輸出裡攜帶的資訊。

在上面的結果中我們看到了幾個重要資訊

塊大小設定的是4096位元組,我們來分析兩種場景

很明顯,以上這兩種情況下4096位元組的塊大小是不合適的。你需要自己根據情況選擇自己的塊大小進行重新格式化。

我們再看另外的兩個資料,inode數量和block數量。我們用block數量除一下inode,26214400/6553600=4,也就是說平均4個block會有乙個inode。再舉兩個極端的例子:

這些情況下,block和inode的配比也都是不符合你使用的,你需要根據自己的業務重新配置。mkfs傻瓜格式出來的結果無法滿足你的業務需求,你就需要使用另外一些格式化命令了,比如mke2fs,這個命令允許你輸入更詳細的格式化選項,demo如下:

mke2fs -j -l "卷標" -b 2048 -i 8192 /dev/sdb1
800 block groups

32768 blocks per group, 32768 fragments per group

8192 inodes per group

那麼這個groups到底說的是啥呢?其實呀,格式化後的所有inode並不是挨著一起放的,同樣block也不是。而是分成了乙個個的group,每乙個group裡都有一些inode和block。邏輯圖如下:

這個塊組一般是多大呢?注意每個塊中的資料塊點陣圖只有乙個,假如你的塊大小為4kb,這樣乙個bit代表乙個資料塊,4kb可以有32kb個bit,可以管理32k*4k=128m的資料塊。來讓我們實際動手驗證一下,如下:

# dumpe2fs /dev/vdb

......

block size: 4096

inode size: 256

inode count: 6553600

block count: 26214400

......

group 16: (blocks 524288-557055) [inode_uninit, itable_zeroed]

checksum 0xe838, unused inodes 8192

block bitmap at 524288 (+0), inode bitmap at 524304 (+16)

inode表位於 524320-524831 (+32)

24544 free blocks, 8192 free inodes, 0 directories, 8192個未使用的inodes

可用塊數: 532512-557055

可用inode數: 131073-139264

......

group 799: (blocks 26181632-26214399) [inode_uninit, itable_zeroed]

......

上述結果中包含資訊如下:

好了,了解了以上原理以後,讓我們回頭在來看看目錄使用的資料是怎麼在磁碟上組織的。建立目錄的時候,作業系統會在inode點陣圖上尋找尚未使用的inode編號,找到後把inode分配給你。目錄會預設分配乙個block,所以還需要查詢block點陣圖,找到後分配乙個block。在block裡面,儲存的就是檔案系統自己定義的desty結構了,每乙個結構裡會儲存其下的檔名,檔案的inode編號等資訊。某個實際資料夾在磁碟上最終使用的空間如下圖所示:

目錄的block中儲存的是其下面的檔案和子目錄的desty結構體,儲存著它們的檔名和inode號。理解了目錄,對於檔案也是一樣的。也需要消耗inode,當有資料寫入的時候,再去申請block。

硬碟就是乙個扇區組成的大陣列,是無法被我們使用的,需要經過分割槽、格式化和掛載三個步驟。分割槽是把所有的扇區按照柱面分割成不同的大塊,格式化就把原始的扇區陣列變成了可被linux檔案系統使用的inode、block等基本元素了。感覺格式化程式有點像是廚師團隊裡的那個切墩的,把原材料變成了可被廚師直接使用的蔥花,肉段。格式化完後再經過最後一步掛載,對應的命令是mount,然後你就可以在它下面建立和儲存檔案了。

再擴充套件一下其實剛分完區的裝置也是可以使用的,這個時候的分割槽叫裸分割槽,也叫裸裝置。比如oracle就是繞開作業系統直接使用裸裝置的。但是這個時候你就無法利用linux檔案系統裡為你封裝好的inode、block組成的檔案與目錄了,開發工作量會增加。

發現寫文章的過程中最費時的是畫圖,眼睛快瞎了,路過就給個贊把,謝了!

開發內功修煉之硬碟篇**:

格式化漏洞利用原理

在printf 函式正常使用中,printf s printf s s 都能夠輸出s字串的值,但如果在s字串中存在 計算機無法判斷是否為引數,所以可以在printf s 中s填入帶有 的符號,能達到洩漏位址的作用。一般我們想要洩漏棧上多個位址,往往可以採用輸出多個 x來達到。如果想直接獲得某個位址,...

格式化,強調 數值格式化

聚合函式返回的的數值型別的值有個特點就是沒有被格式化。通過前面的帶 sum 聚合函式的示例,我們可以看到這一點 注意合計值 命令,或者在物件檢視器中選中 displayformat 屬性。在上節的示例中,格式化操作是針對一物件或物件內的表示式,在物件內僅有乙個表示式時它還能正常工作,不過當物件內不有...

python 格式化和format格式化

格式 name flags width precision typecode name 可選,用於選擇指定的key flags 可選,可提供的值有 右對齊,整數前加正號,負數前加負號 左對齊,正數錢無符號,負數前加負號 空格 右對齊 正數前加空格,負數前加負號 0 右對齊,正數前無符號,負數前加負號...