塊裝置層分析(1)

2021-06-19 01:39:44 字數 1889 閱讀 5149

一、綜述

圖1是塊裝置操作的乙個分層實現圖。當乙個程序呼叫read讀取乙個檔案時,核心執行如下乙個過程:首先,它通過vfs層去讀取要到的檔案塊有沒有已經被cache了,這個cache由乙個buffer_head結構讀取。如果要讀取的檔案塊還沒有被cache,則就要從檔案系統中去讀取了,這就是檔案系統的對映層,它通過乙個address_space結構來引用,然後呼叫檔案系統讀函式(readpage)去讀取乙個頁面大小的資料,這個讀函式對於不同的檔案系統來說,是不一樣的。當它從磁碟中讀出資料時,它會將資料頁鏈入cache中,當下次再讀取時,就不需要再次從磁碟出去讀了。readpage()函式並不是直接去操作磁碟,而只是將請求初始化成乙個bio結構,並提交給通用塊層(generic block layer)。

它就通過submit_bio()去完成的。通用塊層再呼叫相應裝置的io排程器,通過這個排程器的排程演算法,將這個bio或合併到已存在的request中,或建立乙個新的request,並將這個新建立的request插入到裝置的請求佇列中去。這就完成了io排程層的工作。最後就是塊裝置驅動所做的工作了。io排程器傳遞給塊驅動的是乙個請求佇列,塊驅動就是要處理這個佇列中的請求,直到這個隊列為空為止。

二、通用塊層(generic block layer)

通用塊層操作的是乙個bio結構,這個結構主要的資料域是,

unsigned short              bi_vcnt;

struct bio_vec        *bi_io_vec;     /* the actual vec list */

這個就是要讀寫的資料向量,且每個struct bio_vec       為乙個segment。

//這個函式主要是呼叫generic_make_request()去完成工作:

void submit_bio(int rw, struct bio *bio)

//這個函式的主要作用是將bio傳遞給驅動去處理

void generic_make_request(struct bio *bio)

while (ret); }

//這要函式的主要作用就是呼叫io排程演算法將bio合併,或插入到佇列中合適的位置中去

static int __make_request(request_queue_t *q, struct bio *bio)

get_rq:

rw_flags = bio_data_dir(bio);

if (sync)

rw_flags |= req_rw_sync;

//新創乙個request

req = get_request_wait(q, rw_flags, bio);

//初始化這個request。

init_request_from_bio(req, bio);

spin_lock_irq(q->queue_lock);

if (elv_queue_empty(q)) //空佇列的處理

blk_plug_device(q);

add_request(q, req); //將新請求加入佇列中去

out:

if (sync) //如果需要同步,立即處理請求

__generic_unplug_device(q);

spin_unlock_irq(q->queue_lock);

return 0;

end_io:

bio_endio(bio, nr_sectors << 9, err);

return 0; }

//觸發塊裝置驅動進行真正的io操作

void __generic_unplug_device(request_queue_t *q)

linux的塊裝置層

ll rw block 是塊裝置驅動層,向上提供按block讀寫塊裝置到某個記憶體位址的 是以page為目標單位 方法 bread 是塊裝置緩衝層,磁碟上的block用頁快取 先從這個快取裡找,找不到再呼叫ll rw block 讀進來 各個檔案系統,要向vfs層提供read inode 這樣的介面...

塊裝置驅動1 塊裝置基礎知識

塊裝置與字元裝置 1.訪問方式的不同 字元裝置按照位元組進行讀取,塊裝置按塊進行讀取 2.緩衝區 塊裝置本身驅動層支援緩衝區 軟體實現的緩衝區 所以塊裝置驅動最適合儲存裝置 儲存裝置按塊進行讀寫的特點決定 而字元裝置驅動層沒有緩衝 3.訪問的順序 塊裝置可以實現隨機的訪問,不連續塊的訪問,而字元裝置...

LINUX塊裝置驅動 1

編寫塊裝置驅動的關鍵步驟 1 呼叫register blkdev申請或註冊主裝置號及裝置名稱,詳見核心原始碼中該函式的注釋。不過下面這篇文章裡並未用到這一步 2 呼叫blk init queue函式建立並初始化乙個 request queue 結構,該函式需要乙個用來處理請求的do request函...