zoukankan      html  css  js  c++  java
  • 缓存管理器01

    0x01 从文件读取,一瞥“缓存管理器与文件系统以及内存管理器”的关系

           当某个文件第一次被NtReadFile系统调用读取时,NtReadFile函数会构造一个IRP下发到文件系统驱动FSD.

           FSD查看该IRP是否可以被缓存,如果可以的话,会调用缓存管理器的CcInitializeCacheMap()函数建立缓存,它里面会调用内存管理器(VMM)的MmCreateSection函数建立一个Section Object,并把这个Section Object映射到内核空间,如果IRP是可以缓存的,则会调用CcCopyRead()函数进行从缓存中读取文件。

           如果此文件还没有在内存中,则会产生页面错误,交给MmAccessFault()函数处理,它会调用IoPageRead()分配一个不缓存 的IRP,但是它会走FSD,不会调用缓存的函数,而是最终调用磁盘驱动进行真实的磁盘读写读入到内存。之后CcCopyRead()再不会产生错误了,会从缓存复制到用户Buffer中。

           从xp源码看NtReadFile:

       

       NtReadFile 中判断是否有缓存,如果文件已经被缓存,那么读写操作都通过被称为“快速IO”的高速机制来处理,而不需要“生成一个IRP”这样的开销:

         如果没有缓存走文件系统,IopfCallDriver下发IRP到文件对象对应的设备所在的设备堆栈的最顶层设备对象:

          

     

            

                  最后IRP下发会调用到Ntfs的NtfsFsdRead()函数,该函数通过缓存管理器的CcInitializeCacheMap建立缓存      

    CcInitializeCacheMap内又会调用内存管理器(VMM)的MmCreateSection函数建立一个Section Object

     

                   创建SectionObject 后,缓存管理器调用CcCreateVacbArray创建VACB索引数组.

     

                  再之后文件系统驱动的NtfsFsdRead,调用CcCopyRead尝试从缓存中读取数据,如果如果缓存没有这个要读文件的页面,则产生页面异常。

     

    0x02 拿到文件记录缓存数据的方法

           获取缓存管理器所用的那个文件对象,就可以读到缓存管理器中的缓存了。

      如果文件对象对应的文件是文件目录,那么可以读取到该目录对目录下文件的各个索引INDEX_ENTRY;如果是文件对象对应的文件是文件本身,那么可以读到文件数据的缓存;

      要判断这两种缓存读取是否正确,只需要判断NTFS_NTC_SCB_INDEX 和 NTFS_NTC_SCB_DATA标志即可。

     

  • 相关阅读:
    流复制-pg_basebackup (有自定义表空间)
    流复制-pg_basebackup (没有自定义表空间)
    PG 更新统计信息
    PG修改参数方法
    Postgres的索引01
    Postgres基础操作
    PostgreSQL安装
    SQL拦截器
    没对象的快自己写一个吧!带你了解一下python对象!
    喜欢看电影来哦!教你如果使用Python网络爬虫爬取豆瓣高分电影!
  • 原文地址:https://www.cnblogs.com/lsh123/p/14973735.html
Copyright © 2011-2022 走看看