📄 datastore.c
字号:
}
return status;;
}
NTSTATUS
FmmSetMetadataOpenTriggerFileObject (
__inout PFLT_CALLBACK_DATA Cbd
)
/*++
Routine Description:
This routine sets the MetadataOpenTriggerFileObject in the instance context
to the file object of the volume that triggered the release of the metadata file
references.
Arguments:
Cbd - Supplies a pointer to the callbackData which
declares the requested operation.
Return Value:
Status
Note:
This routine takes care of the synchronization needed to access the metadata
file object and handle
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PFMM_INSTANCE_CONTEXT instanceContext = NULL;
PAGED_CODE();
//
// Get the instance context
//
status = FltGetInstanceContext( Cbd->Iopb->TargetInstance,
&instanceContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmSetMetadataOpenTriggerFileObject -> Failed to get instance context.\n") );
goto FmmSetMetadataOpenTriggerFileObjectCleanup;
}
//
// Acquire exclusive access to the instance context
//
FmmAcquireResourceExclusive( &instanceContext->MetadataResouce );
if (FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION)) {
//
// If this instance context is in a transition state, it implies that
// the instance context lock has been released while sending an operation
// down to the file system. The reason for doing so is to prevent a potential
// deadlock if an underlying filter sends an IO to the top of the filter
// stack while we are holding the resource
//
// We have managed to acquire this resource in this state of transition.
// It would be incorrect to use or modify the instance context in any way
// in this situation. So we simply let go.
//
status = STATUS_FILE_LOCK_CONFLICT;
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmSetMetadataOpenTriggerFileObject -> Failed to get exclusive access to instance context since it is in a state of transition.\n") );
} else {
DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmSetMetadataOpenTriggerFileObject -> Setting MetadataOpenTriggerFileObject to %p (OldValue = %p).\n",
Cbd->Iopb->TargetFileObject,
instanceContext->MetadataOpenTriggerFileObject) );
//
// Save the volume file object as the trigger file object
//
ASSERT((instanceContext->MetadataOpenTriggerFileObject == NULL) ||
(instanceContext->MetadataOpenTriggerFileObject = Cbd->Iopb->TargetFileObject));
instanceContext->MetadataOpenTriggerFileObject = Cbd->Iopb->TargetFileObject;
}
//
// Relinquish exclusive access to the instance context
//
FmmReleaseResource( &instanceContext->MetadataResouce);
FmmSetMetadataOpenTriggerFileObjectCleanup:
//
// Release the references we have acquired
//
if (instanceContext != NULL) {
FltReleaseContext( instanceContext );
}
return status;;
}
FORCEINLINE
VOID
FmmBeginFileSystemOperation (
IN PFMM_INSTANCE_CONTEXT InstanceContext
)
/*++
Routine Description:
This routine must be called before the filter performs a file system operation
if it is holding an exclusive lock to the instance context resource at the
time it needs to perform the file system operation
Arguments:
InstanceContext - Supplies the instance context for this instance.
Return Value:
Returns the status of this operation.
Note:
The caller must hold the instance context resource exclusive when this routine is called.
--*/
{
PAGED_CODE();
//
// Release the instance context lock before sending an operation down to the
// file system. The reason for doing so is to prevent a potential deadlock if
// an underlying filter sends an IO to the top of the filter stack while we
// are holding the resource
//
// Before we release the lock we mark the instance context to indicate it is
// in a transition state. Any other thread that finds the instance context in a
// transition state will not use or modify the instance context
//
// This thread can however continue to use/modify the instance context since it
// is guaranteed exclusive access. Other threads that see the instance context
// in a transition state will not use or modify the context
//
ASSERT( !FlagOn( InstanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION ) );
SetFlag( InstanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION );
//
// Relinquish exclusive access to the instance context
//
FmmReleaseResource( &InstanceContext->MetadataResouce);
}
FORCEINLINE
VOID
FmmEndFileSystemOperation (
IN PFMM_INSTANCE_CONTEXT InstanceContext
)
/*++
Routine Description:
This routine must be called after the filter performs a file system operation
if it was holding an exclusive lock to the instance context resource at the
time it needed to perform the file system operation
Arguments:
InstanceContext - Supplies the instance context for this instance.
Return Value:
Returns the status of this operation.
Note:
The caller will hold the instance context resource exclusive when this routine returns.
--*/
{
PAGED_CODE();
//
// Acquire exclusive access to the instance context
//
FmmAcquireResourceExclusive( &InstanceContext->MetadataResouce );
//
// Sanity - nothing should have changed this flag while we dropped the resource
// because all other threads will not use or modify the instance context while
// this flag is set
//
ASSERT( FlagOn( InstanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION ) );
//
// Reset the flag to indicate that the instance context is no longer in
// a transition state
//
ClearFlag( InstanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION );
}
#if VERIFY_METADATA_OPENED
NTSTATUS
FmmIsMetadataOpen (
__inout PFLT_CALLBACK_DATA Cbd,
__out BOOLEAN* MetadataOpen
)
/*++
Routine Description:
This routine returns if the metadata file is open on the specified instance.
Arguments:
Cbd - Supplies a pointer to the callbackData which
declares the requested operation.
MetadataOpen - Returns if the metadata file is open
Return Value:
Status
Note:
This routine takes care of the synchronization needed to access the metadata
file object and handle
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PFMM_INSTANCE_CONTEXT instanceContext = NULL;
//
// Get the instance context
//
status = FltGetInstanceContext( Cbd->Iopb->TargetInstance,
&instanceContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmIsMetadataOpen -> Failed to get instance context.\n") );
goto FmmIsMetadataOpenCleanup;
}
//
// Acquire exclusive access to the instance context
//
FmmAcquireResourceShared( &instanceContext->MetadataResouce );
if (FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION)) {
//
// If this instance context is in a transition state, it implies that
// the instance context lock has been released while sending an operation
// down to the file system. The reason for doing so is to prevent a potential
// deadlock if an underlying filter sends an IO to the top of the filter
// stack while we are holding the resource
//
// We have managed to acquire this resource in this state of transition.
// It would be incorrect to use or modify the instance context in any way
// in this situation. So we simply let go.
//
status = STATUS_FILE_LOCK_CONFLICT;
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmIsMetadataOpen -> Failed to get exclusive access to instance context since it is in a state of transition.\n") );
} else {
//
// Return if the metadata is opened
//
*MetadataOpen = (BOOLEAN) FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED );
//
// Sanity - verify that this flag is reflecting the correct state of the metadata file
//
ASSERT ( (FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED ) &&
(instanceContext->MetadataFileObject != NULL) &&
(instanceContext->MetadataHandle != NULL)) ||
(!FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED ) &&
(instanceContext->MetadataFileObject == NULL) &&
(instanceContext->MetadataHandle == NULL)) );
}
//
// Relinquish exclusive access to the instance context
//
FmmReleaseResource( &instanceContext->MetadataResouce);
FmmIsMetadataOpenCleanup:
//
// Release the references we have acquired
//
if (instanceContext != NULL) {
FltReleaseContext( instanceContext );
}
return status;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -