struct buffer_head {
char * b_data; /* pointer to data block (1024 bytes) */
unsigned long b_blocknr; /* block number */
unsigned short b_dev; /* device (0 = free) */
unsigned char b_uptodate;
unsigned char b_dirt; /* 0-clean,1-dirty */
unsigned char b_count; /* users using this block */
unsigned char b_lock; /* 0 - ok, 1 -locked */
struct task_struct * b_wait;
struct buffer_head * b_prev;
struct buffer_head * b_next;
struct buffer_head * b_prev_free;
struct buffer_head * b_next_free;
};
該結構0.11的快取結構重要的是最後面的4個指標域。當資料被寫入緩衝塊而還沒有寫入磁碟時b_dirt被置位。當資料寫入磁碟或從磁碟讀入資料時,b_uptodate被置位。b_data指向緩衝區對應的資料區。
緩衝區通過b_prev_free和b_next_free被組織成一個雙向鏈表(表頭為free_list,該鏈表是空閑未被使用的緩衝區)。
核心使用緩衝區是通過指定的裝置號和所訪問資料區的邏輯塊號,通過調用bread(),bread_page(),breada()來進行的。
為了快速有效在緩衝區尋找並判斷出請求的資料區塊是否已經讀入到緩衝塊,核心維護這一個散列表結構(0.11中包含有307個buffer_head指標項結構)。散列表函數是裝置號與邏輯塊號的異或。
buffer_head結構中的b_prev和b_next兩個指標,將散列在表中同一項中的緩衝塊串連成一個雙向鏈表。
在搜尋空閑塊時,從free_list的最左邊開始,如果搜尋到則將其插入到散列表對應項的首部並加入到free_list的尾部,這樣越靠近鏈表尾部的緩衝塊被使用的時間越近。
核心塊裝置訪問流程:
上上層應用程式要訪問塊裝置,都需要進過緩衝區。上層應用程式想bread()發出申請,如果要申請的資料已經在緩衝區則直接返回。如果不在則通過ll_re_block想驅動程式發出申請,並讓進城進入休眠,等待驅動程式將資料讀入到緩衝區後,喚醒進程將資料返回給上層應用程式。