📄 resrcsup.c
字号:
// Check here for the EA File. It turns out we need the normal
// resource shared in this case. Otherwise we take the paging
// I/O resource shared.
//
if (!ExAcquireResourceSharedLite( Fcb == ((PFCB)Fcb)->Vcb->EaFcb ?
((PFCB)Fcb)->Header.Resource :
((PFCB)Fcb)->Header.PagingIoResource,
Wait )) {
return FALSE;
}
//
// We assume the Lazy Writer only acquires this Fcb once.
// Therefore, it should be guaranteed that this flag is currently
// clear (the ASSERT), and then we will set this flag, to insure
// that the Lazy Writer will never try to advance Valid Data, and
// also not deadlock by trying to get the Fcb exclusive.
//
ASSERT( NodeType(((PFCB)Fcb)) == FAT_NTC_FCB );
ASSERT( ((PFCB)Fcb)->Specific.Fcb.LazyWriteThread == NULL );
((PFCB)Fcb)->Specific.Fcb.LazyWriteThread = PsGetCurrentThread();
ASSERT( NULL != PsGetCurrentThread() );
if (NULL == FatData.LazyWriteThread) {
FatData.LazyWriteThread = PsGetCurrentThread();
}
//
// This is a kludge because Cc is really the top level. When it
// enters the file system, we will think it is a resursive call
// and complete the request with hard errors or verify. It will
// then have to deal with them, somehow....
//
ASSERT(IoGetTopLevelIrp() == NULL);
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
return TRUE;
}
VOID
FatReleaseFcbFromLazyWrite (
IN PVOID Fcb
)
/*++
Routine Description:
The address of this routine is specified when creating a CacheMap for
a file. It is subsequently called by the Lazy Writer after its
performing lazy writes to the file.
Arguments:
Fcb - The Fcb which was specified as a context parameter for this
routine.
Return Value:
None
--*/
{
//
// Assert that this really is an fcb and that this thread really owns
// the lazy writer mark in the fcb.
//
ASSERT( NodeType(((PFCB)Fcb)) == FAT_NTC_FCB );
ASSERT( NULL != PsGetCurrentThread() );
ASSERT( ((PFCB)Fcb)->Specific.Fcb.LazyWriteThread == PsGetCurrentThread() );
//
// Release the lazy writer mark.
//
((PFCB)Fcb)->Specific.Fcb.LazyWriteThread = NULL;
//
// Check here for the EA File. It turns out we needed the normal
// resource shared in this case. Otherwise it was the PagingIoResource.
//
ExReleaseResourceLite( Fcb == ((PFCB)Fcb)->Vcb->EaFcb ?
((PFCB)Fcb)->Header.Resource :
((PFCB)Fcb)->Header.PagingIoResource );
//
// Clear the kludge at this point.
//
ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
IoSetTopLevelIrp( NULL );
return;
}
BOOLEAN
FatAcquireFcbForReadAhead (
IN PVOID Fcb,
IN BOOLEAN Wait
)
/*++
Routine Description:
The address of this routine is specified when creating a CacheMap for
a file. It is subsequently called by the Lazy Writer prior to its
performing read ahead to the file.
Arguments:
Fcb - The Fcb which was specified as a context parameter for this
routine.
Wait - TRUE if the caller is willing to block.
Return Value:
FALSE - if Wait was specified as FALSE and blocking would have
been required. The Fcb is not acquired.
TRUE - if the Fcb has been acquired
--*/
{
//
// We acquire the normal file resource shared here to synchronize
// correctly with purges.
//
if (!ExAcquireResourceSharedLite( ((PFCB)Fcb)->Header.Resource,
Wait )) {
return FALSE;
}
//
// This is a kludge because Cc is really the top level. We it
// enters the file system, we will think it is a resursive call
// and complete the request with hard errors or verify. It will
// have to deal with them, somehow....
//
ASSERT(IoGetTopLevelIrp() == NULL);
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
return TRUE;
}
VOID
FatReleaseFcbFromReadAhead (
IN PVOID Fcb
)
/*++
Routine Description:
The address of this routine is specified when creating a CacheMap for
a file. It is subsequently called by the Lazy Writer after its
read ahead.
Arguments:
Fcb - The Fcb which was specified as a context parameter for this
routine.
Return Value:
None
--*/
{
//
// Clear the kludge at this point.
//
ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
IoSetTopLevelIrp( NULL );
ExReleaseResourceLite( ((PFCB)Fcb)->Header.Resource );
return;
}
NTSTATUS
FatAcquireForCcFlush (
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject
)
{
PFCB Fcb;
PCCB Ccb;
PVCB Vcb;
PFSRTL_COMMON_FCB_HEADER Header;
TYPE_OF_OPEN Type;
//
// Once again, the hack for making this look like
// a recursive call if needed. We cannot let ourselves
// verify under something that has resources held.
//
// This value is good. We should never try to acquire
// the file this way underneath of the cache.
//
ASSERT( IoGetTopLevelIrp() != (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP );
if (IoGetTopLevelIrp() == NULL) {
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
}
//
// Time for some exposition.
//
// Lockorder for FAT is main->bcb->pagingio. Invert this at your obvious peril.
// The default logic for AcquireForCcFlush breaks this since in writethrough
// unpinrepinned we will grab the bcb then Mm will use the callback (which
// orders us with respect to the MmCollidedFlushEvent) to help us. If for
// directories/ea we then grab the main we are out of order.
//
// Fortunately, we do not need main. We only need paging - just look at the write
// path. This is basic pre-acquisition.
//
// Regular files require both resources, and are safe since we never pin them.
//
Type = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb );
Header = (PFSRTL_COMMON_FCB_HEADER) FileObject->FsContext;
if (Type < DirectoryFile) {
if (Header->Resource) {
if (!ExIsResourceAcquiredSharedLite( Header->Resource )) {
ExAcquireResourceExclusiveLite( Header->Resource, TRUE );
} else {
ExAcquireResourceSharedLite( Header->Resource, TRUE );
}
}
}
if (Header->PagingIoResource) {
ExAcquireResourceSharedLite( Header->PagingIoResource, TRUE );
}
return STATUS_SUCCESS;
}
NTSTATUS
FatReleaseForCcFlush (
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject
)
{
PFCB Fcb;
PCCB Ccb;
PVCB Vcb;
PFSRTL_COMMON_FCB_HEADER Header;
TYPE_OF_OPEN Type;
//
// Clear up our hint.
//
if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP) {
IoSetTopLevelIrp( NULL );
}
Type = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb );
Header = (PFSRTL_COMMON_FCB_HEADER) FileObject->FsContext;
if (Type < DirectoryFile) {
if (Header->Resource) {
ExReleaseResourceLite( Header->Resource );
}
}
if (Header->PagingIoResource) {
ExReleaseResourceLite( Header->PagingIoResource );
}
return STATUS_SUCCESS;
}
BOOLEAN
FatNoOpAcquire (
IN PVOID Fcb,
IN BOOLEAN Wait
)
/*++
Routine Description:
This routine does nothing.
Arguments:
Fcb - The Fcb/Dcb/Vcb which was specified as a context parameter for this
routine.
Wait - TRUE if the caller is willing to block.
Return Value:
TRUE
--*/
{
UNREFERENCED_PARAMETER( Fcb );
UNREFERENCED_PARAMETER( Wait );
//
// This is a kludge because Cc is really the top level. We it
// enters the file system, we will think it is a resursive call
// and complete the request with hard errors or verify. It will
// have to deal with them, somehow....
//
ASSERT(IoGetTopLevelIrp() == NULL);
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
return TRUE;
}
VOID
FatNoOpRelease (
IN PVOID Fcb
)
/*++
Routine Description:
This routine does nothing.
Arguments:
Fcb - The Fcb/Dcb/Vcb which was specified as a context parameter for this
routine.
Return Value:
None
--*/
{
//
// Clear the kludge at this point.
//
ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
IoSetTopLevelIrp( NULL );
UNREFERENCED_PARAMETER( Fcb );
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -