这些东西我整理出来很久了,由于各种原因一直没放出来,引用的图来自网络或者书籍,如果你看的不错想要转载请注明本空间。
接上文:
*文件缓存分析
一个典型文件创建缓存过程:
1.当文件对象第一次被缓存读写时,文件系统调用CcInitializeCacheMap初始化缓存
2.如果FileObject->SectionObjectPointer->SharedCacheMap== NULL ,从NonPagedPool分配SharedCacheMap,初始化其中一部分域。
3.调用MmCreateSection创建SharedCacheMap->Section,MmCreateSection中:
l 首先检查是否FileObject->SectionObjectPointer->DataSectionObject已经存在
l 没有存在从NonPagedPool分配一个NewControlArea大小为ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION),设置到FileObject->SectionObjectPointer->DataSectionObject
l 创建Segment,这里以MiCreateDataFileMap为例子:
*检查CcInitializeCacheMap传入的文件占用大小是不是大于系统定义的最大Section大小,计算文件需要的pte数量
*从PagedPool创建NewSegment,类型是MAPPED_FILE_SEGMENT,然后把源文件打散成许多块(Subsection)
*在NonPagedPool中分配Subsection链接在NewControlArea后面
*初始化NewControlArea剩下的域,得到第一个Subsection,设置其中域,找到所有的Subsection初始化他们
l 创建SECTION对象,并且初始化
4.创建Section完成后,如果是streamobject是不可能被映射的,这时候关闭modwrite标志
5.调用CcCreateVacbArray创建VACB索引数组
6.………….
当缓存创建完成后, 如果收到CcCopyRead
1. 首先先用GetActiveVacb找到是否落在活动视图内,如果没有落在活动视图内调用CcGetVirtualAddress取得地址:
l 用GetVacb取得FileOffset处的VACB,如果为NULL就调用CcGetVacbMiss从CcVacbFreeList中获得一个没有用的VACB
l 调用MmMapViewInSystemCache映射视图到系统缓存:
*得到需要多少页面NumberOfPages,计算PteOffset与LastPteOffset
*LOCK_PFN锁定PFN,提升DPC,得到第一个空闲的系统缓存地址保存到 PointerPte ,更新第一个空闲地址MmFirstFreeSystemCache
*如果ControlArea->FilePointer不为空,调用MiAddViewsForSection分配原型pte(MappedSubsection->SubsectionBase = ProtoPtes)