[文件系统]read系统调用剖析(二)

在vfs_read()函数中有如下几句代码:
291                 if (file->f_op->read)
292                         ret = file->f_op->read(file, buf, count, pos);
293                 else
294                         ret = do_sync_read(file, buf, count, pos);
file->f_op->read()函数在哪里赋值的?
答:是在各个文件系统mount的时候inode初始化的时候赋值的,比如fat文件系统对应的赋值的位置是kernel/fs/fat/Inode.c文件的fat_fill_inode()函数,即:inode->i_fop = &fat_file_operations;
154 const struct file_operations fat_file_operations = {
155         .llseek         = generic_file_llseek,
156         .read           = do_sync_read,
157         .write          = do_sync_write,
158         .aio_read       = generic_file_aio_read,
159         .aio_write      = generic_file_aio_write,
160         .mmap           = generic_file_mmap,
161         .release        = fat_file_release,
162         .ioctl          = fat_generic_ioctl,
163         .fsync          = fat_file_fsync,
164         .splice_read    = generic_file_splice_read,
165 };
最后vfs_read()函数最终会调用到do_sync_read()函数,
252 ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
253 {
254         struct iovec iov = { .iov_base = buf, .iov_len = len };
255         struct kiocb kiocb;
256         ssize_t ret;
257 
258         init_sync_kiocb(&kiocb, filp);
259         kiocb.ki_pos = *ppos;
260         kiocb.ki_left = len;
261 
262         for (;;) {
263                 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
264                 if (ret != -EIOCBRETRY)
265                         break;
266                 wait_on_retry_sync_kiocb(&kiocb);
267         }
268 
269         if (-EIOCBQUEUED == ret)
270                 ret = wait_on_sync_kiocb(&kiocb);
271         *ppos = kiocb.ki_pos;
272         return ret;
273 }
filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos)最终最调用到generic_file_aio_read()函数generic_file_aio_read()函数根据上层open()的时候是否带O_DIRECT flag然后进入不同的分支,如果带O_DIRECT flag则表明是直接IO读取操作,不带page cache的缓冲区。如果不带O_DIRECT flag则最终会执行到do_generic_file_read()函数,do_generic_file_read()函数首先到filp->mapping的空间所要读取的页,如果没有找到对应的page,那么会调用page_cache_sync_readahead()函数启用同步预读,如果在文件的address_space找到对应的page则调用page_cache_async_readahead()函数进行异步预读。
文件预读取的概念: 文件预读取的概念
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值