zzq191
驱动中牛
驱动中牛
  • 注册日期2001-08-09
  • 最后登录2018-05-29
  • 粉丝17
  • 关注0
  • 积分1041分
  • 威望716点
  • 贡献值0点
  • 好评度318点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1893回复:9

请教CcPinRead问题

楼主#
更多 发布于:2007-08-08 11:13
在使用CcPinRead时,这个函数和CcUnpinData是对应的,现在的问题是对同一个FileObject,调用CcPinRead可以嵌套吗?
也就是能按这个顺序调用吗?
1.CcPinRead
2.CcPinRead/CcMapData
3.CcSetDirtyPinnedData第2步的CcPinRead
4.CcSetDirtyPinnedData第1步的CcPinRead
5.CcUnpinData第2步
6.CcUnpinData第1步

还是步能嵌套必须一对一的调用,即
1.CcPinRead
2.CcSetDirtyPinnedData
3.CcUnpinData
4.CcPinRead/CcMapData
5.CcSetDirtyPinnedData
6.CcUnpinData

以上如果是CcMapData则不调用CcSetDirtyPinnedData

还有我重新设置了FileSize,并且新设置的长度大于原来的长度,但调用CcPinRead时不会触发出Read的irp,也就是得到的还是老的cache中的数据,新的数据不会更新到cache中,为什么?

我查了一天,就是看不出原因!
QQ:416331891,承接windows下应用和驱动的开发,雅虎通:zzq191, Email:zzq191@21cn.com
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-08-09 11:36
顶你个成长中的高手
zzq191
驱动中牛
驱动中牛
  • 注册日期2001-08-09
  • 最后登录2018-05-29
  • 粉丝17
  • 关注0
  • 积分1041分
  • 威望716点
  • 贡献值0点
  • 好评度318点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2007-08-10 11:00
自己顶一下
QQ:416331891,承接windows下应用和驱动的开发,雅虎通:zzq191, Email:zzq191@21cn.com
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
地板#
发布于:2007-08-10 15:00
Cache的四个接口
\begin{itemize}
\item File Stream Manipulation Functions
\item Copy Interface
\item MDL Interface
\item Pinning Interface
\end{itemize}
注意:Cache管理器的Pin接口和另外两个接口:Copy接口以及MDL接口不能
同时使用。

重要:Cache管理器并解释被缓存的数据内容,它只是理解File Object以及
相关的Stream对象。

Cache管理器的客户类型:文件系统驱动、过滤器驱动、网络文件重
定向器、网络文件服务器。

HSM:Hierarchical Storage Management。

FILE\_OBJECT中大部分字段是由IO管理器负责维护,但有几个例外:
FsContext指向一个CommonFCBHeader结构,简称FCB,也就是Unix系统
中的vnode结构,或许就是DOS下的FCB。注意FILE\_OBJECT是Per
handle的,而FCB则是per file stream的。

一个重要的结构:
\begin{verbatim}
//
// The following structure is pointed to by the SectionObject
// pointer field
// of a file object, and is allocated by the various NT file systems.
//

typedef struct _SECTION_OBJECT_POINTERS {
    PVOID DataSectionObject;
    PVOID SharedCacheMap;
    PVOID ImageSectionObject;
} SECTION_OBJECT_POINTERS; typedef SECTION_OBJECT_POINTERS
*PSECTION_OBJECT_POINTERS;
\end{verbatim}
和FCB一样,这也是一个per file stream的对象,其三个成员都是
Cache管理器的私有结构,甚至在IFSKits中都没有公开。
\section{Cache Map}
一个复杂的对象,结构未知!

理解Cache子系统的关键在于了解Io管理器、文件系统、Cache管理器、
Memory管理器之间的关系,用户读写文件时首先经过Io管理器,Io管
理器视情况而定可能会直接向文件系统发出请求,也可能绕过文件系统
直接和Cache管理器打交道,对于后者来说,Cache管理器将利用Memory
管理器的功能实现数据的读写----事实上只是一个简单的拷贝。

问题:如果Io管理器向文件系统发出请求,那么是不是文件系统(在做了必要
的初始化工作之后)一定会回头调用Cache管理器?

\section{Virtual Address Control Block}
Cache管理器为每个File
Stream开了一个或者多个窗口,每个窗口的大小都是固定的,
记得是256KB。这些窗口用VACB来管理。

