Linux上的文件系統一般來說就是EXT2或EXT3,但這篇文章並不准備一上來就直接講它們,而希望結合Linux操作系統並從文件系統建立的基礎——硬碟開始,一步步認識Linux的文件系統。## 1.機械硬碟的物理存儲機制現代電腦大部分文件存儲功能都是由機械硬碟這種設備提供的。(現在的SSD和快閃記憶體從... ...
Linux上的文件系統一般來說就是EXT2或EXT3,但這篇文章並不准備一上來就直接講它們,而希望結合Linux操作系統並從文件系統建立的基礎——硬碟開始,一步步認識Linux的文件系統。
1.機械硬碟的物理存儲機制
現代電腦大部分文件存儲功能都是由機械硬碟這種設備提供的。(現在的SSD和快閃記憶體從概念和邏輯上都部分繼承自機械硬碟,所以使用機械硬碟來進行理解也是沒有問題的)
機械硬碟能實現信息存儲的功能基於:磁性存儲介質能夠被磁化,且磁化後會長久保留被磁化的狀態,這種被磁化狀態能夠被讀取出來,同時這種磁化狀態還能夠不斷被修改,磁化正好有兩個方向,所以可以表示0和1。
於是硬碟就是把這種磁性存儲介質做成一個個碟片,每一個碟片上都分佈著數量巨大的磁性存儲單位,使用磁性讀寫頭對碟片進行寫入和讀取(從原理上類似黑膠唱片的播放)。
一個硬碟中的磁性存儲單位數以億計(1T硬碟就有約80億個),所以需要一套規則來規劃信息如何存取(比如一本存儲信息的書我們還會分為頁,每一頁從上到下從左到右讀取,同時還有章節目錄)
於是就有了這些物理、邏輯概念:
- 一個硬碟有多張碟片疊成,不同碟片有編號
- 每張碟片上的存儲顆粒成環形一圈圈地排布,每一圈稱為磁軌,有編號
- 每條磁軌上都有一圈存儲顆粒,每512*8(512位元組,0.5KB)個存儲顆粒作為一個扇區,扇區是硬碟上存儲的最小物理單位
- N個扇區可以組成簇,N取決於不同的文件系統或是文件系統的配置,簇是此文件系統中的最小存儲單位
- 所有盤面上的同一磁軌構成一個圓柱,稱為柱面,柱面是系統分區的最小單位

