lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
阅读:7160回复:17

CcPurgeCacheSection清空cache求救

楼主#
更多 发布于:2007-01-04 23:48
在osronline看到如下代码,是用来清空cache的,但是测试之后发现有死锁,大侠指点指点该怎么做才能 解决死锁问题,谢谢!!
//for example :filename is  L"\\??\\E:\\test.txt";

BOOLEAN
PurgeFile (WCHAR * filename
    )
{
    UNICODE_STRING      fileNameUnicodeString;
    OBJECT_ATTRIBUTES   objectAttributes;
    PFILE_OBJECT        fileObject;
    HANDLE              ntFileHandle;
    PFSRTL_COMMON_FCB_HEADER Fcb;
    BOOLEAN result = TRUE, IoPagingRelease = FALSE,
                                     MainResRelease = FALSE;
    NTSTATUS status;
    IO_STATUS_BLOCK ioStatus;


     //Open file
     RtlInitUnicodeString( &fileNameUnicodeString, filename );

     InitializeObjectAttributes( &objectAttributes,

             &fileNameUnicodeString,
                                 OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile( &ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS,
                           &objectAttributes,
                           &ioStatus,
                           NULL,
                           0,
                           0,
                           FILE_OPEN,
                           FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE,
                           NULL, 0 );

    if( !NT_SUCCESS( status ) )
    {
        KdPrint(("sfilter!PurgeFile: !NT_SUCCESS( status )\n"));
        return FALSE;
    }

    // Find file-object it refers to
    KdPrint(("sfilter!PurgeFile: Find file-object it refers to\n"));
    status = ObReferenceObjectByHandle( ntFileHandle,
                                        FILE_READ_DATA,
                                        NULL,
                                        KernelMode,
                                        (PVOID*)&fileObject,
                                        NULL );
    if( !NT_SUCCESS( status )) {
        KdPrint(("sfilter!PurgeFile:  ZwClose( ntFileHandle );\n"));
        ZwClose( ntFileHandle );
        return FALSE;
    }

    Fcb = (PFSRTL_COMMON_FCB_HEADER)(fileObject->FsContext);
    if (Fcb==NULL)
    {
        KdPrint(("sfilter!PurgeFile:  Fcb==NULL\n"));
        return FALSE;
    }

    if (!ExAcquireResourceExclusive(Fcb->Resource, TRUE ))
    {
        KdPrint(("sfilter!PurgeFile: !ExAcquireResourceExclusive(Fcb->Resource, TRUE )\n"));
       result = FALSE;
    }
    else
    {
        MainResRelease = TRUE;
    }

    if (!ExAcquireResourceExclusive( Fcb->PagingIoResource , TRUE ))
               result = FALSE ;
    else IoPagingRelease = TRUE;
    //Yes,result must be TRUE
    KdPrint(("sfilter!PurgeFile: Yes,result must be TRUE\n"));
    if (result &&                      
        (fileObject->SectionObjectPointer->ImageSectionObject != NULL))
       if (!MmFlushImageSection(fileObject->SectionObjectPointer,
                                MmFlushForWrite ))
                                result = FALSE;
          if (result &&(fileObject->SectionObjectPointer->DataSectionObject != NULL))
          {
      //GOD!!!!!!!DeadLock occurs When Call CcPurgeCacheSection
               KdPrint(("sfilter!PurgeFile: GOD!!!!!!!DeadLock occurs When Call CcPurgeCacheSection\n"));
              if (!CcPurgeCacheSection( fileObject->SectionObjectPointer,
                                 NULL,
                                 0,
                                 FALSE )
                )
                  result = FALSE;
          }
       if (IoPagingRelease)
          ExReleaseResource(Fcb->PagingIoResource);
       if (MainResRelease)
          ExReleaseResource(Fcb->Resource);

   ZwClose( ntFileHandle );
   ObDereferenceObject( fileObject );

   KdPrint(("sfilter!PurgeFile: !success!!\n"));

  return result;
}

背景知识:
1)
CcPurgeCacheSection
The CcPurgeCacheSection routine purges all or a portion of a cached file from the system cache.
 

