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() 呼叫時相同的頁數。