6.5. 移位一個設備

2018-02-24 15:49 更新

6.5.?移位一個設備

本章最后一個需要我們涉及的東西是 llseek 方法, 它有用(對于某些設備)并且容易實現(xiàn).

6.5.1.?llseek 實現(xiàn)

llseek 方法實現(xiàn)了 lseek 和 llseek 系統(tǒng)調(diào)用. 我們已經(jīng)說了如果 llseek 方法從設備的操作中缺失, 內(nèi)核中的缺省的實現(xiàn)進行移位通過修改 filp->f_pos, 這是文件中的當前讀寫位置. 請注意對于 lseek 系統(tǒng)調(diào)用要正確工作, 讀和寫方法必須配合, 通過使用和更新它們收到的作為的參數(shù)的 offset 項.

你可能需要提供你自己的方法, 如果移位操作對應一個在設備上的物理操作. 一個簡單的例子可在 scull 驅動中找到:


loff_t scull_llseek(struct file *filp, loff_t off, int whence)
{
        struct scull_dev *dev = filp->private_data;
        loff_t newpos;

        switch(whence)
        {
        case 0: /* SEEK_SET */
                newpos = off;
                break;

        case 1: /* SEEK_CUR */
                newpos = filp->f_pos + off;
                break;

        case 2: /* SEEK_END */
                newpos = dev->size + off;
                break;

        default: /* can't happen */
                return -EINVAL;
        }
        if (newpos < 0)
                return -EINVAL;
        filp->f_pos = newpos;
        return newpos;
}

唯一設備特定的操作是從設備中獲取文件長度. 在 scull 中 read 和 write 方法如需要地一樣協(xié)作, 如同在第 3 章所示.

盡管剛剛展示的這個實現(xiàn)對 scull 有意義, 它處理一個被很好定義了的數(shù)據(jù)區(qū), 大部分設備提供了一個數(shù)據(jù)流而不是一個數(shù)據(jù)區(qū)(想想串口或者鍵盤), 并且移位這些設備沒有意義. 如果這就是你的設備的情況, 你不能只制止聲明 llseek 操作, 因為缺省的方法允許移位. 相反, 你應當通知內(nèi)核你的設備不支持 llseek , 通過調(diào)用 nonseekable_open 在你的 open 方法中.


int nonseekable_open(struct inode *inode; struct file *filp); 

這個調(diào)用標識了給定的 filp 為不可移位的; 內(nèi)核從不允許一個 lseek 調(diào)用在這樣一個文件上成功. 通過用這樣的方式標識這個文件, 你可確定不會有通過 pread 和 pwrite 系統(tǒng)調(diào)用的方式來試圖移位這個文件.

完整起見, 你也應該在你的 file_operations 結構中設置 llseek 方法到一個特殊的幫忙函數(shù) no_llseek, 它定義在 <linux/fs.h>.

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號