| 下边我们来看一下当进程通过 read() 系统调用读取一个已经设置了 O_DIRECT 标识符的文件的时候,系统都做了哪些处理。 函数 read() 的原型如下所示: ssize_t read(int feledes, void *buff, size_t nbytes) ; 
 操作系统中处理 read() 函数的入口函数是 sys_read(),其主要的调用函数关系图如下: sys_read()   |-----vfs_read()   |----generic_file_read()   |----generic_file_aio_read()   |--------- generic_file_direct_IO()  
 函数 sys_read() 从进程中获取文件描述符以及文件当前的操作位置后会调用 vfs_read() 函数去执行具体的操作过程,而 vfs_read() 函数最终是调用了 file 结构中的相关操作去完成文件的读操作,即调用了 generic_file_read() 函数,其代码如下所示: ssize_t  generic_file_read(struct file *filp,  char __user *buf, size_t count, loff_t *ppos)  {   struct iovec local_iov = { .iov_base = buf, .iov_len = count };   struct kiocb kiocb;   ssize_t ret;     init_sync_kiocb(&kiocb, filp);   ret = __generic_file_aio_read(&kiocb, &local_iov, 1, ppos);   if (-EIOCBQUEUED == ret)   ret = wait_on_sync_kiocb(&kiocb);   return ret;  } 
 函数 generic_file_read() 初始化了 iovec 以及 kiocb 描述符。描述符 iovec 主要是用于存放两个内容:用来接收所读取数据的用户地址空间缓冲区的地址和缓冲区的大小;描述符 kiocb 用来跟踪 I/O 操作的完成状态。之后,函数 generic_file_read() 凋用函数 __generic_file_aio_read()。该函数检查 iovec 中描述的用户地址空间缓冲区是否可用,接着检查访问模式,若访问模式描述符设置了 O_DIRECT,则执行与直接 I/O 相关的代码。函数 __generic_file_aio_read() 中与直接 I/O 有关的代码如下所示: if (filp->f_flags & O_DIRECT) {   loff_t pos = *ppos, size;   struct address_space *mapping;   struct inode *inode;     mapping = filp->f_mapping;   inode = mapping->host;   retval = 0;   if (!count)   goto out;   size = i_size_read(inode);   if (pos < size) {   retval = generic_file_direct_IO(READ, iocb,   iov, pos, nr_segs);   if (retval > 0 && !is_sync_kiocb(iocb))   retval = -EIOCBQUEUED;   if (retval > 0)   *ppos = pos + retval;   }   file_accessed(filp);   goto out;  } 
 上边的代码段主要是检查了文件指针的值,文件的大小以及所请求读取的字节数目等,之后,该函数调用 generic_file_direct_io(),并将操作类型 READ,描述符 iocb,描述符 iovec,当前文件指针的值以及在描述符 io_vec 中指定的用户地址空间缓冲区的个数等值作为参数传给它。当 generic_file_direct_io() 函数执行完成,函数 __generic_file_aio_read()会继续执行去完成后续操作:更新文件指针,设置访问文件 i 节点的时间戳;这些操作全部执行完成以后,函数返回。 函数 generic_file_direct_IO() 会用到五个参数,各参数的含义如下所示: 
    rw:操作类型,可以是 READ 或者 WRITEiocb:指针,指向 kiocb 描述符 iov:指针,指向 iovec 描述符数组offset:file 结构偏移量nr_segs:iov 数组中 iovec 的个数 (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |