]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
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 43ac6ab182180b22c1d8af49b59509f1bdee13ab..f8945ec293bc1dc5b6fdd6063ef2a3a0063dfb6b 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 1c73f1ba25568dfb6851596fd8ae1fdab142263f..ce3046f821995ed168a656df8c064f8d770e0a0b 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 f5d00aa149f8889c54a93877f5cd973908182a07..9272697ff6b70be577c0c98a94bdf3c7a7f6d851 100644 (file)
@@ -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,
index 6f6783a8a5cff59f01ce0b537db5820189a72857..ff10961848940a91b226cdff677683c86ca19977 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);