//
NTSTATUS
-AFSInitFcb( IN AFSDirectoryCB *DirEntry,
- IN OUT AFSFcb **Fcb)
+AFSInitFcb( IN AFSDirectoryCB *DirEntry)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSFcb *pFcb = NULL;
AFSNonPagedFcb *pNPFcb = NULL;
IO_STATUS_BLOCK stIoSb = {0,0};
- BOOLEAN bUninitFileLock = FALSE;
USHORT usFcbLength = 0;
ULONGLONG ullIndex = 0;
AFSDirEnumEntry *pDirEnumCB = NULL;
sizeof( AFSNonPagedFcb));
pNPFcb->Size = sizeof( AFSNonPagedFcb);
+
pNPFcb->Type = AFS_NON_PAGED_FCB;
//
ExInitializeResourceLite( &pNPFcb->PagingResource);
+ ExInitializeResourceLite( &pNPFcb->CcbListLock);
+
pFcb->Header.Resource = &pNPFcb->Resource;
pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
pFcb->NPFcb = pNPFcb;
//
- // Initialize some fields in the Fcb
- //
-
- pFcb->ObjectInformation = pObjectInfo;
-
- pObjectInfo->Fcb = pFcb;
-
- //
// Set type specific information
//
//
pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
-
- //
- // Initialize enumeration information
- //
-
- KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
- NotificationEvent,
- FALSE);
}
else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
{
NULL,
NULL);
- bUninitFileLock = TRUE;
-
//
// Initialize the header file sizes to our dir entry information
//
}
else
{
- ASSERT( FALSE);
- try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
}
//
- // And return the Fcb
+ // Initialize some fields in the Fcb
//
- *Fcb = pFcb;
+ if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSInitFcb Raced Fcb %08lX pFcb %08lX Name %wZ\n",
+ pObjectInfo->Fcb,
+ pFcb,
+ &DirEntry->NameInformation.FileName);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
+ &pObjectInfo->Fcb->NPFcb->Resource,
+ PsGetCurrentThread());
+
+ AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+ TRUE);
+
+ try_return( ntStatus = STATUS_REPARSE);
+ }
+
+ pFcb->ObjectInformation = pObjectInfo;
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
- pFcb,
- &DirEntry->NameInformation.FileName);
-
+ &pObjectInfo->Fcb,
+ &DirEntry->NameInformation.FileName);
try_exit:
- if( !NT_SUCCESS( ntStatus))
+ if( ntStatus != STATUS_SUCCESS)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitFcb Failed to initialize fcb Status %08lX\n",
- ntStatus);
-
- if( pFcb != NULL)
+ if ( !NT_SUCCESS( ntStatus))
{
- if( bUninitFileLock)
- {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitFcb Failed to initialize fcb Status %08lX\n",
+ ntStatus);
+ }
- FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
- }
+ if( pFcb != NULL)
+ {
if( pNPFcb != NULL)
{
AFSReleaseResource( &pNPFcb->Resource);
- ExDeleteResourceLite( &pNPFcb->PagingResource);
+ FsRtlTeardownPerStreamContexts( &pFcb->Header);
- ExDeleteResourceLite( &pNPFcb->Resource);
- }
+ if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
+ {
- AFSExFreePool( pFcb);
- }
+ FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
- if( pNPFcb != NULL)
- {
+ ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
- AFSExFreePool( pNPFcb);
- }
+ ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
+ }
- if( Fcb != NULL)
- {
+ ExDeleteResourceLite( &pNPFcb->PagingResource);
+
+ ExDeleteResourceLite( &pNPFcb->CcbListLock);
+
+ ExDeleteResourceLite( &pNPFcb->Resource);
+
+ AFSExFreePool( pNPFcb);
+ }
- *Fcb = NULL;
+ AFSExFreePool( pFcb);
}
}
}
BOOLEAN bReleaseLocks = FALSE;
AFSVolumeInfoCB stVolumeInformation;
AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+ LONG lCount;
__Enter
{
// So we don't lock with an invalidation call ...
//
- InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+ lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
AFSAcquireExcl( pVolumeCB->VolumeLock,
TRUE);
- InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
*VolumeCB = pVolumeCB;
try_return( ntStatus);
AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInitVolume Initializing count (1) on volume %08lX\n",
+ "AFSInitVolume Initializing count (2) on volume %08lX\n",
pVolumeCB);
- pVolumeCB->VolumeReferenceCount = 1;
+ pVolumeCB->VolumeReferenceCount = 2;
AFSAcquireExcl( pVolumeCB->VolumeLock,
TRUE);
{
pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
+
+ SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
}
else
{
- AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
- &pVolumeCB->TreeEntry);
- }
+ if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
+ &pVolumeCB->TreeEntry)))
+ {
- SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
+ SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
+ }
+ }
if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
{
if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
{
- AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
+ AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
}
AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
{
-
AFSReleaseResource( VolumeCB->VolumeLock);
}
ExInitializeResourceLite( &pNPFcb->PagingResource);
+ ExInitializeResourceLite( &pNPFcb->CcbListLock);
+
pFcb->Header.Resource = &pNPFcb->Resource;
pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
pFcb->NPFcb = pNPFcb;
//
- // Initialize enumeration information
- //
-
- KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
- NotificationEvent,
- FALSE);
-
- //
// Save the root Fcb in the VolumeCB
//
ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
+ ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
+
//
// The non paged region
//
//
void
-AFSRemoveFcb( IN AFSFcb *Fcb)
+AFSRemoveFcb( IN AFSFcb **ppFcb)
{
+ AFSFcb * pFcb;
+
+ pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
+
+ if ( pFcb == NULL)
+ {
+
+ return;
+ }
+
//
// Uninitialize the file lock if it is a file
//
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSRemoveFcb Removing Fcb %08lX\n",
- Fcb);
+ pFcb);
- if( Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
+ if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
{
- FsRtlUninitializeFileLock( &Fcb->Specific.File.FileLock);
+ FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
//
// The resource we allocated
//
- ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.ExtentsResource );
+ ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
- ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.DirtyExtentsListLock);
+ ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
}
- else if( Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
+ else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
{
// Tear down the FM specific contexts
//
- FsRtlTeardownPerStreamContexts( &Fcb->Header);
+ FsRtlTeardownPerStreamContexts( &pFcb->Header);
//
// Delete the resources
//
- ExDeleteResourceLite( &Fcb->NPFcb->Resource);
-
- ExDeleteResourceLite( &Fcb->NPFcb->PagingResource);
+ ExDeleteResourceLite( &pFcb->NPFcb->Resource);
+ ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
+ ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
//
// The non paged region
//
- AFSExFreePool( Fcb->NPFcb);
+ AFSExFreePool( pFcb->NPFcb);
//
// And the Fcb itself, which includes the name
//
- AFSExFreePool( Fcb);
+ AFSExFreePool( pFcb);
return;
}
sizeof( AFSCcb));
pCcb->Size = sizeof( AFSCcb);
+
pCcb->Type = AFS_CCB;
+ pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
+ sizeof( AFSNonPagedCcb),
+ AFS_CCB_NP_ALLOCATION_TAG);
+
+ if( pCcb->NPCcb == NULL)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitCcb Failed to allocate NPCcb\n");
+
+ try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
+
//
// Return the Ccb
//
if( pCcb != NULL)
{
+ if ( pCcb->NPCcb != NULL)
+ {
+
+ AFSExFreePool( pCcb->NPCcb);
+ }
+
AFSExFreePool( pCcb);
}
//
NTSTATUS
-AFSRemoveCcb( IN AFSCcb *Ccb)
+AFSRemoveCcb( IN AFSFcb *Fcb,
+ IN AFSCcb *Ccb)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
+ AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+ TRUE);
+
+ if( Fcb != NULL &&
+ BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
+ {
+
+ AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
+ TRUE);
+
+ if( Ccb->ListEntry.fLink == NULL)
+ {
+
+ Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
+
+ if( Fcb->CcbListTail != NULL)
+ {
+ Fcb->CcbListTail->ListEntry.fLink = NULL;
+ }
+ }
+ else
+ {
+ ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
+ }
+
+ if( Ccb->ListEntry.bLink == NULL)
+ {
+
+ Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
+
+ if( Fcb->CcbListHead != NULL)
+ {
+ Fcb->CcbListHead->ListEntry.bLink = NULL;
+ }
+ }
+ else
+ {
+ ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
+ }
+
+ AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
+ }
+
if( Ccb->MaskName.Buffer != NULL)
{
AFSExFreePool( Ccb->NotifyMask.Buffer);
}
+ AFSReleaseResource( &Ccb->NPCcb->CcbLock);
+
//
// Free up the Ccb
//
+ ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
+
+ AFSExFreePool( Ccb->NPCcb);
+
AFSExFreePool( Ccb);
return ntStatus;
}
+
+NTSTATUS
+AFSInsertCcb( IN AFSFcb *Fcb,
+ IN AFSCcb *Ccb)
+{
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
+ TRUE);
+
+ AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+ TRUE);
+
+ if( Fcb->CcbListHead == NULL)
+ {
+ Fcb->CcbListHead = Ccb;
+ }
+ else
+ {
+ Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
+
+ Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
+ }
+
+ Fcb->CcbListTail = Ccb;
+
+ SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
+
+ AFSReleaseResource( &Ccb->NPCcb->CcbLock);
+
+ AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
+
+ return ntStatus;
+}