AFSNameArrayHdr *pNameArray = NULL;
AFSVolumeCB *pVolumeCB = NULL;
LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+ AFSVolumeCB *pNewVolumeCB = NULL;
+ LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
BOOLEAN bReleaseParentDir = FALSE, bReleaseDir = FALSE;
ULONG ulParseFlags = 0;
&uniParsedFileName,
pNameArray,
ulNameProcessingFlags,
- &pVolumeCB,
- &VolumeReferenceReason,
+ pVolumeCB,
+ pParentDirectoryCB,
+ &pNewVolumeCB,
+ &NewVolumeReferenceReason,
&pParentDirectoryCB,
&pDirectoryCB,
&uniComponentName);
+ //
+ // AFSLocateNameEntry returns pNewVolumeCB with a reference held
+ // even if pVolumeCB == pNewVolumeCB. It is always safe to release
+ // the reference on pVolumeCB that was held prior to the call.
+ // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
+ // will be released second.
+ //
+
+ lCount = AFSVolumeDecrement( pVolumeCB,
+ VolumeReferenceReason);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
+ pVolumeCB,
+ VolumeReferenceReason,
+ lCount);
+
+ pVolumeCB = pNewVolumeCB;
+
+ pNewVolumeCB = NULL;
+
+ VolumeReferenceReason = NewVolumeReferenceReason;
+
+ NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+
+ bReleaseVolume = (pVolumeCB != NULL);
+
if( !NT_SUCCESS( ntStatus) &&
ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
{
&uniFileName,
ntStatus);
- //
- // We released any root volume locks in AFSLocateNameEntry on failure
- // other than STATUS_OBJECT_NAME_NOT_FOUND
- //
-
- bReleaseVolume = FALSE;
-
bReleaseParentDir = FALSE;
- VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
-
try_return( ntStatus);
}
Irp->IoStatus.Information = IO_REPARSE;
- //
- // We released the volume lock above
- //
-
- bReleaseVolume = FALSE;
-
bReleaseParentDir = FALSE;
try_return( ntStatus);
AFSNameArrayHdr *pNameArray = NULL;
AFSVolumeCB *pVolumeCB = NULL;
LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+ AFSVolumeCB *pNewVolumeCB = NULL;
+ LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
WCHAR *pwchBuffer = NULL;
UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
&uniParsedName,
pNameArray,
AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
- &pVolumeCB,
- &VolumeReferenceReason,
+ pVolumeCB,
+ pParentDirEntry,
+ &pNewVolumeCB,
+ &NewVolumeReferenceReason,
&pParentDirEntry,
&pDirectoryEntry,
NULL);
+ //
+ // AFSLocateNameEntry returns pNewVolumeCB with a reference held
+ // even if pVolumeCB == pNewVolumeCB. It is always safe to release
+ // the reference on pVolumeCB that was held prior to the call.
+ // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
+ // will be released second.
+ //
+
+ lCount = AFSVolumeDecrement( pVolumeCB,
+ VolumeReferenceReason);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
+ pVolumeCB,
+ VolumeReferenceReason,
+ lCount);
+
+ pVolumeCB = pNewVolumeCB;
+
+ pNewVolumeCB = NULL;
+
+ VolumeReferenceReason = NewVolumeReferenceReason;
+
+ NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+
if( !NT_SUCCESS( ntStatus) ||
ntStatus == STATUS_REPARSE)
{
- //
- // The volume lock was released on failure or reparse above
- // Except for STATUS_OBJECT_NAME_NOT_FOUND
- //
-
if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
{
- if( pVolumeCB != NULL)
- {
-
- lCount = AFSVolumeDecrement( pVolumeCB,
- VolumeReferenceReason);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
- pVolumeCB,
- VolumeReferenceReason,
- lCount);
- }
-
if( pDirectoryEntry != NULL)
{
}
}
- pVolumeCB = NULL;
-
try_return( ntStatus);
}
AFSNameArrayHdr *pNameArray = NULL;
AFSVolumeCB *pVolumeCB = NULL;
LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+ AFSVolumeCB *pNewVolumeCB = NULL;
+ LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
WCHAR *pwchBuffer = NULL;
UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
&uniParsedName,
pNameArray,
0,
- &pVolumeCB,
+ pVolumeCB,
+ pParentDirEntry,
+ &pNewVolumeCB,
&VolumeReferenceReason,
&pParentDirEntry,
&pDirectoryEntry,
NULL);
+ //
+ // AFSLocateNameEntry returns pNewVolumeCB with a reference held
+ // even if pVolumeCB == pNewVolumeCB. It is always safe to release
+ // the reference on pVolumeCB that was held prior to the call.
+ // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
+ // will be released second.
+ //
+
+ lCount = AFSVolumeDecrement( pVolumeCB,
+ VolumeReferenceReason);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
+ pVolumeCB,
+ VolumeReferenceReason,
+ lCount);
+
+ pVolumeCB = pNewVolumeCB;
+
+ pNewVolumeCB = NULL;
+
+ VolumeReferenceReason = NewVolumeReferenceReason;
+
+ NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+
if( !NT_SUCCESS( ntStatus) ||
ntStatus == STATUS_REPARSE)
{
- //
- // The volume lock was released on failure or reparse above
- // Except for STATUS_OBJECT_NAME_NOT_FOUND
- //
-
if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
{
- if( pVolumeCB != NULL)
- {
-
- lCount = AFSVolumeDecrement( pVolumeCB,
- VolumeReferenceReason);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
- pVolumeCB,
- VolumeReferenceReason,
- lCount);
- }
-
if( pDirectoryEntry != NULL)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSVolumeCB *pVolumeCB = NULL;
LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+ AFSVolumeCB *pNewVolumeCB = NULL;
+ LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
AFSObjectInfoCB *pObjectInfo = NULL;
ULONGLONG ullIndex = 0;
pNameArray,
AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
- &pVolumeCB,
- &VolumeReferenceReason,
+ pVolumeCB,
+ pParentDirEntry,
+ &pNewVolumeCB,
+ &NewVolumeReferenceReason,
&pParentDirEntry,
&pDirectoryEntry,
NULL);
+ //
+ // AFSLocateNameEntry returns pNewVolumeCB with a reference held
+ // even if pVolumeCB == pNewVolumeCB. It is always safe to release
+ // the reference on pVolumeCB that was held prior to the call.
+ // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
+ // will be released second.
+ //
+
+ lCount = AFSVolumeDecrement( pVolumeCB,
+ VolumeReferenceReason);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
+ pVolumeCB,
+ VolumeReferenceReason,
+ lCount);
+
+ pVolumeCB = pNewVolumeCB;
+
+ pNewVolumeCB = NULL;
+
+ VolumeReferenceReason = NewVolumeReferenceReason;
+
+ NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+
if( !NT_SUCCESS( ntStatus) ||
ntStatus == STATUS_REPARSE)
{
if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
{
- if( pVolumeCB != NULL)
- {
-
- lCount = AFSVolumeDecrement( pVolumeCB,
- VolumeReferenceReason);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSGetObjectStatus Decrement3 count on volume %p Reason %u Cnt %d\n",
- pVolumeCB,
- VolumeReferenceReason,
- lCount);
- }
-
if( pDirectoryEntry != NULL)
{
// AFSLocateNameEntry
//
// On entry, *VolumeCB must have a held ReferenceCount provided by
-// the caller which will be released. On successful exit, *VolumeCB
+// the caller which will not be released. On successful exit, *OutVolumeCB
// will be assigned the new current volume with a held ReferenceCount.
//
// On entry, *ParentDirectoryCB must have a held DirOpenReferenceCount
NTSTATUS
AFSLocateNameEntry( IN GUID *AuthGroup,
IN PFILE_OBJECT FileObject,
- IN UNICODE_STRING *RootPathName,
+ IN OUT UNICODE_STRING *RootPathName,
IN UNICODE_STRING *ParsedPathName,
IN AFSNameArrayHdr *NameArray,
IN ULONG Flags,
- IN OUT AFSVolumeCB **VolumeCB,
- IN OUT LONG *pVolumeReferenceReason,
- IN OUT AFSDirectoryCB **ParentDirectoryCB,
- OUT AFSDirectoryCB **DirectoryCB,
+ IN AFSVolumeCB *VolumeCB,
+ IN AFSDirectoryCB *ParentDirectoryCB,
+ OUT AFSVolumeCB **OutVolumeCB,
+ OUT LONG *OutVolumeReferenceReason,
+ OUT AFSDirectoryCB **OutParentDirectoryCB,
+ OUT AFSDirectoryCB **OutDirectoryCB,
OUT PUNICODE_STRING ComponentName)
{
UNICODE_STRING uniRelativeName, uniNoOpName;
AFSObjectInfoCB *pCurrentObject = NULL;
AFSObjectInfoCB *pParentObjectInfo = NULL;
- AFSVolumeCB *pCurrentVolume = *VolumeCB;
+ AFSVolumeCB *pCurrentVolume = NULL;
AFSVolumeCB *pTargetVolume = NULL;
- BOOLEAN bReleaseCurrentVolume = TRUE;
- LONG VolumeReferenceReason = *pVolumeReferenceReason;
+ BOOLEAN bReleaseCurrentVolume = FALSE;
+ LONG VolumeReferenceReason;
BOOLEAN bSubstitutedName = FALSE;
LONG lCount;
__Enter
{
+ ASSERT( *OutVolumeCB != VolumeCB);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE_2,
"AFSLocateNameEntry (FO: %p) Processing full name %wZ\n",
pParentDirEntry = NULL;
- pDirEntry = *ParentDirectoryCB;
+ pDirEntry = ParentDirectoryCB;
+
+ pCurrentVolume = VolumeCB;
+
+ VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
+
+ lCount = AFSVolumeIncrement( pCurrentVolume,
+ VolumeReferenceReason);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
+ pCurrentVolume,
+ VolumeReferenceReason,
+ lCount);
+
+ bReleaseCurrentVolume = TRUE;
uniPathName = *ParsedPathName;
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
+
+ *OutDirectoryCB = pDirEntry;
+
+ *OutVolumeCB = pCurrentVolume;
- *DirectoryCB = pDirEntry;
+ *OutVolumeReferenceReason = VolumeReferenceReason;
- *VolumeCB = pCurrentVolume;
+ bReleaseCurrentVolume = FALSE;
*RootPathName = uniFullPathName;
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
- *DirectoryCB = pDirEntry;
+ *OutDirectoryCB = pDirEntry;
- *VolumeCB = pCurrentVolume;
+ *OutVolumeCB = pCurrentVolume;
+
+ *OutVolumeReferenceReason = VolumeReferenceReason;
+
+ bReleaseCurrentVolume = FALSE;
*RootPathName = uniFullPathName;
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
+
+ *OutDirectoryCB = pDirEntry;
- *DirectoryCB = pDirEntry;
+ *OutVolumeCB = pCurrentVolume;
- *VolumeCB = pCurrentVolume;
+ *OutVolumeReferenceReason = VolumeReferenceReason;
+
+ bReleaseCurrentVolume = FALSE;
*RootPathName = uniFullPathName;
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
+
+ *OutDirectoryCB = pDirEntry;
- *DirectoryCB = pDirEntry;
+ *OutVolumeCB = pCurrentVolume;
- *VolumeCB = pCurrentVolume;
+ *OutVolumeReferenceReason = VolumeReferenceReason;
+
+ bReleaseCurrentVolume = FALSE;
*RootPathName = uniFullPathName;
}
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
+
+ *OutDirectoryCB = pDirEntry;
- *DirectoryCB = pDirEntry;
+ *OutVolumeCB = pCurrentVolume;
- *VolumeCB = pCurrentVolume;
+ *OutVolumeReferenceReason = VolumeReferenceReason;
+
+ bReleaseCurrentVolume = FALSE;
*RootPathName = uniFullPathName;
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
+
+ *OutDirectoryCB = NULL;
- *DirectoryCB = NULL;
+ *OutVolumeCB = pCurrentVolume;
- *VolumeCB = pCurrentVolume;
+ *OutVolumeReferenceReason = VolumeReferenceReason;
+
+ bReleaseCurrentVolume = FALSE;
if( ComponentName != NULL)
{
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
+
+ *OutDirectoryCB = NULL;
+
+ *OutVolumeCB = pCurrentVolume;
- *DirectoryCB = NULL;
+ *OutVolumeReferenceReason = VolumeReferenceReason;
- *VolumeCB = pCurrentVolume;
+ bReleaseCurrentVolume = FALSE;
if( ComponentName != NULL)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
+ "AFSLocateNameEntry Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
&pDirEntry->NameInformation.FileName,
pDirEntry,
NULL,
// Pass back the directory entries
//
- *ParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
- *DirectoryCB = NULL;
+ *OutDirectoryCB = NULL;
- *VolumeCB = pCurrentVolume;
+ *OutVolumeCB = pCurrentVolume;
+
+ *OutVolumeReferenceReason = VolumeReferenceReason;
+
+ bReleaseCurrentVolume = FALSE;
if( ComponentName != NULL)
{
ASSERT( lCount >= 0);
}
- if( bReleaseCurrentVolume)
- {
-
- ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
-
- lCount = AFSVolumeDecrement( pCurrentVolume,
- VolumeReferenceReason);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry Decrement3 count on volume %p Reason %u Cnt %d\n",
- pCurrentVolume,
- VolumeReferenceReason,
- lCount);
-
- bReleaseCurrentVolume = FALSE;
- }
-
if( RootPathName->Buffer != uniFullPathName.Buffer)
{
else
{
- if( *ParentDirectoryCB != NULL)
+ if( *OutParentDirectoryCB != NULL)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
- &(*ParentDirectoryCB)->NameInformation.FileName,
- *ParentDirectoryCB,
+ &(*OutParentDirectoryCB)->NameInformation.FileName,
+ *OutParentDirectoryCB,
NULL,
- (*ParentDirectoryCB)->DirOpenReferenceCount);
+ (*OutParentDirectoryCB)->DirOpenReferenceCount);
}
- if( *DirectoryCB != NULL)
+ if( *OutDirectoryCB != NULL)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
- &(*DirectoryCB)->NameInformation.FileName,
- *DirectoryCB,
+ &(*OutDirectoryCB)->NameInformation.FileName,
+ *OutDirectoryCB,
NULL,
- (*DirectoryCB)->DirOpenReferenceCount);
+ (*OutDirectoryCB)->DirOpenReferenceCount);
}
}
- if( bSubstituteName &&
- uniSearchName.Buffer != NULL)
+ if( bReleaseCurrentVolume)
{
- AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
+ ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
+
+ lCount = AFSVolumeDecrement( pCurrentVolume,
+ VolumeReferenceReason);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNameEntry Decrement7 count on volume %p Reason %u Cnt %d\n",
+ pCurrentVolume,
+ VolumeReferenceReason,
+ lCount);
+
+ bReleaseCurrentVolume = FALSE;
}
- if ( bReleaseCurrentVolume) {
+ if( bSubstituteName &&
+ uniSearchName.Buffer != NULL)
+ {
- *pVolumeReferenceReason = VolumeReferenceReason;
+ AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
}
}