linux 0 11 檔案系統(二)

2022-02-11 13:50:54 字數 3000 閱讀 6109

超級塊描述了整個檔案系統的資訊,而檔案作為儲存的物件,它的資訊是有inode節點來描述的。i節點位圖描述了inode的使用情況。

struct m_inode

其 中i_zone[9]很重要,它指出了檔案使用的裝置的邏輯塊號。其中0-6為直接塊,也就是檔案的資料直接在相應的邏輯塊上;7位1級塊,1級塊可以包 含512個邏輯塊號;8位2級塊,它可以存放512個1級塊。所以檔案長度在7k以內只使用前7個位指定邏輯塊,再大就要使用間接塊指定了。

對i節點位圖以及i節點的操作有new_inode,free_inode,iget,iput,bmp,以及namei.輔助的函式有get_empty_inode,read_inode,write_inode.核心維護了乙個inode節點陣列:

struct m_inode inode_table[nr_inode]=,};

new_inode(int dev)從inode_table中獲取乙個空閒的inode節點項,然後相應裝置超級塊中的i節點點陣圖中的第乙個0bit,接著設定inode節點信 息,並置引用為1。free_inode則相反,進行一系列測試後,它清除點陣圖的相應位元為,並清空inode節點占用的記憶體。

對 邏輯塊點陣圖的操作有new_block和free_block,前者獲取乙個空閒緩衝塊並置位相應位元位,後者相反。以上都是對記憶體中的inode陣列以 及緩衝區中的點陣圖進行操作,而最終要落實到裝置特定的塊上。read_inode是從裝置上讀取指定i節點的資訊到記憶體中,write_inode是寫入 指定i節點到裝置。後者是將inode寫到相應緩衝塊中,並置位

b_dirt。這裡涉及到計算指定的inode節點在裝置上的邏輯塊號:

//啟動塊+超級塊+i節點位圖塊數+邏輯塊位圖塊數+(i節點號-1)/每塊含有的i節點

block=1+1+sb->s_imap_blocks+sb->s_zmap_blocks+(inode->s_inum)/inodes_per_block;

iget 函式是從裝置上讀取指定的i節點。如同getblk,考慮到同步問題也是個反覆的過程。它首先從i節點表中申請乙個空閒i節點。然後搜尋i節點表,看是否 有指定的i節點,如果沒有就用read_inode從裝置中讀取到空閒節點就可返回。如果有則等待它解鎖。等待過程中如果節點表發生變化那麼要重新搜尋。 若該i節點是某個檔案系統的安裝點,則讀取相應檔案系統的超級塊並設定節點號為該檔案系統的第乙個inode,然後重新開始。

iput是回寫到設 備,這裡根據檔案的型別有幾種不同的處理方法。如果檔案是管道檔案,則喚醒管道上等待的程序,並釋放管道頁面。管道的物理記憶體位址在inode-> i_size欄位。如果檔案是塊裝置,那麼重新整理裝置。inode->i_zone[0]中存放的是裝置號。如果鏈結數為0,則釋放i節點所有的邏輯 塊,並釋放該節點。

還有乙個比較重要的函式是 _bmp,它是將檔案資料塊對映到盤塊。在前面講過的do_no_page中用到過,計算出缺頁的記憶體位址在程式所佔的塊號後,通過bmp對映到裝置上的塊號,並讀取被交換到塊裝置上的頁面。

下面具體講解一下:

//inode:檔案的節點,block:檔案中的塊號;create:建立標誌。

static int _bmp(struct m_inode *inode,int block,int create)

return inode->i_zone[block];

}//否則就看是不是在間接塊中

block-=7;

if(block<512)

if(!inode->_zone[7])

return 0;

//讀取裝置上的一次間接塊

if(!(bh=bread(inode->i_dev,inode->i_zone[7])))

return 0;

//取間接塊第block上的邏輯塊號

i=((unsigned short*)(bh->b_data))[block];

if(create&&!i)

if(i=new_block(inode->i_dev))

brelse(bh);

return i;

}//到此,表明資料塊是在二次間接塊上,如上所述處理之

block-=512;

if(create&&!inode->i_zone[8])

if(inode->i_zone[8]=new_block[inode->i_dev])

if(!inode->i_zone[8])

return 0;

//讀取該二次間接塊的一級塊

if(!(bh=bread(inode->i_dev,inode->i_zone[8])))

return 0;

i=((unsigned short*)bh->b_data)[block>>9];

if(create&&!i)

if(i=new_block(inode->i_dev)

brelse(bh);

if(!i)

return 0;

//讀取二次間接塊的二級塊

if(!(bh=bread(inode->i_dev,i))

return 0;

//取二級塊上的block項的邏輯號

i=((unsigned short*)bh->b_data)[block&&511];

if(create&&!i)

if(i=new_block(inode->i_dev))

brelse(bh);

return i;

}bmp是create=0的_bmp,僅取檔案中的資料塊號在緩衝區的對應塊號,而create_block則是create=1的_bmp,它建立對應的裝置邏輯塊的緩衝塊。

到 目前為止,應該對超級塊,i節點,邏輯塊,緩衝塊有了一定的認識了。裝置上的物理部分都有記憶體的表示,比如超級塊在記憶體中有超級塊陣列 super_block[nr_super],i節點和邏輯塊點陣圖有s_imap[8]和s_zmap[8]指向的緩衝區表示,i節點在記憶體中有i節點數 組inode_table[nr_inode],邏輯塊有緩衝區中的緩衝塊。分配inode和邏輯塊只需要分配記憶體中保留的空閒塊,並設定對應點陣圖和修改 位,核心會在適當時間重新整理到裝置上。

原文**:

linux 0 11 檔案系統(二)

超級塊描述了整個檔案系統的資訊,而檔案作為儲存的物件,它的資訊是有inode節點來描述的。i節點位圖描述了inode的使用情況。struct m inode 其 中i zone 9 很重要,它指出了檔案使用的裝置的邏輯塊號。其中0 6為直接塊,也就是檔案的資料直接在相應的邏輯塊上 7位1級塊,1級塊...

Linux 0 11 檔案系統

每乙個程序都有乙個flip存放著乙個索引,該索引就是核心檔案表的索引,而檔案表中的項又指向記憶體i結點表中的一項,這樣程序就要以操作乙個檔案了。null for i 0 is zmap null block 2 for i 0 is imap blocks i if s s imap bread d...

Linux 0 11 系統呼叫學習

通過增加乙個系統呼叫來了解系統呼叫的實現原理。增加 int fun void 1 在include unistd.h 中加入 define nr fun72 加入系統函式呼叫宣告 int fun void 2.在include linux sys.h 加入系統函式宣告 extern int sys ...