BOOLEAN
CcPurgeCacheSection(
IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
IN PLARGE_INTEGER FileOffset OPTIONAL,
IN ULONG Length,
IN BOOLEAN UninitializeCacheMaps
);
 

Parameters
SectionObjectPointer
Pointer to a structure containing the file object's section object pointers.
FileOffset
Pointer to a variable that specifies the starting byte offset within the cached file where the data is to be purged.
If FileOffset is NULL, the entire file is purged from the cache.

If FileOffset is not NULL, only the byte range specified by FileOffset and Length is purged.

Length
Length of the byte range to purge, starting at FileOffset. If Length is zero, the range from FileOffset to the end of the file is purged. If FileOffset is NULL, Length is ignored.
UninitializeCacheMaps
Set to TRUE to uninitialize any private cache maps for the file before purging the file data.
Headers
Declared in ntifs.h. Include ntifs.h.

Return Value
CcPurgeCacheSection returns TRUE if the cached file data was successfully purged, FALSE otherwise.

Comments
File systems call CcPurgeCacheSection to purge stale data from the cache. For example, when a file is truncated but not deleted, CcPurgeCacheSection should be called to purge any cached data that is no longer part of the file.

CcPurgeCacheSection will not purge mapped files.

Before calling CcPurgeCacheSection, the caller must acquire the file exclusively and ensure that no thread, including the caller, has mapped or pinned any byte range in the file.

Callers of CcPurgeCacheSection must be running at IRQL < DISPATCH_LEVEL.
 

2)
about Purge the file cache
I have read A notes:
>This works for me:

>1. Lock the FCB Resource exclusive (after checking for non-NULL).
>2. Lock the FCB PagingIoResource exclusive (after checking for non-NULL
>and in a polling loop to prevent deadlocks, since different filesystems
>will apparently acquire these two locks in different orders).
>3. If fobj->SectionObjectPointer is non-NULL then:
>3a. do a CcFlushCache for the entire file
>3b. do a MmFlushImageSection for write if
>fobj->SectionObjectPointer->ImageSectionObject is
>non-NULL
<...excess quoted lines suppressed...>
I according to it,make the code below,but It will deadlock when calling
CcPurgeCacheSection.
God,it puzzled me.please help me.
If your code can work fine,please...thanks you very much.
perhaps,the reason is I don't understand the sentence:
>and in a polling loop to prevent deadlocks, since different filesystems
>will apparently acquire these two locks in different orders

this is my code,the function is used at IRP_MJ_CREATE dispatch and
IRP_MJ_CLOSE dispatch routine.ah,I filter it.
Addtional,In my code,when I filter the Paging Read/Write,I roll a IRP to
below device(Query file name).
Yes,sometimes deadlock when calling CcPurgeCacheSection.
when I delete the code about rolling a IRP to Query file name,That's
OK(perhaps,I just can't find deadlock in test for a long period).
But I'm not sure that's key.
OK,this is my code:

最新喜欢:

linshierlinshi... snoxsnox
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
沙发#
发布于:2007-01-05 00:11
osronline上几位牛人的回答,但小牛愚笨,不太理解,牛牛们发发话,指点指点,最好能把这个函数做得比较通用.

1)Alexei Jelvis

