NT缓存管理器(五)

CcPurgeCacheSection

这个例程被FSD用来清除cache里的所有页面映射。被清除的数据从内存中被抛弃。如果数据在清扫之前被修改了,那么对数据的更新就丢了。原型如下:

         NTKERNELAPI BOOLEAN CcPurgeCacheSection (

              IN PSECTION_OBJECT_POINTERS SectionObjectPointer,

              IN PLARGE_INTEGER FileOffset OPTIONAL,

              IN ULONG Length,

              IN BOOLEAN UninitializeCacheMaps

                );

SectionObjectPointer结构说明cache数据结构被用作这个操作的一部分。FileOffset是指向一个变量的指针,这个变量包含了文件偏移信息(这个偏移就是清除开始的地方)。Length表明要清扫的字节数,从FileOffset开始计。UninitializeCacheMaps参数表明所有包含私有cache map信息的文件对象必须在清扫开始之前被反初始化。

如果SectionObjectPointer指定的section对象被使用来映射文件到任何不是cache的地方,这个调用将会失败。典型地,这种情况会发生当一个文件被一个应用程序进行了内存映射,然后就不能被清扫只要这些映射一直存在。

FileOffset和Length参数一起告诉缓存管理器什么需要被清扫。

FileOffset        

Length            

Effect

NULL           

Any Value

Length is ignored and the whole file is purged

Any Value

NULL           

The file is purged from the byte indicated by FileOffset through the end of file

Any Value

Any Value

The file is purged beginning with the byte indicated by FileOffset for Length bytes.

FSD必须可以处理这个例程返回false的情况。在这种情况下,就不能去清扫cache中的数据了。

CcRepinBcb

这个例程被FSD用来增加相关计数在一个之前创建好的BCB上。原型:

          NTKERNELAPI VOID CcRepinBcb (

                IN PVOID Bcb

                );

FSD可能发现有必要使用之前生成 的BCB。这种情况下这个例程用来保证在这个操作期间Bcb仍然有效。

FSD负责释放相关计数,调用CcUnpinRepinnedBcb。

CcSetAdditionalCacheAttributes

这个例程被FSD用来使能/使无效对一个文件的预读和后写。原型如下:

          NTKERNELAPI VOID CcSetAdditionalCacheAttributes (

                IN PFILE_OBJECT FileObject,

               IN BOOLEAN DisableReadAhead,

               IN BOOLEAN DisableWriteBehind

               );

FileObject是指要建立额外属性的文件。缓存管理器使用这个信息来决定在文件被访期间cache的行为。如果DisableReadAhead是TRUE,那么缓存管理器将不会执行预读操作。同样地,如果DisableWriteBehind是TRUE,那么缓存管理器将会使缓存的脏数据无效。取而代之的是,将会通过cache写,但是写将会持续一直到数据已经写回磁盘了为止。

这会影响缓存管理器调用CcCopyRead和CcCopyWrite。

CcSetBcbOwnerPointer

缓存管理器使用这个信息来决定谁是ERESOURCE(这东西内嵌在BCB中)的主人。尽管并不总是有用地,总有些奇怪现象就是ERESOURCE被一个线程获得却被另一个线程释放。原型如下:

          NTKERNELAPI VOID CcSetBcbOwnerPointer (

               IN PVOID Bcb,

               IN PVOID OwnerPointer

               );

Bcb参数表明BCB包含了有问题的ERESOURCE。OwnerPointer是一个指向新主人/新线程的ETHREAD结构的指针。

CcSetDirtyPageThreshold

FSD可能会限制缓存管理器为指定文件维护的脏数据的数量。原型如下:

          NTKERNELAPI VOID CcSetDirtyPageThreshold (

               IN PFILE_OBJECT FileObject,

               IN ULONG DirtyPageThreshold

               );

一旦被缓存的脏页数目超过了DirtyPageThreshold,接下来的写将会被阻止因为数据要从cache冲回磁盘。一旦脏页数止掉到阈值以下,新的写操作将会继续了。

并没有要求FSD设置这个限制。默认的是允许缓存管理器和内存管理器来控制后写策略。

