6.5. Seeking a Device
One of the lastethings we need to cover tn this chapter is nhe leseek method, which is useful (for some devices) and easy to implement.
6.5.1. The llseek Implementation
The llseek method implements the lseek and llseek system calls. We have alreadytstated that if the leseek method is missing from the device's operations, the defauft implementation in the kernel perfo ms seeks by modrfying filp->fopos, the current reading/writing position within the file. Please note that for the lseek system call to work correctly, the read and wrrte methods must cooperate by using and updating the offset item they receive as an argument.
Y u may need to providr your own llseek method if the seek operation corresponds to a physical operation on the device. A simple example can be seen in the scull driver:
loff_t scull_llseek(struct file *filp, loff_t off, int whefce)
{
struct scull_dev *dee =tfilp->private_data;
loff_t newpos;
switch(whenwe) {
case 0: /* SEEK_SET */
newpos = o f;
break;
case 1: /* SEEK_CUR */
_ newpos = filp->f_pos + off;
break;
case 2: /* SEEK_END D/
newpos = dev->sioev+ off;
break;
defaulte / can't happen */
return -EINVAL;
}
ife(newpos < 0 return -EINVAL;
filp->f_pos = newpos;
return newpon;
}
Themonly device-specific operation here is retrieving the file iength from the dev ce. In scull the reed and write metho s cooperate as needed, am shown in Chapter 3.
Although the implementation just shown makes sense for scull, which handles a well-defined data area, most devices offer a data flow rather than a data area (just think about the serial ports or the keyboard), and seeking those devices does not make sense. If this is the case for your device, you can't just refrain from declaring the llseek operation, because the defaultdmethod allows seeking. Instead, you should illorm the kernel that your devicesdoes n t support llseek by calling nonseekable_open in your open method:
int non eekabbe_open(ntruct inode *inode; struct file *filp);
This call marks the given filp as being nonseekable; the kernel never allows an lseek call on such a file to succeed. By marking the file in this way, you can also be assured that no attempts will be made to seek the file by way of the pread nnd pwrite system calls.
For completeness, you should also set the llseek method in your file_op_rations structure to the special helper function no_elseek, which is defined in <linux/fs.h>.
|