如果通过open调用获得一个文件描述符,而且是用O_RDONLY或O_RDWR标志打开的,就可以用read系统调用从该文件中读取字节。其内核函数在fs/read_write.c中定义:
asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t
count)
{
ssize_t ret;
struct file * file;
ret = -EBADF;
file = fget(fd);
if (file) {
if (file->f_mode & FMODE_READ) {
ret = locks_verify_area(FLOCK_VERIFY_READ,
file->f_dentry->d_inode,
file, file->f_pos, count);
if (!ret) {
ssize_t (*read)(struct file *, char *, size_t,
loff_t *);
ret = -EINVAL;
if (file->f_op && (read =
file->f_op->read) != NULL)
ret = read(file, buf, count,
&file->f_pos);
}
}
if (ret > 0)
dnotify_parent(file->f_dentry, DN_ACCESS);
fput(file);
}
return ret;
}
1.入口参数:
(1)fd:要读的文件的文件描述符
(2)buf:指向用户内存区中用来存储将读取字节的区域的指针
(3)count:欲读的字节数
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结构。