sys_read

系统调用-read

入口

read_write.c/sys_read()

函数签名

asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count)

调用

  • tmp = getname(filename) 将文件字符串从用户态转换到内核态

  • file_table.c/fget_light(fd, fput_needed) 根据fd获取file

    • 从current->files->fd[fd]中获取sys_open打开的file
  • read_write.c/file_pos_read(file) 获取file的读取位置f_ops

  • read_write.c/vfs_read(file, buf, count, pos) 通过vfs读取文件内容到缓存中

    • 判断权限,如open的时候是否指定可读权限,以及file对应的文件系统是否有对应的read方法
    • 调用file->f_op->read/file->f_op->aio_read方法
      • 调用filemap.c/generic_file_read 这里的怎么到文件系统的,可以见下一个章节file->op
        • 创建iovec向量(这个是用来批量文件操作)和kiocb(这个具体啥用不懂) 通过buff和count
        • filemap.c/__generic_file_aio_read 这里做了一些参数转换
          • do_generic_file_read
            • do_generic_mapping_read 核心方法,支持page_cache缓存读取和实际磁盘的读取,接下来主要分析page_cache miss读取实际磁盘加载到page_cache,以及page_cache命中2种逻辑,中间还有缓存是否dirty等一系列逻辑
              • 通过*ppos >> PAGE_CACHE_SHIFT 计算block的索引数, 即磁盘block大小(等于一个page页大小),
              • 通过req_size = (desc->count + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT 计算需要请求的block数
              • 接下来通过for循环读取磁盘文件内容
                • 先判断要读取的index是否大于文件最大block数

                • 预读处理readahead.c/page_cache_readahead,这块不是很懂,以后在补充

                • filemap.c/find_get_page(mapping, index) 从page_cache中获取缓存,基于索引从基数树中查询缓存

                  • radix-tree.c/radix_tree_lookup(&mapping->page_tree, offset) 在基树上查询是否有记录
                • 第一种情况,cache miss,会先调整预读参数 readahead.c/handle_ra_miss,然后实际读取文件

                  • pagemap.c/page_cache_alloc_cold(address_mapping) 先分配page cache页,注意此时还没有填充磁盘内存
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值