X-Git-Url: https://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2FWINNT%2Fafsrdr%2Fkernel%2Flib%2FAFSCreate.cpp;h=c534890c78e71d6dac69b080b6809c9385fccf0a;hp=63f25342a2fe4b763c9d0e9466bfa8fae2f34ef0;hb=b78b8f64a69481e59e957ebe09315fc5b8b60c17;hpb=5263b04796dfae34b2ac52e420bdc2f0c70e0568 diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp index 63f2534..c534890 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp @@ -145,6 +145,7 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, ULONG ulParseFlags = 0; GUID stAuthGroup; ULONG ulNameProcessingFlags = 0; + BOOLEAN bOpenedReparsePoint = FALSE; __Enter { @@ -577,20 +578,11 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, NULL, pParentDirectoryCB->OpenReferenceCount); - InterlockedDecrement( &pDirectoryCB->OpenReferenceCount); - - AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n", - &pDirectoryCB->NameInformation.FileName, - pDirectoryCB, - NULL, - pDirectoryCB->OpenReferenceCount); - // - // The name array also contains a reference to the pDirectoryCB so we need to remove it - // Note that this could decrement the count to zero allowing it to be deleted, hence - // don't access the pointer contents beyond here. + // Do NOT decrement the reference count on the pDirectoryCB yet. + // The BackupEntry below might drop the count to zero leaving + // the entry subject to being deleted and we need some of the + // contents during later processing // AFSBackupEntry( pNameArray); @@ -613,6 +605,21 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, &uniComponentName, &pFcb, &pCcb); + if( pDirectoryCB != NULL) + { + // + // It is now safe to drop the Reference Count + // + InterlockedDecrement( &pDirectoryCB->OpenReferenceCount); + + AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n", + &pDirectoryCB->NameInformation.FileName, + pDirectoryCB, + NULL, + pDirectoryCB->OpenReferenceCount); + } if( !NT_SUCCESS( ntStatus)) { @@ -641,17 +648,31 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, try_return( ntStatus); } - if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT) && - pDirectoryCB != NULL && - !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT)) + if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT)) { - AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ Type %08lX\n", - Irp, - &uniFileName, - pDirectoryCB->ObjectInformation->FileType); + if( pDirectoryCB == NULL || + !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT)) + { + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n", + Irp, + &uniFileName, + pDirectoryCB, + pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0); + } + else + { + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCommonCreate (%08lX) Opening as reparse point %wZ Type %08lX\n", + Irp, + &uniFileName, + pDirectoryCB->ObjectInformation->FileType); + + bOpenedReparsePoint = TRUE; + } } // @@ -733,23 +754,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, &pParentDirectoryCB->NameInformation.FileName, ntStatus); } - else - { - - // - // Reference the new dir entry - // - - InterlockedIncrement( &pCcb->DirectoryCB->OpenReferenceCount); - - AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSCreate Increment (Create) count on %wZ DE %p Ccb %p Cnt %d\n", - &pCcb->DirectoryCB->NameInformation.FileName, - pCcb->DirectoryCB, - pCcb, - pCcb->DirectoryCB->OpenReferenceCount); - } // // Dereference the parent entry @@ -1063,6 +1067,11 @@ try_exit: } } + if( bOpenedReparsePoint) + { + SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT); + } + AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCreate Count on %wZ DE %p Ccb %p Cnt %d\n", @@ -1458,7 +1467,7 @@ AFSOpenRoot( IN PIRP Irp, AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, - "AFSOpenRoot (%08lX) Failed to open file in service Status %08lX\n", + "AFSOpenRoot (%08lX) Failed open in service AFSRoot Status %08lX\n", Irp, ntStatus); @@ -1770,6 +1779,43 @@ AFSProcessCreate( IN PIRP Irp, pObjectInfo = pDirEntry->ObjectInformation; + if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) || + pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n", + Irp, + &pDirEntry->NameInformation.FileName, + pObjectInfo->FileId.Cell, + pObjectInfo->FileId.Volume, + pObjectInfo->FileId.Vnode, + pObjectInfo->FileId.Unique); + + ntStatus = AFSEvaluateNode( AuthGroup, + pDirEntry); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n", + Irp, + &pDirEntry->NameInformation.FileName, + pObjectInfo->FileId.Cell, + pObjectInfo->FileId.Volume, + pObjectInfo->FileId.Vnode, + pObjectInfo->FileId.Unique, + ntStatus); + + try_return( ntStatus); + } + + ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED); + } + // // We may have raced and the Fcb is already created // @@ -1932,16 +1978,16 @@ AFSProcessCreate( IN PIRP Irp, AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n", - *Fcb, - (*Fcb)->OpenReferenceCount); + *Fcb, + (*Fcb)->OpenReferenceCount); InterlockedIncrement( &(*Fcb)->OpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n", - (*Fcb), - (*Fcb)->OpenHandleCount); + (*Fcb), + (*Fcb)->OpenHandleCount); // // Increment the open reference and handle on the parent node @@ -2010,6 +2056,13 @@ try_exit: if( bFileCreated) { + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n", + pDirEntry, + pParentObjectInfo, + ntStatus); + // // Remove the dir entry from the parent // @@ -2017,8 +2070,37 @@ try_exit: AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock, TRUE); - AFSDeleteDirEntry( pParentObjectInfo, - pDirEntry); + SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED); + + // + // Decrement the reference added during initialization of the DE + // + + InterlockedDecrement( &pDirEntry->OpenReferenceCount); + + AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n", + &pDirEntry->NameInformation.FileName, + pDirEntry, + pDirEntry->OpenReferenceCount); + + // + // Pull the directory entry from the parent + // + + AFSRemoveDirNodeFromParent( pParentObjectInfo, + pDirEntry, + FALSE); // Leave it in the enum list so the worker cleans it up + + AFSNotifyDelete( pDirEntry, + FALSE); + + // + // Tag the parent as needing verification + // + + SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY); AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock); } @@ -2061,7 +2143,6 @@ AFSOpenTargetDirectory( IN PIRP Irp, PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp); PACCESS_MASK pDesiredAccess = NULL; USHORT usShareAccess; - BOOLEAN bRemoveAccess = FALSE; BOOLEAN bAllocatedCcb = FALSE; BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE; AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL; @@ -2298,13 +2379,6 @@ try_exit: *Ccb = NULL; - if( bRemoveAccess) - { - - IoRemoveShareAccess( pFileObject, - &pParentObject->Fcb->ShareAccess); - } - if( bAllocatedFcb) { @@ -2342,6 +2416,8 @@ AFSProcessOpen( IN PIRP Irp, ULONG ulResultLen = 0; AFSObjectInfoCB *pParentObjectInfo = NULL; AFSObjectInfoCB *pObjectInfo = NULL; + ULONG ulFileAccess = 0; + AFSFileAccessReleaseCB stReleaseFileAccess; __Enter { @@ -2592,6 +2668,10 @@ AFSProcessOpen( IN PIRP Irp, stOpenCB.ShareAccess = usShareAccess; + stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId(); + + stOpenCB.Identifier = (ULONGLONG)pFileObject; + stOpenResultCB.GrantedAccess = 0; ulResultLen = sizeof( AFSFileOpenResultCB); @@ -2620,6 +2700,12 @@ AFSProcessOpen( IN PIRP Irp, } // + // Save the granted access in case we need to release it below + // + + ulFileAccess = stOpenResultCB.FileAccess; + + // // Check if there is a conflict // @@ -2665,6 +2751,8 @@ AFSProcessOpen( IN PIRP Irp, (*Ccb)->DirectoryCB = DirectoryCB; + (*Ccb)->FileAccess = ulFileAccess; + // // Perform the access check on the target if this is a mount point or symlink // @@ -2782,6 +2870,26 @@ try_exit: if( !NT_SUCCESS( ntStatus)) { + if ( ulFileAccess > 0) + { + + stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId(); + + stReleaseFileAccess.FileAccess = ulFileAccess; + + stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject; + + AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS, + AFS_REQUEST_FLAG_SYNCHRONOUS, + AuthGroup, + &DirectoryCB->NameInformation.FileName, + &pObjectInfo->FileId, + (void *)&stReleaseFileAccess, + sizeof( AFSFileAccessReleaseCB), + NULL, + NULL); + } + if( bAllocatedCcb) {