Windows: Fix Redir link counting
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 19 Nov 2012 20:06:47 +0000 (15:06 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Fri, 23 Nov 2012 15:48:20 +0000 (07:48 -0800)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Rod Widdowson <rdw@steadingsoftware.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp
src/WINNT/afsrdr/kernel/lib/AFSClose.cpp
src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp

index 43ac6ab..f8945ec 100644 (file)
@@ -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",
index 1c73f1b..ce3046f 100644 (file)
@@ -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)
                     {
 
                         //
index f5d00aa..9272697 100644 (file)
@@ -1139,16 +1139,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
             // the code
@@ -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,
index 6f6783a..ff10961 100644 (file)
@@ -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);