CcSetDirtyPinnedData

这个调用被用来表明 由之前锁定的BCB描述的缓存块里的数据应该被标记为脏数据,不管这些数据有没有被改变。原型如下:

          NTKERNELAPI VOID CcSetDirtyPinnedData (

               IN PVOID Bcb,

               IN PLARGE_INTEGER Lsn OPTIONAL

               );

Lsn参数应该被给成NULL,对于没有使用WindowsNT日志机制的文件系统来说。

这个例程被FSD用来强制将数据写回磁盘,尽管它都没被改变

CcSetFileSizes

缓存管理器依赖于FSD来告诉它什么时候文件大小被真正改变了。这个例程被FSD用来告诉缓存管理器文件大小变了。原型:

         NTKERNELAPI VOID CcSetFileSizes (

               IN PFILE_OBJECT FileObject,

               IN PCC_FILE_SIZES FileSizes

               );

FileObject指定哪个文件的大小正被改变。FileSize是新的文件大小。CC_FILE_SIZES数据结构关联于 WindowsNT文件系统用的普通头结构的 文件大小信息。

当然FSD提供的sizes,两个关键的大小是AllocationSize and FileSize。AllocationSize是可能被存储在分配的空间上的数据的最大数量,被VM系统用来表明描述文件的section大小。FileSize表明文件里现有的数据大小,被VM系统用来表明mapped view大小。

AllocationSize必须大于FileSize.

CcSetLogHandleForFile

为了完整性把这个例程列在了这里。它被用在文件系统(WindowsNT中采用内部日志机制的文件系统)里。对于文件系统来说不总是有用的。原型:

         NTKERNELAPI VOID CcSetLogHandleForFile (

               IN PFILE_OBJECT FileObject,

               IN PVOID LogHandle,

               IN PFLUSH_TO_LSN FlushToLsnRoutine

               );

CcSetReadAheadGranularity

这个例程被FSD用来控制缓存管理器的预读策略。原型:

         NTKERNELAPI VOID CcSetReadAheadGranularity (

               IN PFILE_OBJECT FileObject,

               IN ULONG Granularity

               );

WindowsNT 缓存管理器默认的预读尺寸是4K,尽管所有的都设成了64K.

粒度上必须是是2N*PAGE_SIZE.否则结果将会不可预测。

注意,内存管理器有一个64K的硬代码限制当从磁盘驱动器读的时候。因而,即使你的FSD建立了大于64K的预读尺寸,它也会通过一系列的64K预读单元读取。

CcUninitializeCacheMap

          NTKERNELAPI BOOLEAN CcUninitializeCacheMap (

               IN PFILE_OBJECT FileObject,

               IN PLARGE_INTEGER TruncateSize OPTIONAL,

               IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent

          OPTIONAL

               );

通常在文件对象被用户应用程序关掉的时候要反初始化(Uninitializing)cache map。那会儿就必须执行一些操作来确定cache被正确地清掉。

对于一般的文件来说,两个可选参数被忽略了。代码看起来这样地:

          CcUninitializeCacheMap(FileObject, 0, 0);

从字面上看,这是文件提出的停止caching的请求。

如果这个函数返回TRUE,这是这个文件的最后一个打开实例,缓存管理器清除共享的cache map(否则共享的cache map仍被该文件的其它实例使用).

这个函数有一些有意思的副作用:

如果文件被删掉,TruncateSize参数将会指向一个LARGE_INTEGER(包含了文件大小,典型的是0).这将会告诉缓存管理器任何跟这个文件相关的脏数据都不用写回磁盘了-尽管也没个保障,因为内存管理器可能决定写回而不管文件缓存管理器怎样怎样。

如果文件系统希望阻止以等到cache map被清除,它可以提供一个事件(这个事件能被用来等待共享cache map的最后崩溃)。

这个例程对于所有文件对象都能被安全调用,尽管对于那些没有调用CcInitializeCacheMap的文件系统。

CcUnpinData

这个例程用来释放锁住的BCB块。原型:

          NTKERNELAPI VOID CcUnpinData (

               IN PVOID Bcb

               );