When you get a deadlock you need to check what the current thread is waiting
for and find the other thread that is holding this resource. You can use
!locks command to enumerate all locks that are acquired in the system and
check if there is a loop in waiting threads. Alternatively, you can dump all
threads using !process 0 7 and check if there are threads in which you
filter is on the stack. If there is such thread you need to check if it is
holding the resource the first thread is waiting for.
I would suggest not to query name at paging io dispatch routine. When paging
IO occurs some resources are already acquired and sending query information
IRP may cause a deadlock. Hodling paging IO will cause CcPurgeCacheSection
to wait.
Also calling this function from IRP_MJ_CLOSE dispatch routine is not a good
idea. This IRP comes when ObDereferenceObject is invoked which may happen
when arbitrary set of resources is acquired by the calling thread.
IRP_MJ_CLOSE may be generated from CcPurgeCacheSection so it is also
potential cause of deadlock.
I would suggest not to query name at paging io dispatch routine. When paging
IO occurs some resources are already acquired and sending query information
IRP may cause a deadlock. Hodling paging IO will cause CcPurgeCacheSection
to wait.
Also calling this function from IRP_MJ_CLOSE dispatch routine is not a good
idea. This IRP comes when ObDereferenceObject is invoked which may happen
when arbitrary set of resources is acquired by the calling thread.
IRP_MJ_CLOSE may be generated from CcPurgeCacheSection so it is also
potential cause of deadlock.

Alexei.

2)Nick Ryan (MVP for DDK)

Resources can be acquired recursively by the same thread as described in
the DDK docs for the ExAcquire* functions. The deadlock comes when you
try to acquire main and paging in one order, while the FSD may try to
take them in the reverse order in another thread. You can prevent a
deadlock here by take one lock, then testing if the other is currently
held. If no, take it, and you've got both locks. If yes, release the
first lock, pause for 50 ms or so, and repeat.
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
板凳#
发布于:2007-03-08 09:16
根据最后一句解释,写了如下代码,:-) :
BOOLEAN
ffdrv_puge_file_cache(PFILE_OBJECT FileObject)
{
    PFSRTL_COMMON_FCB_HEADER Fcb = NULL;
    LARGE_INTEGER Interval = {0};
    BOOLEAN result = TRUE,
        IoPagingRelease = FALSE,
        MainResRelease = FALSE;

    Fcb = (PFSRTL_COMMON_FCB_HEADER)(FileObject->FsContext);
    if(Fcb == NULL) {
        return FALSE;
    }
    Interval.QuadPart = -1 * (LONGLONG)50;
    
    for(; (Fcb->Resource != NULL) || (Fcb->PagingIoResource != NULL); ) {

        if( (Fcb->Resource == NULL) ||
            ExAcquireResourceExclusive(Fcb->Resource, TRUE) ) {
            MainResRelease = TRUE;
        }
        else {
            MainResRelease = FALSE;
        }
        if(Fcb->PagingIoResource != NULL) {
            if( !( (Fcb->PagingIoResource->Flag & ResourceOwnedExclusive) &&
                (Fcb->PagingIoResource->OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread()) ) ) {
                
                if( ExAcquireResourceExclusive(Fcb->PagingIoResource, TRUE) ) {
                    IoPagingRelease = TRUE;
                }
                else {
                    IoPagingRelease = FALSE;
                }
            }
        }
        else {
            IoPagingRelease = TRUE;
        }
        if(MainResRelease && IoPagingRelease) {
            break;
        }
        if(Fcb->Resource != NULL) {
            ExReleaseResource(Fcb->Resource);
        }
        MainResRelease = FALSE;

        KeDelayExecutionThread(KernelMode, FALSE, &Interval);
    }
    if( FileObject->SectionObjectPointer->DataSectionObject != NULL ) {        
        result = CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
    }
    if(IoPagingRelease && Fcb->PagingIoResource != NULL) {
        ExReleaseResource(Fcb->PagingIoResource);
    }    
    if(MainResRelease && Fcb->Resource != NULL) {
        ExReleaseResource(Fcb->Resource);
    }
    return result;
}
人总在矛盾中徘徊。。。
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
地板#
发布于:2007-03-08 09:43
大家可以验证一下执行后FILE_OBJECT的SectionObjectPointe的内容。
人总在矛盾中徘徊。。。
yaolixing
驱动小牛
驱动小牛
  • 注册日期2006-06-27
  • 最后登录2010-07-15
  • 粉丝1
  • 关注0
  • 积分991分
  • 威望135点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-03-08 15:18
这样的代码无法清除内存映射的缓存,它缺少一条关键的代码,纵然解决了死锁也枉然。
我最老实
驱动小牛
驱动小牛
  • 注册日期2005-09-11
  • 最后登录2010-01-27
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望253点
  • 贡献值0点
  • 好评度189点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-03-09 13:22
