檔案系統原始碼分析之inode c

2021-09-24 08:46:02 字數 4899 閱讀 8936

inode.c主要是管理檔案系統中inode結構的,功能包括,把硬碟的inode讀入內容,把記憶體的inode內容寫入硬碟,或記憶體的inode表中獲取乙個空的或者指定的inode,生成乙個管道的inode,查詢inode中的某個塊,或者在inode中生成新的塊。

/*

* linux/fs/inode.c

* * (c) 1991 linus torvalds

*/#include

#include

#include

#include

#include

#include

// 系統的inode表,整個系統的所有程序共享

struct m_inode inode_table[nr_inode]=,};

static void read_inode(struct m_inode * inode);

static void write_inode(struct m_inode * inode);

// 互斥訪問

static inline void wait_on_inode(struct m_inode * inode)

static inline void lock_inode(struct m_inode * inode)

static inline void unlock_inode(struct m_inode * inode)

// 置屬於dev的inode無效

void invalidate_inodes(int dev) }}

// 遍歷所有inode,從硬碟讀包括該inode的資料塊,然後用記憶體的inode覆蓋硬碟讀進來的,存在buffer裡,等待回寫

void sync_inodes(void)

}// 找到inode中塊號為block的塊對應哪個硬碟塊號或如果沒有該塊則在硬碟中新建乙個塊

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

// 返回硬碟中的塊號

return inode->i_zone[block];

} block -= 7;

if (block<512)

if (!inode->i_zone[7])

return 0;

// 索引為7的塊是間接塊,需要把內容讀進來才知道具體的硬碟塊號

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;

// 先取得一級索引對應的資料,資料中的每一項對應512個項

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

return 0;

// 每乙個索引對應512個項,所以除以512,即右移9位,取得二級索引

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;

// 算出偏移,最大偏移是511,所以&511

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

if (create && !i)

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

brelse(bh);

return i;

}// 查詢inode中第block塊對應硬碟的塊號

int bmap(struct m_inode * inode,int block)

// 查詢inode中的第block塊對應的硬碟哪個塊,如果有則返回,沒有則建立,返回硬碟中的塊號

int create_block(struct m_inode * inode, int block)

void iput(struct m_inode * inode)

if (!inode->i_dev)

if (s_isblk(inode->i_mode))

repeat:

// 還有人引用引用數減一后返回

if (inode->i_count>1)

// 沒人引用該inode,刪除該inode的內容,並釋放該inode

if (!inode->i_nlinks)

// 需要回寫硬碟,則回寫

if (inode->i_dirt)

inode->i_count--;

return;

}// 從inode表(陣列)裡找到乙個未使用的inode結構

struct m_inode * get_empty_inode(void)

} if (!inode)

wait_on_inode(inode);

// 沒有被引用還會有需要回寫的資料?

while (inode->i_dirt)

// 找到後該inode又被引用了,繼續找

} while (inode->i_count);

memset(inode,0,sizeof(*inode));

inode->i_count = 1;

return inode;

}// 獲取乙個用於管道的inode節點

struct m_inode * get_pipe_inode(void)

inode->i_count = 2; /* sum of readers/writers */

// 初始化讀寫指標

pipe_head(*inode) = pipe_tail(*inode) = 0;

// 標記該inode是管道型別

inode->i_pipe = 1;

return inode;

}// 在inode表中找到對應的inode節點,如果找到的是掛載的檔案系統,則要查詢的等於掛載點的裝置和,nr為檔案系統的根目錄

struct m_inode * iget(int dev,int nr)

wait_on_inode(inode);

// 阻塞的時候資料可能發生了變化,繼續比較,不一樣了則從頭開始再找

if (inode->i_dev != dev || inode->i_num != nr)

inode->i_count++;

// 另乙個檔案系統掛載在該inode下

if (inode->i_mount)

iput(inode);

// 找到了該超級塊,更新dev為該超級塊的的裝置號,塊號為第一塊,從新的起點開始找

dev = super_block[i].s_dev;

nr = root_ino;

inode = inode_table;

continue;

} if (empty)

iput(empty);

return inode;

} if (!empty)

return (null);

// 找不到則返回乙個新的inode

inode=empty;

inode->i_dev = dev;

inode->i_num = nr;

read_inode(inode);

return inode;

}// 把inode的資料從硬碟中讀進來,通過超級塊的資訊和inode中的編號算出inode在硬碟的塊號,讀進來

static void read_inode(struct m_inode * inode)

// 先把inode從硬碟中讀進來,然後覆蓋,等待回寫

static void write_inode(struct m_inode * inode)

if (!(sb=get_super(inode->i_dev)))

panic("trying to write inode without device");

block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +

(inode->i_num-1)/inodes_per_block;

// 讀入包含該inode的整個資料塊

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

panic("unable to read i-node block");

// 寫到快取記憶體等待回寫到硬碟

((struct d_inode *)bh->b_data)

[(inode->i_num-1)%inodes_per_block] =

*(struct d_inode *)inode;

bh->b_dirt=1;

inode->i_dirt=0;

brelse(bh);

unlock_inode(inode);

}複製**

檔案系統原始碼分析之普通檔案讀寫

檔案讀寫主要是通過inode結構裡的資料,讀取或者寫入到底層的硬碟中,並更新相應的屬性。linux fs read write.c c 1991 linus torvalds include include include include include include extern intrw c...

檔案系統 inode節點

檔案儲存在硬碟上,硬碟的最小儲存單位叫做 扇區 sector 每個扇區儲存512位元組 相當於0.5kb 扇區是磁碟上儲存的最小單位 作業系統讀取硬碟的時候,不會乙個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取乙個 塊 block 這種由多個扇區組成的 塊 是檔案訪問的最小單...

C 原始碼學習之 監控檔案系統

說明 建立windows應用程式,在e盤上建立資料夾wang using system using system.collections.generic using system.componentmodel using system.data using system.drawing using ...