dm-io¶
Dm-io 提供同步和非同步 I/O 服務。有三種可用的 I/O 服務型別,每種型別都有同步和非同步版本。
使用者必須設定一個 io_region 結構來描述所需的 I/O 位置。每個 io_region 指示一個塊裝置以及區域的起始扇區和大小。
struct io_region {
struct block_device *bdev;
sector_t sector;
sector_t count;
};
Dm-io 可以從一個 io_region 讀取或寫入一個或多個 io_region。對多個區域的寫入透過 io_region 結構陣列指定。
第一種 I/O 服務型別將記憶體頁列表作為 I/O 的資料緩衝區,以及指向第一頁的偏移量。
struct page_list {
struct page_list *next;
struct page *page;
};
int dm_io_sync(unsigned int num_regions, struct io_region *where, int rw,
struct page_list *pl, unsigned int offset,
unsigned long *error_bits);
int dm_io_async(unsigned int num_regions, struct io_region *where, int rw,
struct page_list *pl, unsigned int offset,
io_notify_fn fn, void *context);
第二種 I/O 服務型別將 bio 向量陣列作為 I/O 的資料緩衝區。如果呼叫者有一個預先組裝好的 bio,但想將 bio 的不同部分指向不同的裝置,這種服務會很方便。
int dm_io_sync_bvec(unsigned int num_regions, struct io_region *where,
int rw, struct bio_vec *bvec,
unsigned long *error_bits);
int dm_io_async_bvec(unsigned int num_regions, struct io_region *where,
int rw, struct bio_vec *bvec,
io_notify_fn fn, void *context);
第三種 I/O 服務型別將指向 vmalloc'd 記憶體緩衝區的指標作為 I/O 的資料緩衝區。如果呼叫者需要對大區域進行 I/O 但又不想分配大量單個記憶體頁,這種服務會很方便。
int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw,
void *data, unsigned long *error_bits);
int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw,
void *data, io_notify_fn fn, void *context);
非同步 I/O 服務的呼叫者必須包含一個完成回撥例程的名稱以及指向 I/O 上下文資料的一些指標。
typedef void (*io_notify_fn)(unsigned long error, void *context);
此回撥中的“error”引數,以及所有同步版本中的 *error 引數,是一個位集(而不是簡單的錯誤值)。在對多個區域進行寫 I/O 的情況下,此位集允許 dm-io 指示每個單獨區域的成功或失敗。
在使用任何 dm-io 服務之前,使用者應呼叫 dm_io_get() 並指定他們期望同時執行 I/O 的頁數。Dm-io 將嘗試調整其記憶體池大小,以確保始終有足夠的頁可用,從而避免在執行 I/O 時不必要的等待。
當用戶完成 dm-io 服務的使用後,他們應呼叫 dm_io_put() 並指定與 dm_io_get() 呼叫時相同的頁數。