不允许lseek文件 | nonseekable_open()【转】

时间:2023-12-04 12:38:02

转自:https://blog.csdn.net/gongmin856/article/details/8273545

使用数据区时,可以使用 lseek 来往上往下地定位数据。但像串口或键盘一类设备,使用的是数据流,所以定位这些设备没有意义;在这种情况下,不能简单地不声明 llseek 操作,因为默认方法是允许定位的。

在 open 方法中调用 nonseekable_open() 时,它会通知内核设备不支持 llseek,nonseekable_open() 函数的实现定义在 fs/open.c 中:

  1. /*
  2. * This is used by subsystems that don't want seekable
  3. * file descriptors
  4. */
  5. int nonseekable_open(struct inode *inode, struct file *filp)
  6. {
  7.     filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
  8.     return 0;
  9. }

当该函数调用后,如果再使用 lseek 操作时,那么内核会进行检查(fs/read_write.c):

  1. loff_t vfs_llseek(struct file *file, loff_t offset, int origin)
  2. {
  3.     loff_t (*fn)(struct file *, loff_t, int);
  4.     fn = no_llseek;
  5.     if (file->f_mode & FMODE_LSEEK) {   //检查是否可以 LSEEK
  6.         fn = default_llseek;
  7.         if (file->f_op && file->f_op->llseek)
  8.             fn = file->f_op->llseek;
  9.     }
  10.     return fn(file, offset, origin);
  11. }

上面,no_llseek() 函数定义为:

  1. loff_t no_llseek(struct file *file, loff_t offset, int origin)
  2. {
  3.     return -ESPIPE;
  4. }

为了完整起见,如果不希望设备被 seek,还应该将 file_operations 结构中的 llseek 方法设置为特殊的辅助函数 no_llseek 。