磁頭讀寫文件的時候,首先是分區讀寫的,由inode編號(區內唯一的編號後面介紹)找到對應的磁軌和扇區,然後一個柱面一個柱面地進行讀寫。機械硬碟的讀寫控制系統是一個令人嘆為觀止的精密工程(一個盤面上有幾億個存儲單位,每個磁軌寬度不到幾十納米,磁碟每分鐘上萬轉),同時關於讀寫的邏輯也是有諸多細節(比如扇區的編號並不是連續的),非常有意思,可以自行搜索文章拓展閱讀。
有了硬碟並不意味著LInux可以立刻把它用來存儲,還需要組合進Linux的文件體系才能被Linux使用。
2.Linux文件體系
Linux以文件的形式對電腦中的數據和硬體資源進行管理,也就是徹底的一切皆文件,反映在Linux的文件類型上就是:普通文件、目錄文件(也就是文件夾)、設備文件、鏈接文件、管道文件、套接字文件(數據通信的介面)等等。而這些種類繁多的文件被Linux使用目錄樹進行管理, 所謂的目錄樹就是以根目錄(/)為主,向下呈現分支狀的一種文件結構。不同於純粹的ext2之類的文件系統,我把它稱為文件體系,一切皆文件和文件目錄樹的資源管理方式一起構成了Linux的文件體系,讓Linux操作系統可以方便使用系統資源。
所以文件系統比文件體系涵蓋的內容少很多,Linux文件體系主要在於把操作系統相關的東西用文件這個載體實現:文件系統掛載在操作系統上,操作系統整個系統又放在文件系統里。但本文中文件體系的相關內容不是很多,大部分地方都可以用文件系統代替文件體系。
Linux中的文件類型
那就先簡單說說Linux中的文件類型,主要關註普通文件、目錄文件和符號連接文件。
- 普通文件(-)
- 從Linux的角度來說,類似mp4、pdf、html這樣應用層面上的文件類型都屬於普通文件
- Linux用戶可以根據訪問許可權對普通文件進行查看、更改和刪除
- 目錄文件(d,directory file)
- 目錄文件對於用慣Windows的用戶來說不太容易理解,目錄也是文件的一種
- 目錄文件包含了各自目錄下的文件名和指向這些文件的指針,打開目錄事實上就是打開目錄文件,只要有訪問許可權,你就可以隨意訪問這些目錄下的文件(普通文件的執行許可權就是目錄文件的訪問許可權),但是只有內核的進程能夠修改它們
- 雖然不能修改,但是我們能夠通過vim去查看目錄文件的內容
- 符號鏈接(l,symbolic link)
- 這種類型的文件類似Windows中的快捷方式,是指向另一個文件的間接指針,也就是我們常說的軟鏈接
- 塊設備文件(b,block)和字元設備文件(c,char)
- 這些文件一般隱藏在/dev目錄下,在進行設備讀取和外設交互時會被使用到
- 比如磁碟光碟機就是塊設備文件,串口設備則屬於字元設備文件
- 系統中的所有設備要麼是塊設備文件,要麼是字元設備文件,無一例外
- FIFO(p,pipe)
- 管道文件主要用於進程間通訊。比如使用mkfifo命令可以創建一個FIFO文件,啟用一個進程A從FIFO文件里讀數據,啟動進程B往FIFO里寫數據,先進先出,隨寫隨讀。
- 套接字(s,socket)
- 用於進程間的網路通信,也可以用於本機之間的非網路通信
- 這些文件一般隱藏在/var/run目錄下,證明著相關進程的存在
Linux 的文件是沒有所謂的擴展名的,一個 Linux文件能不能被執行與它是否可執行的屬性有關,只要你的許可權中有 x ,比如[ -rwx-r-xr-x ] 就代表這個文件可以被執行,與文件名沒有關係。跟在 Windows下能被執行的文件擴展名通常是 .com .exe .bat 等不同。
不過,可以被執行跟可以執行成功不一樣。比如在 root 主目彔下的 install.log 是一個文本文件,修改許可權成為 -rwxrwxrwx 後這個文件能夠真的執行成功嗎? 當然不行,因為它的內容根本就沒有可以執行的數據。所以說,這個 x 代表這個文件具有可執行的能力, 但是能不能執行成功,當然就得要看該文件的內容了。
雖然如此,不過我們仍然希望能從擴展名來瞭解該文件是什麼東西,所以一般我們還是會以適當的擴展名來表示該文件是什麼種類的。
所以Linux 系統上的文件名真的只是讓你瞭解該文件可能的用途而已, 真正的執行與否仍然需要許可權的規範才行。比如常見的/bin/ls 這個顯示文件屬性的指令要是許可權被修改為無法執行,那麼ls 就變成不能執行了。這種問題最常發生在文件傳送的過程中。例如你在網路上下載一個可執行文件,但是偏偏在你的 Linux 系統中就是無法執行,那就可能是檔案的屬性被改變了。而且從網路上傳送到你 的 Linux 系統中,文件的屬性許可權確實是會被改變的
Linux目錄樹
對Linux系統和用戶來說,所有可操作的電腦資源都存在於目錄樹這個邏輯結構中,對電腦資源的訪問都可以認為是目錄樹的訪問。就硬碟來說,所有對硬碟的訪問都變成了對目錄樹中某個節點也就是文件夾的訪問,訪問時不需要知道它是硬碟還是硬碟中的文件夾。
目錄樹的邏輯結構也非常簡單,就是從根目錄(/)開始,不斷向下展開各級子目錄。
3.硬碟分區
硬碟分區是硬碟結合到文件體系的第一步,本質是「硬碟」這個物理概念轉換成「區」這個邏輯概念,為下一步格式化做準備。
所以分本身並不是必須的,你完全可以把一整塊硬碟作為一個區。但從數據的安全性以及系統性能角度來看,分區還是有很多用處的,所以一般都會對硬碟進行分區。
講分區就不得不先提每塊硬碟上最重要的第一扇區,這個扇區中有硬碟主引導記錄(Master boot record, MBR) 及分區表(partition table), 其中 MBR 占有 446 bytes,而分區表占有 64 bytes。硬碟主引導記錄放有最基本的引導載入程式,是系統開機啟動的關鍵環節,在附錄中有更詳細的說明。而分區表則跟分區有關,它記錄了硬碟分區的相關信息,但因分區表僅有 64bytes , 所以最多只能記彔四塊分區(分區本身其實就是對分區表進行設置)。
只能分四個區實在太少了,於是就有了擴展分區的概念,既然第一個扇區所在的分區表只能記錄四條數據, 那我可否利用額外的扇區來記錄更多的分區信息。
把普通可以訪問的分區稱為主分區,擴展分區不同於主分區,它本身並沒有內容,它是為進一步邏輯分區提供空間的。在某塊分區指定為擴展分區後,就可以對這塊擴展分區進一步分成多個邏輯分區。操作系統規定:
- 四塊分區每塊都可以是主分區或擴展分區
- 擴展分區最多只能有一個(也沒必要有多個)
- 擴展分區可以進一步分割為多個邏輯分區
- 擴展分區只是邏輯概念,本身不能被訪問,也就是不能被格式化後作為數據訪問的分區,能夠作為數據訪問的分區只有主分區和邏輯分區
- 邏輯分區的數量依操作系統而不同,在 Linux 系統中,IDE 硬碟最多有 59 個邏輯分區(5 號到 63 號), SATA 硬碟則有 11 個邏輯分區(5 號到 15 號)
一般給硬碟進行分區時,一個主分區一個擴展分區,然後把擴展分區劃分為N個邏輯分區是最好的
- 是否可以不要主分區呢?不知道,但好像不用管,你創建分區的時候會自動給你配置類型
- 特殊的,你最好單獨分一個swap區(記憶體置換空間),它獨為一類,功能是:當有數據被存放在物理記憶體裡面,但是這些數據又不是常被 CPU 所取用時,那麼這些不常被使用的程式將會被丟到硬碟的 swap 置換空間當中, 而將速度較快的物理記憶體空間釋放出來給真正需要的程式使用
4.格式化
我們知道Linux操作系統支持很多不同的文件系統,比如ext2、ext3、XFS、FAT等等,而Linux把對不同文件系統的訪問交給了VFS(虛擬文件系統),VFS能訪問和管理各種不同的文件系統。所以有了區之後就需要把它格式化成具體的文件系統以便VFS訪問。
標準的Linux文件系統Ext2是使用「基於inode的文件系統」
- 我們知道一般操作系統的文件數據除了文件實際內容外, 還帶有很多屬性,例如 Linux 操作系統的文件許可權(rwx)與文件屬性(擁有者、群組、 時間參數等),文件系統通常會將屬性和實際內容這兩部分數據分別存放在不同的區塊
- 在基於inode的文件系統中,許可權與屬性放置到 inode 中,實際數據放到 data block 區塊中,而且inode和data block都有編號
Ext2 文件系統在此基礎上
- 文件系統最前面有一個啟動扇區(boot sector)
- 這個啟動扇區可以安裝開機管理程式, 這個設計讓我們能將不同的引導裝載程式安裝到個別的文件系統前端,而不用覆蓋整個硬碟唯一的MBR, 也就是這樣才能實現多重引導的功能
- 把每個區進一步分為多個塊組 (block group),每個塊組有獨立的inode/block體系
- 如果文件系統高達數百 GB 時,把所有的 inode 和block 通通放在一起會因為 inode 和 block的數量太龐大,不容易管理
- 這其實很好理解,因為分區是用戶的分區,實際電腦管理時還有個最適合的大小,於是電腦會進一步的在分區中分塊
- (但這樣豈不是可能出現大文件放不了的問題?有什麼機制善後嗎?)
- 每個塊組實際還會分為分為6個部分,除了inode table 和 data block外還有4個附屬模塊,起到優化和完善系統性能的作用
所以整個分區大概會這樣劃分:

inode table
- 主要記錄文件的屬性以及該文件實際數據是放置在哪些block中,它記錄的信息至少有這些:
- 大小、真正內容的block號碼(一個或多個)
- 訪問模式(read/write/excute)
- 擁有者與群組(owner/group)
- 各種時間:建立或狀態改變的時間、最近一次的讀取時間、最近修改的時間
- 沒有文件名!文件名在目錄的block中!
- 一個文件占用一個 inode,每個inode有編號
- Linux 系統存在 inode 號被用完但磁碟空間還有剩餘的情況
- 註意,這裡的文件不單單是普通文件,目錄文件也就是文件夾其實也是一個文件,還有其他的也是
- inode 的數量與大小在格式化時就已經固定了,每個inode 大小均固定為128 bytes (新的ext4 與xfs 可設定到256 bytes)
- 文件系統能夠建立的文件數量與inode 的數量有關,存在空間還夠但inode不夠的情況
- 系統讀取文件時需要先找到inode,並分析inode 所記錄的許可權與使用者是否符合,若符合才能夠開始實際讀取 block 的內容
- inode 要記錄的資料非常多,但偏偏又只有128bytes , 而inode 記錄一個block 號碼要花掉4byte ,假設我一個文件有400MB 且每個block 為4K 時, 那麼至少也要十萬條block 號碼的記錄!inode 哪有這麼多空間來存儲?為此我們的系統很聰明的將inode 記錄block 號碼的區域定義為12個直接,一個間接, 一個雙間接與一個三間接記錄區(詳細見附錄)
data block
- 放置文件內容數據的地方
- 在格式化時block的大小就固定了,且每個block都有編號,以方便inode的記錄
- 原則上,block 的大小與數量在格式化完就不能夠再改變了(除非重新格式化)
- 在Ext2文件系統中所支持的block大小有1K, 2K及4K三種,由於block大小的區別,會導致該文件系統能夠支持的最大磁碟容量與最大單一文件容量各不相同:
- Block 大小 1KB 2KB 4KB
- 最大單一檔案限制 16GB 256GB 2TB
- 最大檔案系統總容量 2TB 8TB 16TB
- 每個block 內最多只能夠放置一個文件的資料,但一個文件可以放在多個block中(大的話)
- 若文件小於block ,則該block 的剩餘容量就不能夠再被使用了(磁碟空間會浪費)
- 所以如果你的檔案都非常小,但是你的block 在格式化時卻選用最大的4K 時,可能會產生容量的浪費
- 既然大的block 可能會產生較嚴重的磁碟容量浪費,那麼我們是否就將block 大小定為1K ?這也不妥,因為如果block 較小的話,那麼大型檔案將會占用數量更多的block ,而inode 也要記錄更多的block 號碼,此時將可能導致檔案系統不良的讀寫效能
- 事實上現在的磁碟容量都太大了,所以一般都會選擇4K 的block 大小
superblock
- 記錄整個文件系統相關信息的地方,一般大小為1024bytes,記錄的信息主要有:
- block 與inode 的總量
- 未使用與已使用的inode / block 數量
- 一個valid bit 數值,若此文件系統已被掛載,則valid bit 為0 ,若未被掛載,則valid bit 為1
- block 與inode 的大小 (block 為1, 2, 4K,inode 為128bytes 或256bytes);
- 其他各種文件系統相關信息:filesystem 的掛載時間、最近一次寫入資料的時間、最近一次檢驗磁碟(fsck) 的時間
- Superblock是非常重要的, 沒有Superblock ,就沒有這個文件系統了,因此如果superblock死掉了,你的文件系統可能就需要花費很多時間去輓救
- 每個塊都可能含有superblock,但是我們也說一個文件系統應該僅有一個superblock 而已,那是怎麼回事?事實上除了第一個塊內會含有superblock 之外,後續的塊不一定含有superblock,而若含有superblock則該superblock主要是做為第一個塊內superblock的備份,這樣可以進行superblock的救援
Filesystem Description
- 文件系統描述
- 這個區段可以描述每個block group的開始與結束的block號碼,以及說明每個區段(superblock, bitmap, inodemap, data block)分別介於哪一個block號碼之間
block bitmap
- 塊對照表
- 如果你想要新增文件時要使用哪個block 來記錄呢?當然是選擇「空的block」來記錄。那你怎麼知道哪個block 是空的?這就得要通過block bitmap了,它會記錄哪些block是空的,因此我們的系統就能夠很快速的找到可使用的空間來記錄
- 同樣在你刪除某些文件時,那些文件原本占用的block號碼就得要釋放出來, 此時在block bitmap 中對應該block號碼的標誌位就得要修改成為「未使用中」
inode bitmap
- 與block bitmap 是類似的功能,只是block bitmap 記錄的是使用與未使用的block 號碼, 至於inode bitmap 則是記錄使用與未使用的inode 號碼
5.掛載
在一個區被格式化為一個文件系統之後,它就可以被Linux操作系統使用了,只是這個時候Linux操作系統還找不到它,所以我們還需要把這個文件系統「註冊」進Linux操作系統的文件體系裡,這個操作就叫「掛載」 (mount)。
掛載是利用一個目錄當成進入點(類似選一個現成的目錄作為代理),將文件系統放置在該目錄下,也就是說,進入該目錄就可以讀取該文件系統的內容,類似整個文件系統只是目錄樹的一個文件夾(目錄)。
這個進入點的目錄我們稱為「掛載點」。
由於整個 Linux 系統最重要的是根目錄,因此根目錄一定需要掛載到某個分區。 而其他的目錄則可依用戶自己的需求來給予掛載到不同的分去。
到這裡Linux的文件體系的構建過程其實已經大體講完了,總結一下就是:硬碟經過分區和格式化,每個區都成為了一個文件系統,掛載這個文件系統後就可以讓Linux操作系統通過VFS訪問硬碟時跟訪問一個普通文件夾一樣。這裡通過一個在目錄樹中讀取文件的實際例子來細講一下目錄文件和普通文件。
6.目錄樹的讀取過程
首先我們要知道
- 每個文件(不管是一般文件還是目錄文件)都會占用一個inode
- 依據文件內容的大小來分配一個或多個block給該文件使用
- 創建一個文件後,文件完整信息分佈在3處地方,生成2個新文件:
- 文件名記錄在該文件所在目錄的目錄文件的block中,沒有新文件生成
- 文件屬性、許可權信息、記錄具體內容的block編號記錄在inode中,inode是新生成文件
- 文件具體記憶體記錄在block中,block是新生成文件
- 因為文件名的記錄是在目錄的block當中,「新增/刪除/更名文件名」與目錄的w許可權有關
所以在Linux/Unix中,文件名稱只是文件的一個屬性,叫別名也好,叫綽號也罷,僅為了方便用戶記憶和使用,但系統內部並不需要用文件名來定為文件位置,這樣處理最直觀的好處就是,你可以對正在使用的文件改名,換目錄,甚至放到廢紙簍,都不會影響當前文件的使用,這在Windows里是無法想象的。比如你打開個Word文件,然後對其進行重命名操作,Windows會告訴你門兒都沒有,關閉文件先!但在Mac里就毫無壓力,因為Mac的操作系統同樣採用了inode的設計。
創建文件過程
當在ext2下建立一個一般文件時, ext2 會分配一個inode 與相對於該文件大小的block 數量給該文件
- 例如:假設我的一個block 為4 Kbytes ,而我要建立一個100 KBytes 的文件,那麼linux 將分配一個inode 與25 個block 來儲存該文件
- 但同時請註意,由於inode 僅有12 個直接指向,因此還要多一個block 來作為區塊號碼的記錄
創建目錄過程
當在ext2文件系統建立一個目錄時(就是新建了一個目錄文件),文件系統會分配一個inode與至少一塊block給該目錄
- inode記錄該目錄的相關許可權與屬性,並記錄分配到的那塊block號碼
- 而block則是記錄在這個目錄下的文件名與該文件對應的inode號
- block中還會自動生成兩條記錄,一條是.文件夾記錄,inode指向自身,另一條是..文件夾記錄,inode指向父文件夾
從目錄樹中讀取某個文件過程
- 因為文件名是記錄在目錄的block當中,因此當我們要讀取某個文件時,就一定會經過目錄的inode與block ,然後才能夠找到那個待讀取文件的inode號碼,最終才會讀到正確的文件的block內的資料。
- 由於目錄樹是由根目錄開始,因此操作系統先通過掛載信息找到掛載點的inode號,由此得到根目錄的inode內容,並依據該inode讀取根目錄的block信息,再一層一層的往下讀到正確的文件。
舉例來說,如果我想要讀取/etc/passwd 這個文件時,系統是如何讀取的呢?
先看一下這個文件以及有關路徑文件夾的信息:
$ ll -di / /etc /etc/passwd
128 dr-xr-x r-x . 17 root root 4096 May 4 17:56 /
33595521 drwxr-x r-x . 131 root root 8192 Jun 17 00:20 /etc
36628004 -rw-r-- r-- . 1 root root 2092 Jun 17 00:20 /etc/passwd
於是該文件的讀取流程為:
- /的inode:
- 通過掛載點的信息找到inode號碼為128的根目錄inode,且inode規定的許可權讓我們可以讀取該block的內容(有r與x)
- /的block:
- 經過上個步驟取得block的號碼,並找到該內容有etc/目錄的inode號碼(33595521)
- etc/的inode:
- 讀取33595521號inode得知具有r與x的許可權,因此可以讀取etc/的block內容
- etc/的block:
- 經過上個步驟取得block號碼,並找到該內容有passwd文件的inode號碼(36628004)
- passwd的inode:
- 讀取36628004號inode得知具有r的許可權,因此可以讀取passwd的block內容
- passwd的block:
- 最後將該block內容的資料讀出來
附錄:
開機流程和硬碟主引導記錄
可以稍微講下開機流程和硬碟主引導記錄(MBR,或者叫主引導分區)
一臺可正常運行的電腦會在BIOS上設置一塊啟動硬碟,其實每塊硬碟都可以作為啟動盤,硬碟本身的設計提供的這種可能,這就要從硬碟上的第一個扇區說起,這個扇區中有硬碟主引導記錄(Master boot record, MBR)及分區表(partition table), 其中 MBR 占有 446 bytes,而分區表則占有 64 bytes。
電腦主板上有一段寫入到主板的程式BIOS,BIOS是開機之後電腦系統會主動執行的第一個程式。BIOS 會去分析電腦裡面有哪些儲存設備,我們以硬碟為例,BIOS 會依據使用者的設定去取得能夠開機的硬碟, 並且到該硬碟裡面去讀取第一個扇區的MBR位置。
MBR 這個僅有 446 bytes 的硬碟容量裡面會放置最基本的引導載入程式(Boot loader),它的目的是載入操作系統內核文件,由於引導載入程式是操作系統在安裝的時候所提供的,所以它會認識硬碟內的文件系統格式,因此就能夠讀取操作系統內核文件。接下來就是內核文件的工作,也就是大家所知道癿操作系統的任務了。
所以簡單說開機流程就是:
- BIOS:開機主動運行的程式,會識別第一個可開機的設備
- MBR-引導載入程式:第一個可開機設備的第一個扇區內的主引導分區中的引導載入程式,可讀取操作系統內核文件
- 操作系統內核文件:不同的操作系統中關於開啟自己的程式
由上面的說明我們會知道,BIOS和MBR 都是硬體本身會支持的功能,到MBR中的Boot loader 則是操作系統寫在 MBR 上面的一段程式了。由於 MBR 僅有 446 bytes,因此這個引導載入程式是非常小而美的,它的主要任務有:
- 提供菜單:用戶可以選擇不同的開機項目,這也是多重引導的重要功能
- 載入操作系統內核:直接指向可開機的程式區段來啟動操作系統
- 轉交其他 loader:將引導載入功能轉交給其他 loader 負責
- 這點很有趣,表示你的電腦系統裡面可能具有兩個以上的引導載入程式
- 有可能嗎?我們的硬碟不是只有一個 MBR 而已?是這樣,但是引導載入程式除了可以安 裝在 MBR 之外, 還可以安裝在每個分區的引導扇區(boot sector)內
- 分區的引導扇區這個特色造就了『多重引導』的功能
- (具體可以看鳥哥的書第三章第四節)
機械硬碟物理存儲結構拓展閱讀
- 蔣致誠. 硬碟驅動器巨磁電阻 (GMR) 磁頭: 從微米到納米[J]. 物理, 2004, 33(07): 0-0.
- 近年來電腦硬碟存儲密度的飛速增長最關鍵的因素是自旋閥納米多層膜結構,即巨磁電阻(GMR)讀感測器磁頭的應用。巨磁電阻磁頭讀感測器已經實現由微電子器件向納米電子器件轉化,這一過程包含了自旋電子學、材料科學、微電子工程學、化學、微機械力學和工程學等諸學科和相關微加工技術綜合性挑戰極限。
- 磁碟工作原理揭秘 http://www.dostor.com/article/2012-09-07/1712853.shtml
- 大多數永久性或半永久性電腦數據都是將磁碟上的一小片金屬物質磁化來實現。然後再將這些磁性圖可被轉換成原始數據。
- 機械硬碟內部硬體結構和工作原理詳解 http://blog.csdn.net/coslay/article/details/42215409
- 給扇區編號的最簡單方法是l,2,3,4,5,6等順序編號。如果扇區按順序繞著磁軌依次編號,那麼,控制器在處理一個扇區的數據期間,磁碟旋轉太遠,超過扇區間的間隔(這個間隔很小),控制器要讀出或寫入的下一扇區已經通過磁頭,也許是相當大的一段距離。在這種情況下,磁碟控制器就只能等待磁碟再次旋轉幾乎一周,才能使得需要的扇區到達磁頭下麵。這就很浪費時間了。許多年前,IBM的一位傑出工程師想出了一個絕妙的辦法,即對扇區不使用順序編號,而是使用一個交叉因數(interleave)進行編號。
格式化的其他細節
- 每種操作系統能夠使用的文件系統並不相同。舉例來說,windows 98 以前的微 軟操作系統主要利用的文件系統是 FAT (或 FAT16),windows 2000 以後的版本有所謂的 NTFS 文件系統,至於 Linux 的正統文件系統則為Ext2 (Linux second extended file system, ext2fs) 這一個。而且在預設的情況下,windows 操作系統是不會認識 Linux的Ext2的。
- 傳統的磁碟與文件系統的應用中,一個分區只能夠被格式化成為一個文件系統,所以我們可以說 一個 文件系統 就是一個分區。但是由於新技術的利用,例如我們常聽到的 LVM 與軟體磁碟陣列(software raid), 這些技術可以將一個分區格式化為多個文件系統,也能夠將多個分區合成一個文件系統,所以說,目前我們在格式化時已經不再說成針對分區來格式化了, 通常我們可以稱呼一個可被掛載的數據為一個文件系統而不是一個分區。
inode/block 與文件大小的關係(有趣)
我們簡單分析一下EXT2 的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來記錄號碼。如上圖中間接只是拿一個block來記錄額外的號碼而已。同理,如果文件持續長大,那麼就會利用所謂的雙間接,第一個block僅再指出下一個記錄號碼的block在哪裡,實際記錄的在第二個block當中。依此類推,三間接就是利用第三層block來記錄號碼啦!
這樣子inode 能夠指定多少個block 呢?我們以較小的1K block 來說明好了,可以指定的情況如下:
- 12個直接指向: 12*1K=12K
- 由於是直接指向,所以總共可記錄12筆記錄,因此總額大小為如上所示
- 間接: 256*1K=256K
- 每筆block號碼的記錄會花去4bytes,因此1K的大小能夠記錄256筆記錄,因此一個間接可以記錄的文件大小如上;
- 雙間接: 2562561K=256 2 K
- 第一層block會指定256個第二層,每個第二層可以指定256個號碼,因此總額大小如上;
- 三間接: 256256256*1K=256 3 K
- 第一層block會指定256個第二層,每個第二層可以指定256個第三層,每個第三層可以指定256個號碼,因此總額大小如上;
- 總額:將直接、間接、雙間接、三間接加總,得到12 + 256 + 256256 + 256256*256 (K) = 16GB
- 此時我們知道當文件系統將block格式化為1K大小時,能夠容納的最大文件為16GB,比較一下文件系統限製表的結果可發現是一致的!
- 但這個方法不能用在2K及4K block大小的計算中,因為大於2K的block將會受到Ext2文件系統本身的限制,所以計算的結果會不太符合
文件系統大小與磁碟讀取性能
關於文件系統的使用效率,當你的一個文件系統規劃的很大時,例如100GB這麼大時,由於磁碟上的資料總是來來去去的,所以,整個文件系統上面的文件通常無法連續寫在一起(block號碼不連續),而是填入式的將資料填入沒有被使用的block當中。如果文件寫入的block真的分的很散,此時就會有所謂的文件資料離散的問題發生了。
如前所述,雖然我們的ext2 在inode 處已經將該文件所記錄的block 號碼都記上了, 所以資料可以一次性讀取,但是如果文件真的太過離散,確實還是會發生讀取效率低的問題。因為磁碟讀取頭還是得要在整個文件系統中來來去去的頻繁讀取!果真如此,那麼可以將整個文件系統內的資料全部複製出來,將該文件系統重新格式化, 再將資料給他複製回去即可解決這個問題。
此外,如果文件系統真的太大了,那麼當一個文件分別記錄在這個文件系統的最前面與最後面的block 號碼中, 此時會造成磁碟的機械手臂移動幅度過大(不是還會分塊嗎?),也會造成資料讀取效能的低落。而且讀取頭在搜尋整個文件系統時, 也會花費比較多的時間去搜尋。因此分區的規劃並不是越大越好, 而是真的要針對你的主機用途來進行規劃才行。
Linux的一切皆文件
Linux 中的各種事物比如像文檔、目錄(Mac OS X 和 Windows 系統下稱之為文件夾)、鍵盤、監視器、硬碟、可移動媒體設備、印表機、數據機、虛擬終端,還有進程間通信(IPC)和網路通信等輸入/輸出資源都是定義在文件系統空間下的位元組流。
一切都可看作是文件,其最顯著的好處是對於上面所列出的輸入/輸出資源,只需要相同的一套 Linux 工具、實用程式和 API。你可以使用同一套api(read, write)和工具(cat , 重定向, 管道)來處理unix中大多數的資源.
設計一個系統的終極目標往往就是要找到原子操作,一旦鎖定了原子操作,設計工作就會變得簡單而有序。“文件”作為一個抽象概念,其原子操作非常簡單,只有讀和寫,這無疑是一個非常好的模型。通過這個模型,API的設計可以化繁為簡,用戶可以使用通用的方式去訪問任何資源,自有相應的中間件做好對底層的適配。
現代操作系統為解決信息能獨立於進程之外被長期存儲引入了文件,文件作為進程創建信息的邏輯單元可被多個進程併發使用。在 UNIX 系統中,操作系統為磁碟上的文本與圖像、滑鼠與鍵盤等輸入設備及網路交互等 I/O 操作設計了一組通用 API,使他們被處理時均可統一使用位元組流方式。換言之,UNIX 系統中除進程之外的一切皆是文件,而 Linux 保持了這一特性。為了便於文件的管理,Linux 還引入了目錄(有時亦被稱為文件夾)這一概念。目錄使文件可被分類管理,且目錄的引入使 Linux 的文件系統形成一個層級結構的目錄樹。