引用第4楼yaolixing2007-03-08 15:18发表的“”:
这样的代码无法清除内存映射的缓存,它缺少一条关键的代码,纵然解决了死锁也枉然。




If there are no mapped views of the image section。
MmFlushImageSection destroys the image section and returns any used pages to the free list. 所以首先要将已有的Mapped section unmap!
养牛专业户
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
6楼#
发布于:2007-03-09 15:51
俺只是简单翻译,批判就是最大的进步,:-)
人总在矛盾中徘徊。。。
lancelet
驱动牛犊
驱动牛犊
  • 注册日期2006-01-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分420分
  • 威望43点
  • 贡献值0点
  • 好评度42点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-03-10 14:58
先谢谢楼上的

文档上说CcPurgeCacheSection will not purge mapped files,要如何解决
lancelet
驱动牛犊
驱动牛犊
  • 注册日期2006-01-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分420分
  • 威望43点
  • 贡献值0点
  • 好评度42点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-03-10 18:41
我写了一个函数,不知对否?贴出来给大家看看。
还有请问yaolixing,要清除内存映射的缓存,是不是要调用MmFlushImageSection(pFileObject->SectionObjectPointer, MmFlushForDelete);
注意还没测过。

void ManageFileCache(PFILE_OBJECT pFileObject, BOOL bClearOrFlush)
{
    PFSRTL_COMMON_FCB_HEADER pFcb;
    LARGE_INTEGER liInterval;
    BOOL bNeedReleaseResource = FALSE;
    BOOL bNeedReleasePagingIoResource = FALSE;
    KIRQL irql;

    pFcb = (PFSRTL_COMMON_FCB_HEADER)pFileObject->FsContext;
    if(pFcb == NULL)
    {
        return;
    }

    irql = KeGetCurrentIrql();
    if (irql >= DISPATCH_LEVEL)
    {
        return;
    }

    liInterval.QuadPart = -1 * (LONGLONG)50;

    while (TRUE)
    {
        BOOL bBreak = TRUE;
        BOOL bLockedResource = FALSE;
        BOOL bLockedPagingIoResource = FALSE;
        bNeedReleaseResource = FALSE;
        bNeedReleasePagingIoResource = FALSE;

        if (pFcb->PagingIoResource)
        {
            bLockedPagingIoResource = ExIsResourceAcquiredExclusiveLite(pFcb->PagingIoResource);
        }

        if (pFcb->Resource)
        {
            bLockedResource = TRUE;
            if (ExIsResourceAcquiredExclusiveLite(pFcb->Resource) == FALSE)
            {
                bNeedReleaseResource = TRUE;
                if (bLockedPagingIoResource)
                {
                    if (ExAcquireResourceExclusiveLite(pFcb->Resource, FALSE) == FALSE)
                    {
                        bBreak = FALSE;
                        bNeedReleaseResource = FALSE;
                        bLockedResource = FALSE;
                    }
                }
                else
                {
                    ExAcquireResourceExclusiveLite(pFcb->Resource, TRUE);
                }
            }
        }
    
        //if (bBreak)
        if (bLockedPagingIoResource == FALSE)
        {
            if (pFcb->PagingIoResource)
            {
                bLockedPagingIoResource = TRUE;
                bNeedReleasePagingIoResource = TRUE;
                if (bLockedResource)
                {
                    if (ExAcquireResourceExclusiveLite(pFcb->PagingIoResource, FALSE) == FALSE)
                    {
                        bBreak = FALSE;
                        bLockedPagingIoResource = FALSE;
                        bNeedReleasePagingIoResource = FALSE;
                    }
                }
                else
                {
                    ExAcquireResourceExclusiveLite(pFcb->PagingIoResource, TRUE);
                }
            }
        }

        if (bBreak)
        {
            break;
        }
        
        if (bNeedReleasePagingIoResource)
        {
            ExReleaseResourceLite(pFcb->PagingIoResource);
        }
        if (bNeedReleaseResource)
        {
            ExReleaseResourceLite(pFcb->Resource);
        }

        if (irql == PASSIVE_LEVEL)
        {
            KeDelayExecutionThread(KernelMode, FALSE, &liInterval);
        }
        else
        {
            KEVENT waitEvent;
            KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
            KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, &liInterval);
        }
    }

    //加锁完毕
    if (pFileObject->SectionObjectPointer)
    {
        if (bClearOrFlush == FALSE)
        {
            IO_STATUS_BLOCK ioStatus;
            CcFlushCache(pFileObject->SectionObjectPointer, NULL, 0, &ioStatus);
            if (pFileObject->SectionObjectPointer->ImageSectionObject)
            {
                MmFlushImageSection(pFileObject->SectionObjectPointer, MmFlushForWrite);//MmFlushForDelete
            }
        }
        CcPurgeCacheSection(pFileObject->SectionObjectPointer, NULL, 0, FALSE);
    }

    if (bNeedReleasePagingIoResource)
    {
        ExReleaseResourceLite(pFcb->PagingIoResource);
    }
    if (bNeedReleaseResource)
    {
        ExReleaseResourceLite(pFcb->Resource);
    }
}
coolw
驱动牛犊
驱动牛犊
  • 注册日期2006-03-20
  • 最后登录2012-04-13
  • 粉丝0
  • 关注0
  • 积分521分
  • 威望65点
  • 贡献值0点
  • 好评度54点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-03-13 16:43