看上去Private Cache Map只是为了将同一个File Stream的多个File
Object串起来, 因为Cache管理器为了Unmap一个VACB,必须通知每个
File Object,所以这样一个 链表是有必要的。

Cache Manager的Fast IO看上去是NT的开发小组在最后时刻发现系统
性能问题后草草设计出来的,虽然现在这个接口已经发展的很成熟了,
但总的来说还是有些不好理解。

每个Handle都必须调用Cache管理器初始化缓存。

文件系统提供给Cache管理器的回调接口倒是很简单:
\begin{verbatim}
typedef struct _CACHE_MANAGER_CALLBACKS {
    PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite;
    PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite;
    PACQUIRE_FOR_READ_AHEAD AcquireForReadAhead;
    PRELEASE_FROM_READ_AHEAD ReleaseFromReadAhead;
} CACHE_MANAGER_CALLBACKS, *PCACHE_MANAGER_CALLBACKS

初始化CacheMap:
void CcInitializeCacheMap (
    IN PFILE_OBJECT PtrFileObject,
    IN PCC_FILE_SIZES FileSizes,
    IN BOOLEAN PinAccess,
    IN PCACHE_MANAGER_CALLBACKS CallBacks,
    IN PVOID LazyWriterContext
);
\end{verbatim}
LazyWrite和ReadAhead是Cache管理器完成的,但是Cache管理器在
执行这些任务时,必须获得文件系统的支持,上面的Callback参数
就是文件系统提供给Cache管理器的许可证,Cache管理器会在
LazyWrite和ReadAhead的时候调用这些回调函数。这些回调的主要
任务通常是同步。

LazyWriterContext这个名字取的不好,实际上这个参数同时用作
LazyWriter和ReadAhead的上下文参数,通常这个参数就是Context
Control Block,一个和File Object并列的对象,不过后者是Io
管理器创建的而CCB则是文件系统创建的,另外,通常这个指针会
保存在FileObject对象的Context2字段中,这应该算是一种文化
了吧我想。

注意这个函数没有返回值,调用者必须作好准备接受任何可能产生
的例外。

\section{Copy接口}
文件系统在处理Read请求时,可以调用Cache管理器的Copy接口,
如果要copy的数据不在物理内存中,则会产生页面错误,将由
Memory Manager调用文件系统将数据从外设(磁盘或者网络服
务器)拷贝到物理内存中,也就是说,文件系统将被递归的调用。

写数据的时候也可能会需要等待,如果写的内容不是硬件扇区
对齐的,则可能需要执行读操作,这样就有可能造成Blocking;
另外写数据需要空闲物理内存页面,如果没有的话则需要执行
LazyWrite并分配新的内存,这也会造成阻塞。

\emph{CcCanIWrite}\\
这个函数很有意思,由于在Write接口中的函数有可能会由于空闲
页面不足(即Dirty Page过多)造成等待,所以可以用这个函数
测试一下当前能否执行不阻塞的写操作,这个测试是建议性的,
如果测试完了立刻有个别的家伙又写了一堆东西,则随后的写操作
可能还是会阻塞,不过由于这个竞争情况不会影响程序的正确性,
只是会导致阻塞,所以通常不需要关心。

\emph{CcDeferWrite}\\
请求Cache管理器调度一个事件,在能够进行写操作的时候执行
一个回调,通常就是文件系统的写入口函数。

\section{Pin接口}
和Copy接口不同,Copy接口始终是使用FileObject和Offset来
寻址Cache管理器管理的内存,而不是直接用指针,而Pin接口
则提供了Pin功能,这样文件系统就可以把Cache管理器管理的
内存'钉'在内存里,随后就可以用指针来寻址了。

Pin需要经过两个步骤:Map、Pin。
CcMapData\\
CcPinMappedData\\
CcPinRead\\
CcSetDirtyPinnedData\\
CcPreparePinWrite\\
提供这个函数可以认为是一种优化措施,和CcPinRead相比,如果
参数中指定的区域刚好在Page边界上,则Cache管理器不会从二级
存储器中读入该页,因此这个函数返回的缓冲区不能用来读取数据。

CcUnpinData/CcUnPinDataForThread。