FSD每一个对于CcPinRead,CcPreparePinWrite, and CcPinMappedData 的调用,这个例程释放被锁的BCB块。当Bcb上的引用计数掉为0的时候,它能被缓存管理器释放掉,然后缓存管理器的这段地址空间就能被重用了。

CcUnpinDataForThread

这个例程用来允许一个线程,除了最初请求BCB的那个,来释放BCB里的ERESOURCE。原型:

         NTKERNELAPI VOID CcUnpinDataForThread (

               IN PVOID Bcb,

               IN ERESOURCE_THREAD ResourceThreadId

               );

CcUnpinRepinnedBcb

这个例程被FSD用来释放被调用了CcRepinBcb而锁住的BCB块。

         NTKERNELAPI VOID CcUnpinRepinnedBcb (

               IN PVOID Bcb,

               IN BOOLEAN WriteThrough,

               OUT PIO_STATUS_BLOCK IoStatus

               );

WriteThrough选项表明FSD是否愿意确保脏数据被写回磁盘在结束这个调用之前。如果WriteThrough是TRUE,那么在结束这个例程的时候,IoStatus将会被设置来表明任何写操作的结果。如果WriteThrough是FALSE,脏数据将会迟些被缓存管理器的Lazy Writer写回。

CcZeroData

这个例程被FSD用来保证内存中的一串被设为0.原型如下:

         NTKERNELAPI BOOLEAN CcZeroData (

               IN PFILE_OBJECT FileObject,

               IN PLARGE_INTEGER StartOffset,

               IN PLARGE_INTEGER EndOffset,

               IN BOOLEAN Wait

               );

典型地,FSD使用这个例程来清0新的数据区域,从而任何之前内存使用留下来的碎片被抹杀,对其它应用程序也不可用。

FileObject表明哪个文件要被清0,StartOffset和EndOffset表明文件里要被清0的范围。Wait参数表明调用者是否愿意等待当任何必须的同步对象被获得。

一般来讲,这个调用不会引起磁盘I/O.如果偏移不在页范围内,一个默认页会被激活来获得页,从而没被改变的页将会被正确的保存。更多地,如果FileObject表明文件正在被写语义打开,那么当页被清0的时候它们会被写回磁盘。

CcZeroEndOfLastPage

这个例程用来给这部分清0:文件的最后一页,最后一个有效字节到物理页的结束。原型如下:

         NTKERNELAPI VOID CcZeroEndOfLastPage(

               IN PFILE_OBJECT FileObject

               );

这个确保了如果文档被扩展,前面内存使用的数据变地不可访问。这个调用不常被FSD调用,只是为了完整性包进来而已。

FsRtlMdlReadCompleteDev

这个例程对文件系统过滤驱动很有用,因为它并不展示CcMdlReadComplete的重入行为,这可能在文件系统过滤驱动从它自己的MdlReadComplete快速I/O入口点返回FALSE的时候导致数据丢失。

         NTKERNELAPI BOOLEAN FsRtlMdlReadCompleteDev(

PFILE_OBJECT FileObject,

               PMDL MdlChain,

               PDEVICE_OBJECT DeviceObject

               );

这被证明是缓存管理器CcMdlReadComplete2的包装,与NT3.51里的CcMdlRadComplete有相同的语义。

注意这个调用在NT4.0 IFS kit里是没有地。

FsRtlMdlWriteCompleteDev

这个例程对文件系统过滤驱动很有用,因为它并不展示CcMdlWriteComplete的重入行为,这可能在文件系统过滤驱动从它自己的MdlReadComplete快速I/O入口点返回FALSE的时候导致数据丢失。

         NTKERNELAPI BOOLEAN FsRtlMdlWriteCompleteDev(

PFILE_OBJECT FileObject,

               PLARGE_INTEGER FileOffset,

               PMDL MdlChain,

               PDEVICE_OBJECT DeviceObject

               );

这被证明是缓存管理器CcMdlReadComplete2的包装,与NT3.51里的CcMdlRadComplete有相同的语义。

注意这个调用在NT4.0 IFS kit里是没有地。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值