8.7.2  read 系统调用

如果通过open调用获得一个文件描述符,而且是用O_RDONLYO_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.入口参数:

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结构。