注意在Pin期间,在调用者线程上下文中不会有IO发生,所有的IO
都是异步的。
\section{MDL接口}
CcMdlRead\\
CcMdlReadComplete\\
CcPrepareMdlWrite\\
CcMdlWriteComplete\\
CcMdlRead和CcPrepareMdlWrite会返回一个MDL链表,这个链表在
对应的Complete函数中释放,所以这两对函数必须成对调用,以
避免内存泄漏。
\section{Cache管理器和VMM的交互}
初始化CacheMap时调用MmCreateSection,扩展文件流时调用
MmExtendSection。

这里有很多在DDK中都没有公开的函数,倒是作为系统服务导出给
ntdll了,例如MmCreateSection大致等于ZwCreateSection。

从工作集管理上看,Cache管理器对VMM来说是一个普通的客户,
即它和普通进程一样,其Working Set要经过VMM的修剪。
\section{预读取模块}
\section{后写模块}
\chapter{文件子系统}
文件系统不能区分两种请求,一种是应用程序调用产生的读写
请求,一种是由于Cache管理器进行Copy时的页面故障导致VMM向
文件系统发出的读写请求。
\section{几种重要的同步对象}
\begin{itemize}
\item FSD锁(MainResource)
\item PagingIoResource
\item 和文件流相关的字节范围锁
\item 机会锁(oplock)
\end{itemize}



[返回顶部]


--------------------------------------------------------------------------------

2004-04-22 20:21:59

主题: 内核对象和执行体对象


内核和执行体具有一些同名对象,例如Event、Mutant、Process、Thread等,
通常的说法是执行体对象是对零个或者多个内核对象的封装,这个说法不妨
可以再直白一些:
\begin{verbatim}
class EPROCESS :
    public KPROCESS,
    public OBJECT_HEADER
{
};
class KPROCESS :
    public DISPATCHER_HEADER
{
};
\end{verbatim}
写成这样,为什么说Windows的进程对象(以及线程对象,道理类似)都是
可以等待的,应该就很清楚了吧:因为它继承了DISPATCH\_HEADER对象,而
后者正是实现可等待对象(用Windows自己的话,大概应该叫`可调度对象'吧)
的关键。

也就是说,在一个执行体进程对象中,包含了一个用来给内核管理用的
KPROCESS对象,一个用来使进程对象能够参与同步的DISPATCHER\_HEADER
头部对象,和一个给对象管理器用来实施管理的OBJECT\_HEADER结构。
其它执行体对象,例如Event、FileObject等都可以进行类似分析。
oyclkelly
驱动牛犊
驱动牛犊
  • 注册日期2006-06-07
  • 最后登录2009-07-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-08-10 17:20
lsxredrain兄,你是一个负责任,乐于助人的人
这个坛子,向你这样的朋友不多了
zzq191
驱动中牛
驱动中牛
  • 注册日期2001-08-09
  • 最后登录2018-05-29
  • 粉丝17
  • 关注0
  • 积分1041分
  • 威望716点
  • 贡献值0点
  • 好评度318点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2007-08-10 18:39
增加了FsRtlEnterFileSystem/FsRtlExitFileSystem就好了
可能没有加这个时执行中途被交换出去了
QQ:416331891,承接windows下应用和驱动的开发,雅虎通:zzq191, Email:zzq191@21cn.com
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
6楼#
发布于:2007-08-10 19:06
恭喜 恭喜,
http://www.pyrasis.com
这 个网 站上有 一个 开源的 文件 系统 项目,
可以 参考 参考 他们的代码
zzq191
驱动中牛
驱动中牛
  • 注册日期2001-08-09
  • 最后登录2018-05-29
  • 粉丝17
  • 关注0
  • 积分1041分
  • 威望716点
  • 贡献值0点
  • 好评度318点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2007-08-10 20:15
他这个是文件过滤驱动?
QQ:416331891,承接windows下应用和驱动的开发,雅虎通:zzq191, Email:zzq191@21cn.com
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
8楼#
发布于:2007-08-10 22:04
好象不是过滤驱动,是文件系统,
zzq191
驱动中牛
驱动中牛
  • 注册日期2001-08-09
  • 最后登录2018-05-29
  • 粉丝17
  • 关注0
  • 积分1041分
  • 威望716点
  • 贡献值0点
  • 好评度318点
  • 原创分0分
  • 专家分0分
  • 社区居民
9楼#
发布于:2007-08-11 16:34
那看fastfat的源代码一样的
QQ:416331891,承接windows下应用和驱动的开发,雅虎通:zzq191, Email:zzq191@21cn.com
游客

返回顶部