1 CcFlushCache
2 MmFlushImageSection
3 CcPurgeCacheSection
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
10楼#
发布于:2007-03-23 13:58
这个函数可以用的,基本上尝试一两次就可以获lock

sfilter!SfRead: Decrypt 开始读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始解密文件头 E:\lsx\fff.txt CompletionCtx->Length = 4096  IrpSp->Parameters.Read.ByteOffset.LowPart = 0
sfilter!SfRead: 发现加密标记   Decrypt E:\lsx\fff.txt  
SFilter!SioctlDeviceControl 解压前长度 UnCompressDataLen = 38
SFilter!SioctlDeviceControl 解压后长度 UnCompressDataLen = 509
lsx KeClearEvent gpEventDeCode sussfully!
sfilter!SfRead: 解压成功 Decrypt E:\lsx\fff.txt  UnCompressData = 1111112sd1111111111123sdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd11111112sd1111111111123sdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd11111112sd1111111111123sdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd11111112sd1111111111123sdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
sfilter!SfRead: Decrypt 结束读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始解密文件头 E:\lsx\fff.txt CompletionCtx->Length = 20480  IrpSp->Parameters.Read.ByteOffset.LowPart = 4096
sfilter!SfRead: Decrypt 结束读新的IRP包 E:\lsx\fff.txt
sfilter!SfClose: 开始关闭  E:\lsx\fff.txt
sfilter!SfClose: 开始清空cache  
sfilter!ffdrv_puge_file_cache 失败
sfilter!SfWrite: Encrypt 开始写新的IRP包 E:\lsx\fff.txt
lsx UnCompressWaitEvent sussfully!
SFilter!SioctlDeviceControl 压缩前长度 CompressDataLen = 509
SFilter!SioctlDeviceControl 压缩后长度 CompressDataLen = 38
lsx KeClearEvent gpEventObject sussfully!
sfilter!SfWrite: 开始添加加密标记 Encrypt E:\lsx\fff.txt need compress!  
sfilter!SfWrite: Encrypt 加密文件头成功 E:\lsx\fff.txt Length = 24576  IrpSp->Parameters.Read.ByteOffset.LowPart = 0
sfilter!SfWrite: Encrypt 结束写新的IRP包 E:\lsx\fff.txt
lsx CompressWaitEvent sussfully!
sfilter!ffdrv_puge_file_cache 成功
sfilter!SfRead: Decrypt 开始读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始解密文件头 E:\lsx\fff.txt CompletionCtx->Length = 4096  IrpSp->Parameters.Read.ByteOffset.LowPart = 0
sfilter!SfRead: Decrypt 结束读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始解密文件头 E:\lsx\fff.txt CompletionCtx->Length = 20480  IrpSp->Parameters.Read.ByteOffset.LowPart = 4096
sfilter!SfRead: Decrypt 结束读新的IRP包 E:\lsx\fff.txt
sfilter!SfClose: 开始关闭  E:\lsx\fff.txt
sfilter!SfClose: 开始清空cache  
sfilter!ffdrv_puge_file_cache 失败
sfilter!ffdrv_puge_file_cache 成功
sfilter!SfRead: Decrypt 开始读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始解密文件头 E:\lsx\fff.txt CompletionCtx->Length = 4096  IrpSp->Parameters.Read.ByteOffset.LowPart = 0
sfilter!SfRead: Decrypt 结束读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始读新的IRP包 E:\lsx\fff.txt
sfilter!SfRead: Decrypt 开始解密文件头 E:\lsx\fff.txt CompletionCtx->
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
11楼#
发布于:2007-03-23 16:23
void ManageFileCache(PFILE_OBJECT pFileObject, BOOL bClearOrFlush)
符合下面的流程

