Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1183474
  • 博文数量: 221
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2139
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(221)

文章存档

2024年(6)

2023年(8)

2022年(2)

2021年(2)

2020年(29)

2019年(11)

2018年(23)

2017年(41)

2016年(76)

2015年(23)

我的朋友
最近访客

分类: LINUX

2020-10-05 23:32:06

open函数通过系统调用sys_open进入内核空间, sysopen又调用do_sys_open,
do_sys_open 通过get_unused_fd(),在当前进程空间内的struct file结构数组中,
找一个空的struct file{}结构,并返回一个数组的下标号,之后do_sys_open又调用do_filp_open,do_filp_open调用nameidata_to_filp,
nameidata_to_filp调用__dentry_open,

 read调用顺序如下: read()->sys_read()->vfs_read()->{file->f_op->read}用户空间的read、write---linux系统调用---间接调用设备驱动程序中file_operations结构中的函数
整个调用过程是这样一个顺序的。



在__dentry_open,通过关键语句,f->f_op = fops_get(inode->i_fop);
得到了具有一个指向struct file_operations结构的指针的struct file结构指针, 

VFS的read操作
Linux中应用程序对read()的系统调用,将引起内核调用sys_read()服务例程,这完全和其它系统调用类似。在fs/目录下的read_write.c文件有sys_read()的定义,如下
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
 ssize_t ret;
 if (!(file->f_mode & FMODE_READ))
  return -EBADF;
 if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read))
  return -EINVAL;
 if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
  return -EFAULT;
 ret = rw_verify_area(READ, file, pos, count);
 if (ret >= 0) {
  count = ret;
  if (file->f_op->read)
   ret = file->f_op->read(file, buf, count, pos);
  else
   ret = do_sync_read(file, buf, count, pos);

  if (ret > 0) {
   fsnotify_access(file->f_path.dentry);
   add_rchar(current, ret);
  }
  inc_syscr(current);
 }
 return ret;
}

1.入口参数:

1fd:要读的文件的文件描述符

2buf:指向用户内存区中用来存储将读取字节的区域的指针

3count:欲读的字节数

2.出口参数:返回一个整数。在出错时返回-1;否则返回所读的字节数,通常这个数就是count值,但如果请求的字节数超过剩余的字节数,则返回实际读的字节数,例如文件的当前位置在文件尾,则返回值为0

3.执行过程:

(1)      函数fget()根据打开文件号fd找到该文件已打开文件的file结构;

(2)      取得了目标文件的file结构指针,并确认文件是以只读方式打开后,还要检查文件从当前位置f_pos开始的count字节是否对读操作加上了“强制锁”,这是通过调用locks_verify_area()函数完成的,其代码在fs.h中。

(3)      通过了对强制锁的检查后,就是读操作本身了。可想而知,不同的文件系统有不同的读操作,具体的文件系统通过file_operations结构提供用于读操作的函数指针。就Ext2文件系统来说,它有两个这样的结构,一个是Ext2_file_operations,另一个是Ext2_dir_operations,视操作的目标为文件或目录而选择其一,在打开文件时,操作结构就安装在其file结构中。对于常规文件,这个函数指针指向generic_file_read(),其代码在mm/filemap.c中。

(4)      如果读操作的返回值大于0,说明出错,则调用dnotify_parent()报告错误,并释放文件描述符、file结构、inode结构。

 

///////////////////////////////////////////////////////////

阅读(1751) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~