1. 程式人生 > >(萊昂氏unix原始碼分析導讀-44) 檔案系統資源

(萊昂氏unix原始碼分析導讀-44) 檔案系統資源

                                                 by cszhao1980

一個裝置被mount進系統後,就被稱為一個檔案系統。它有兩類資源:

(1)         磁碟inode資源;

(2)         普通盤塊資源。

1. 磁碟inode資源

對於inode資源,unix v6採用了一種很簡單的管理方法。即在超級塊中維護一個free inode

資源陣列(max 100 entry),存放可用的inode資源(inode id):

5568:     int s_ninode;     /* number of in core I nodes (0-100) */

5569:     int s_inode[100];  /* in core free I nodes */

5571:     char s_ilock;     /* lock during I list manipulation */                      

當程序請求inode資源時,先檢查free inode陣列,看是否還有空閒項:

(1)         有:直接分配給程序。

(2)         inode項已經耗盡:

先執行一個free inode陣列重建過程——Loop所有的inode盤塊,找到空閒的inode項,

存入free inode陣列;然後再從空閒陣列中分配。

基本上,上面描述的就是inode資源分配函式“ialloc”的分配演算法,唯一需要多注意的

free inode資源陣列重建過程中,對空閒磁碟inode的判斷方法:

(1)         7101行: i_mode0

(2)         7104 ~ 7106行:還需要Loop系統inode表,看該inode是否正在使用。

相應的,unix v6還提供了inode資源釋放函式ifree(dev, ino)——這個函式的實現非常簡單:

(1)         free inode陣列“不滿”時,將要釋放的inode資源放入該陣列;否則,直接return

(2)         而且,遇到檔案系統“上鎖”時,也直接return

,不做任何處理。

——這也難怪,按照前面的描述,ialloc()本身就是“自適應”的函式,根本不需要ifree()配合。

        ifree的存在只是錦上添花而已。

【效能考慮】:

     上述演算法中的free inode陣列的全域性過程會不會成為效能瓶頸?

應該不會:

1)一個盤塊可容納256/16 = 16個磁碟inode項。而一個檔案僅需要一個磁碟inode(1/16)——對

         大多數檔案來說,這遠遠小於檔案內容所佔用的磁碟塊數。因此,通常情況下一個檔案系統中

         只需分配很小部分的盤塊作inode資源。

而我們的模型所配置的RK磁碟,總共才有4800塊盤塊,因此,這個重建過程不會太慢;

2)一次重建可以恢復100個空閒資源——在當時的環境下,重建的次數也不會太頻繁。

2. 盤塊資源

超級塊中用於盤塊資源管理的變數與inode管理的極其相似:

5565:     int s_nfree;      /* number of in core free blocks (0-100) */

5567:     int s_free[100];   /* in core free blocks */

5570:     char s_flock;     /* lock during free list manipulation */

但是,事實上,對於盤塊資源的管理,unix v6採用了完全不同的方式。

所有的空閒盤塊被按照100個一組分為若干組,而每組的第一個盤塊指向下一組——它記錄的內容:

(1)         第一個word是下一組空閒盤塊的個數;

(2)         2~…是下一組空閒盤塊的塊號。

因此,這些空閒盤塊組就形成了一個鏈狀結構,如下所示:

 


超級塊中的free block資源陣列記錄的就是第1組盤塊資訊。

當分配資源時,從s_free數組裡逆序進行分配,當僅剩一個entry時,就讀取該盤塊,獲取下一組空閒盤塊。

當釋放資源時,如果s_free陣列不滿,則直接返回到該陣列內;

否則,利用新釋放的盤塊新建一個空閒組,將s_free陣列所記錄的盤塊號寫入盤塊中——即使

用“頭插法”插入新組。

理解了上述過程,則資源分配和回收函式alloc()free()就顯得比較簡單了。

最後我們看一下itrunc函式,它用來進行回收指定檔案所佔用的盤塊資源,它只有一個引數,即該文

件的inode。呼叫該函式後,檔案佔用的盤塊資源被回收:

(1)         檔案inodei_addr陣列以及i_size0i_size1都被置0

(2)         如果原檔案為大檔案,大檔案標誌也被清除。