以前对文件系统、缓存管理器、内存管理器的关系比较模糊,特别是具体在文件操作过程中的相互调用关系。在看《数据恢复技术》这本书时,介绍了些,以及另外的一些资料,总算是大致明白了它们之间的关系。摘录相关的文字如下;
1、显示文件I/O:应用程序通过Win32 I/O接口函数如CreateFile、ReadFile及WriteFile等来访问文件。函数CreateFile是通过Win32客户端DLL-Kernel32.dll来实现的。函数CreateFile通过NtCreateFile来完成。NtCreateFile通过ObopenobjectByName解析名字字符串,通过IopParseDevice创建I/O请求包IRP,通过IoCallDriver将IRP交给合适的FSD以创建文件。函数ReadFile通过NtReadFile来完成。NtReadFile将已打开文件的句柄转换成文件对象指针,检查访问权限,创建IRP读请求,通过IoCallDriver将IRP交给合适的FSD。如果文件可以放到高速缓存中,那么需要检查PrivateCacheMap:如有效则表示该文件已有私有高速缓存映射结构;如无效则表示尚没有私有高速缓存映射结构,需要调用CcInitializeCacheMap来初始化。NtReadFile通过CcCopyRead从高速缓存中读取数据。如果数据还不在高速缓存中,CcCopyRead会引起缺页中断,并间接调用MmAccessFault。函数WriteFile与ReadFile相类似:只不过WriteFile调用NtWriteFile,且FSD调用CcCopyWrite而不是CcCopyRead。
2、高速缓存延迟写:高速缓存管理器的延迟写线程定期对高速缓存中已被修改的页面进行写操作。这是通过调用内存管理器的MmFlushSection函数来完成的。具体地说,MmFlushSection通过调用IoAsynchronousPageWrite将数据送交FSD。
3、高速缓存提前读:高速缓存管理器的提前读线程负责提前读数据,提前读线程通过分析已作的读操作,来决定提前读多少。提前读操作是通过缺页中断来完成的。
4、内存脏页写:内存脏页写线程定期地清洗缓冲区。该线程通过IoAsynchronousPageWrite来创建IRP写请求,这些IRP被标识为不能通过高速缓存,因为它们被FSD直接送交到磁盘存储驱动程序。
5、内存缺页处理:以上在进行显示I/操作与高速缓存提前读时,都会用到内存缺页处理。另外,只要应用程序访问内存映射文件且所需页面不在内存时,也会产生内存缺页处理。内存缺页处理MmAccessFault通过IoPageReadFile向文件所在文件系统发送IRP请求包来完成。