OK the previous message got completely garbled, let's have another go at
it:

This works for me:

1. Lock the FCB Resource exclusive (after checking for non-NULL).
2. Lock the FCB PagingIoResource exclusive (after checking for non-NULL
and in a polling loop to prevent deadlocks, since different filesystems
will apparently acquire these two locks in different orders).
3. If fobj->SectionObjectPointer is non-NULL then:
    3a. do a CcFlushCache for the entire file
    3b. do a MmFlushImageSection for write if
        fobj->SectionObjectPointer->ImageSectionObject is
non-NULL
    3c. do a CcPurgeCacheSection (last param FALSE) if
        fobj->SectionObjectPointer->DataSectionObject is
non-NULL
4. Unlock the FCB PagingIoResource if you locked it.
5. Unlock the FCB Resource if you locked it.
lancelet
驱动牛犊
驱动牛犊
  • 注册日期2006-01-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分420分
  • 威望43点
  • 贡献值0点
  • 好评度42点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-03-24 09:31
你确信可以用?
我在IRP_MJ_CLOSE中调用还是会死锁。好象除非我不加锁,要不然都有死锁的可能。
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
13楼#
发布于:2007-03-24 15:16
我也是 在IRP_MJ_CLOSE中调用的,不过我不是对所有的close历程都做处理,只是对加密过的文件处理,目前测试过的没有出现过死锁的现象.
luckyshow00
驱动牛犊
驱动牛犊
  • 注册日期2007-03-12
  • 最后登录2008-11-24
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望36点
  • 贡献值0点
  • 好评度34点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-03-26 22:41
我也是 在IRP_MJ_CLOSE中调用,只是对加密过的文件处理
void ManageFileCache(PFILE_OBJECT pFileObject, BOOL bClearOrFlush)
BOOLEAN
ffdrv_puge_file_cache(PFILE_OBJECT FileObject)
这两个,我都试过了,都会deadlock
不知道是哪儿的问题,晕...我是xp,ntfs
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
15楼#
发布于:2007-03-27 08:28
不加锁
qianjunhua
驱动小牛
驱动小牛
  • 注册日期2003-12-08
  • 最后登录2013-02-27
  • 粉丝11
  • 关注0
  • 积分712分
  • 威望1052点
  • 贡献值1点
  • 好评度57点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2007-07-23 17:39
CcPurgeCacheSection 请问一下 这个函数会不会在通过pageio的形式来请求pFcb->PagingIoResource啊?如果是的话,在前面已经取到了这个lock,那后面的acquire肯定会deadlock了吧
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2007-07-23 18:17
咱们处理的nocache,应该不会deadlock出现,只要在前面判断一下是否是自己的加解密文件即可,我也测试过上面的代码,ok的。。。
游客

返回顶部