Chinaunix首页 | 论坛 | 博客
  • 博客访问: 123767
  • 博文数量: 23
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 345
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-13 15:50
文章分类

全部博文(23)

文章存档

2010年(6)

2009年(12)

2008年(5)

我的朋友

分类: LINUX

2008-05-07 21:22:28

在内核想对一个文件中的数据用二分法查找。二分法查找的输入是需要一个长度做二分的。对文件而言就是文件长度了。于是想到了内核中用seek函数,实现对文件中内容的二分法查找。
seek在内核中是怎么实现的呢?
直接想到了在内核中找了file_operations的实现于是
在Fs.h中发现了file_operations
struct file_operations {
 struct module *owner;
 loff_t (*llseek) (struct file *, loff_t, int);
 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
..........
};
其中只看到了llseek();
说明llseek();是seek簇函数的最终实现。
分析loff_t (*llseek) (struct file *, loff_t, int);
其中loff_t为 long long型:
typedef long long __kernel_loff_t; //Posix_types.h
typedef __kernel_loff_t  loff_t; //Types.h
struct file* 为文件指针是由filp_open得到的。
int应该是方向
 
在ext3中(file.c)
const struct file_operations ext3_file_operations = {
 .llseek  = generic_file_llseek,
 ...
};
可见最终实现是generic_file_llseek,
generic_file_llsee实现在Read_write.c里
loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
{
 long long retval;
 struct inode *inode = file->f_mapping->host;
 mutex_lock(&inode->i_mutex);
 switch (origin) {
  case SEEK_END:
   offset += inode->i_size;
   break;
  case SEEK_CUR:
   offset += file->f_pos;
 }
 retval = -EINVAL;
 if (offset>=0 && offset<=inode->i_sb->s_maxbytes) {
  if (offset != file->f_pos) {
   file->f_pos = offset;
   file->f_version = 0;
  }
  retval = offset;
 }
 mutex_unlock(&inode->i_mutex);
 return retval;
}
注意其中没有显式写SEEK_SET,体会一下:)
以上就是在ext3文件系统中对用户态seek的最终实现。
回到开始的问题,
对llseek使用参数llseek(filp, 0L, SEEK_END);
返回值就是以字节为单位的文件大小。
得到了文件大小,再用llseek实现二分法查找,呵呵下面的就简单了。
阅读(1357) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~