Unix 系統已經長時間支持名為 readv 和 writev 的 2 個系統調用. 這些 read 和 write 的"矢量"版本使用一個結構數組, 每個包含一個緩存的指針和一個長度值. 一個 readv 調 用被期望來輪流讀取指示的數量到每個緩存. 相反, writev 要收集每個緩存的內容到一起 並且作為單個寫操作送出它們.
如果你的驅動不提供方法來處理矢量操作, readv 和 writev 由多次調用你的 read 和 write 方法來實現. 在許多情況, 但是, 直接實現 readv 和 writev 能獲得更大的效率.
矢量操作的原型是:
ssize_t (*readv) (struct file *filp, const struct iovec *iov, unsigned long count, loff_t
*ppos);
ssize_t (*writev) (struct file *filp, const struct iovec *iov, unsigned long count, loff_t
*ppos);
這里, filp 和 ppos 參數與 read 和 write 的相同. iovec 結構, 定義於
<linux/uio.h>, 如同:
struct iovec
{
void user *iov_base; kernel_size_t iov_len;
};
每個 iovec 描述了一塊要傳送的數據; 它開始於 iov_base (在用戶空間)並且有 iov_len 字節長. count 參數告訴有多少 iovec 結構. 這些結構由應用程序創建, 但是內核在調用 驅動之前拷貝它們到內核空間.
矢量操作的最簡單實現是一個直接的循環, 只是傳遞出去每個 iovec 的地址和長度給驅動 的 read 和 write 函數. 然而, 有效的和正確的行為常常需要驅動更聰明. 例如, 一個磁 帶驅動上的 writev 應當將全部 iovec 結構中的內容作為磁帶上的單個記錄.
很多驅動, 但是, 沒有從自己實現這些方法中獲益. 因此, scull 省略它們. 內核使用 read 和 write 來模擬它們, 最終結果是相同的.