From 6d37315a9c4fa4aae99715dd18827fcc0b543ba3 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 19 Nov 2012 15:06:47 -0500 Subject: [PATCH] Windows: Fix Redir link counting Each object in AFS has a link count which tracks the number of directory entries that refer to the FileId. In the redirector there is one ObjectInformationCB per FileId and one AFSDirectoryCB for each directory entry. When a directory entry is deleted perhaps by delete on close it is important to ensure that the matching ObjectInformationCB is not deleted unless the Link count drops to 0. Change-Id: I2c7906d5881f93ed60697d40a0ea462f4567d443 Reviewed-on: http://gerrit.openafs.org/8480 Tested-by: BuildBot Reviewed-by: Rod Widdowson Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp | 74 ++++++++++--------- src/WINNT/afsrdr/kernel/lib/AFSClose.cpp | 3 +- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 24 +++--- .../afsrdr/kernel/lib/AFSNameSupport.cpp | 3 +- 4 files changed, 57 insertions(+), 47 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp index 43ac6ab18..f8945ec29 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp @@ -376,41 +376,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE)) { - // - // Stop anything possibly in process - // - - AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSCleanup Acquiring Fcb extents lock %08lX EXCL %08lX\n", - &pFcb->NPFcb->Specific.File.ExtentsResource, - PsGetCurrentThread()); - - AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource, - TRUE); - - pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED; - - KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete, - 0, - FALSE); - - // - // Before telling the server about the deleted file, tear down all extents for - // the file - // - - AFSTearDownFcbExtents( pFcb, - &pCcb->AuthGroup); - - AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSCleanup Releasing Fcb extents lock %08lX EXCL %08lX\n", - &pFcb->NPFcb->Specific.File.ExtentsResource, - PsGetCurrentThread()); - - AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource); - ntStatus = STATUS_SUCCESS; ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED; @@ -454,6 +419,45 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = STATUS_SUCCESS; + if ( --pObjectInfo->Links < 1) + { + + // + // Stop anything possibly in process + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCleanup Acquiring Fcb extents lock %08lX EXCL %08lX\n", + &pFcb->NPFcb->Specific.File.ExtentsResource, + PsGetCurrentThread()); + + AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource, + TRUE); + + pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED; + + KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete, + 0, + FALSE); + + // + // Before telling the server about the deleted file, tear down all extents for + // the file + // + + AFSTearDownFcbExtents( pFcb, + &pCcb->AuthGroup); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCleanup Releasing Fcb extents lock %08lX EXCL %08lX\n", + &pFcb->NPFcb->Specific.File.ExtentsResource, + PsGetCurrentThread()); + + AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource); + } + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Setting DELETE flag in file %wZ Dir Entry %p\n", diff --git a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp index 1c73f1ba2..ce3046f82 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp @@ -314,7 +314,8 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, if( BooleanFlagOn( pDirCB->Flags, AFS_DIR_ENTRY_DELETED)) { - if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB) + if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB && + pObjectInfo->Links == 0) { // diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index f5d00aa14..9272697ff 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -1138,16 +1138,6 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo, pObjectInfoCB->EaSize = DirEnumEntry->EaSize; - // - // Object specific information - // - - pObjectInfoCB->Links = DirEnumEntry->Links; - - pObjectInfoCB->Expiration = DirEnumEntry->Expiration; - - pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion; - // // Check for the case where we have a filetype of SymLink but both the TargetFid and the // TargetName are empty. In this case set the filetype to zero so we evaluate it later in @@ -1174,6 +1164,16 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo, } } + // + // Object specific information + // + + pObjectInfoCB->Links = DirEnumEntry->Links; + + pObjectInfoCB->Expiration = DirEnumEntry->Expiration; + + pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion; + try_exit: if( !NT_SUCCESS( ntStatus)) @@ -1658,6 +1658,8 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo, // Mark this node as invalid // + (*ppObjectInfo)->Links = 0; + SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED); AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, @@ -8960,6 +8962,8 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo, AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource, TRUE); + ObjectInfo->Links = 0; + ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED; KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp index 6f6783a8a..ff1096184 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp @@ -2464,7 +2464,8 @@ AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo, DirEntry->ObjectInformation, lCount); - if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED)) + if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) && + DirEntry->ObjectInformation->Links == 0) { SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED); -- 2.39.5