windows: ObjectInformationCB.ObjectReferenceCount
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSCleanup.cpp
index 69096ec..77bf7e9 100644 (file)
@@ -66,7 +66,10 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
     IO_STATUS_BLOCK stIoSB;
     AFSObjectInfoCB *pObjectInfo = NULL;
     AFSFileCleanupCB stFileCleanup;
+    AFSFileCleanupResultCB *pResultCB = NULL;
+    ULONG ulResultLen = 0;
     ULONG   ulNotificationFlags = 0;
+    LONG    lCount;
 
     __try
     {
@@ -111,6 +114,26 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
         stFileCleanup.Identifier = (ULONGLONG)pFileObject;
 
         //
+        // Allocate our return buffer
+        //
+
+        pResultCB = (AFSFileCleanupResultCB *)AFSExAllocatePoolWithTag( PagedPool,
+                                                                        PAGE_SIZE,
+                                                                        AFS_GENERIC_MEMORY_32_TAG);
+
+        if( pResultCB == NULL)
+        {
+
+            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+        }
+
+        RtlZeroMemory( pResultCB,
+                       PAGE_SIZE);
+
+        ulResultLen = PAGE_SIZE;
+
+
+        //
         // Perform the cleanup functionality depending on the type of node it is
         //
 
@@ -131,15 +154,15 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 ASSERT( pFcb->OpenHandleCount != 0);
 
-                InterlockedDecrement( &pFcb->OpenHandleCount);
+                AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+                lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSCleanup (RootAll) Decrement handle count on Fcb %08lX Cnt %d\n",
                               pFcb,
-                              pFcb->OpenHandleCount);
-
-                AFSReleaseResource( &pFcb->NPFcb->Resource);
+                              lCount);
 
                 FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync,
                                     &pControlDeviceExt->Specific.Control.DirNotifyList,
@@ -162,14 +185,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 ASSERT( pFcb->OpenHandleCount != 0);
 
-                InterlockedDecrement( &pFcb->OpenHandleCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCleanup (IOCtl) Decrement handle count on Fcb %08lX Cnt %d\n",
-                              pFcb,
-                              pFcb->OpenHandleCount);
-
                 //
                 // Decrement the open child handle count
                 //
@@ -178,21 +193,25 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                     pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
                 {
 
-                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                    lCount = InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCleanup (IOCtl) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                   pObjectInfo->ParentObjectInformation,
-                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                                  lCount);
                 }
 
-                //
-                // And finally, release the Fcb if we acquired it.
-                //
-
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+                lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanup (IOCtl) Decrement handle count on Fcb %08lX Cnt %d\n",
+                              pFcb,
+                              lCount);
+
                 break;
             }
 
@@ -291,14 +310,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 ASSERT( pFcb->OpenHandleCount != 0);
 
-                InterlockedDecrement( &pFcb->OpenHandleCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCleanup (File) Decrement handle count on Fcb %08lX Cnt %d\n",
-                              pFcb,
-                              pFcb->OpenHandleCount);
-
                 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
                 {
 
@@ -354,11 +365,12 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                 }
 
                 //
-                // If the count has dropped to zero and there is a pending delete
-                // then delete the node
+                // If the count has dropped to one and there is a pending delete
+                // then delete the node.  The final count will be decremented just
+                // before the Fcb->NPFcb->Resource is released.
                 //
 
-                if( pFcb->OpenHandleCount == 0 &&
+                if( pFcb->OpenHandleCount == 1 &&
                     BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                 {
 
@@ -418,8 +430,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                                   &pObjectInfo->FileId,
                                                   &stFileCleanup,
                                                   sizeof( AFSFileCleanupCB),
-                                                  NULL,
-                                                  NULL);
+                                                  pResultCB,
+                                                  &ulResultLen);
 
                     if( !NT_SUCCESS( ntStatus) &&
                         ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
@@ -450,10 +462,21 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                         ASSERT( pObjectInfo->ParentObjectInformation != NULL);
 
-                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
-                                                        pCcb,
-                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
-                                                        (ULONG)FILE_ACTION_REMOVED);
+                        AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                        TRUE);
+
+                        if ( pObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
+                        {
+
+                            SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                            pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+                        }
+                        else
+                        {
+
+                            pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = pResultCB->ParentDataVersion.QuadPart;
+                        }
 
                         //
                         // Now that the service has the entry has deleted we need to remove it from the parent
@@ -463,9 +486,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                         if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
                         {
 
-                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                                            TRUE);
-
                             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_VERBOSE,
                                           "AFSCleanup DE %p for %wZ removing entry\n",
@@ -474,8 +494,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                             AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
                                                 pCcb->DirectoryCB);
-
-                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
                         }
                         else
                         {
@@ -486,6 +504,14 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                           pCcb->DirectoryCB,
                                           &pCcb->DirectoryCB->NameInformation.FileName);
                         }
+
+                        AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
+                                                        pCcb,
+                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
+                                                        (ULONG)FILE_ACTION_REMOVED);
+
                     }
                 }
                 else
@@ -520,7 +546,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                          &pCcb->AuthGroup);
                     }
 
-                    if( pFcb->OpenHandleCount == 0)
+                    if( pFcb->OpenHandleCount == 1)
                     {
 
                         //
@@ -542,15 +568,38 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                     // Push the request to the service
                     //
 
-                    AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
-                                       ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                       &pCcb->AuthGroup,
-                                       &pCcb->DirectoryCB->NameInformation.FileName,
-                                       &pObjectInfo->FileId,
-                                       &stFileCleanup,
-                                       sizeof( AFSFileCleanupCB),
-                                       NULL,
-                                       NULL);
+                    ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
+                                                  ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
+                                                  &pCcb->AuthGroup,
+                                                  &pCcb->DirectoryCB->NameInformation.FileName,
+                                                  &pObjectInfo->FileId,
+                                                  &stFileCleanup,
+                                                  sizeof( AFSFileCleanupCB),
+                                                  pResultCB,
+                                                  &ulResultLen);
+
+                    if ( NT_SUCCESS( ntStatus))
+                    {
+
+                        if ( pObjectInfo->ParentObjectInformation != NULL)
+                        {
+
+                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                            TRUE);
+
+                            if ( pObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart)
+                            {
+
+                                SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                                pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+                            }
+
+                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                        }
+                    }
+
+                    ntStatus = STATUS_SUCCESS;
                 }
 
                 //
@@ -581,21 +630,35 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                     ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);
 
-                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                    lCount = InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCleanup (File) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                   pObjectInfo->ParentObjectInformation,
-                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                                  lCount);
                 }
 
-                //
-                // And finally, release the Fcb if we acquired it.
-                //
-
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+                if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE))
+                {
+                    InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+
+                    ClearFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+
+                    AFSPerformObjectInvalidate( pObjectInfo,
+                                                AFS_INVALIDATE_DATA_VERSION);
+                }
+
+                lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanup (File) Decrement handle count on Fcb %08lX Cnt %d\n",
+                              pFcb,
+                              lCount);
+
                 break;
             }
 
@@ -639,14 +702,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 ASSERT( pFcb->OpenHandleCount != 0);
 
-                InterlockedDecrement( &pFcb->OpenHandleCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCleanup (Dir) Decrement handle count on Fcb %08lX Cnt %d\n",
-                              pFcb,
-                              pFcb->OpenHandleCount);
-
                 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
                 {
 
@@ -686,11 +741,12 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                 }
 
                 //
-                // If the count has dropped to zero and there is a pending delete
-                // then delete the node
+                // If the count has dropped to one and there is a pending delete
+                // then delete the node.  The final count will be decremented just
+                // before the Fcb->NPFcb->Resource is released.
                 //
 
-                if( pFcb->OpenHandleCount == 0 &&
+                if( pFcb->OpenHandleCount == 1 &&
                     BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                 {
 
@@ -717,8 +773,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                                   &pObjectInfo->FileId,
                                                   &stFileCleanup,
                                                   sizeof( AFSFileCleanupCB),
-                                                  NULL,
-                                                  NULL);
+                                                  pResultCB,
+                                                  &ulResultLen);
 
                     if( !NT_SUCCESS( ntStatus) &&
                         ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
@@ -749,10 +805,21 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                         ASSERT( pObjectInfo->ParentObjectInformation != NULL);
 
-                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
-                                                        pCcb,
-                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
-                                                        (ULONG)FILE_ACTION_REMOVED);
+                        AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                        TRUE);
+
+                        if ( pObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
+                        {
+
+                            SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                            pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+                        }
+                        else
+                        {
+
+                            pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = pResultCB->ParentDataVersion.QuadPart;
+                        }
 
                         //
                         // Now that the service has the entry has deleted we need to remove it from the parent
@@ -762,13 +829,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                         if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
                         {
 
-                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                                            TRUE);
-
                             AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
                                                 pCcb->DirectoryCB);
-
-                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
                         }
                         else
                         {
@@ -779,6 +841,14 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                           pCcb->DirectoryCB,
                                           &pCcb->DirectoryCB->NameInformation.FileName);
                         }
+
+                        AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
+                                                        pCcb,
+                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
+                                                        (ULONG)FILE_ACTION_REMOVED);
+
                     }
                 }
 
@@ -815,15 +885,38 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                     stFileCleanup.FileAccess = pCcb->FileAccess;
 
-                    AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
-                                       ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                       &pCcb->AuthGroup,
-                                       &pCcb->DirectoryCB->NameInformation.FileName,
-                                       &pObjectInfo->FileId,
-                                       &stFileCleanup,
-                                       sizeof( AFSFileCleanupCB),
-                                       NULL,
-                                       NULL);
+                    ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
+                                                  ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
+                                                  &pCcb->AuthGroup,
+                                                  &pCcb->DirectoryCB->NameInformation.FileName,
+                                                  &pObjectInfo->FileId,
+                                                  &stFileCleanup,
+                                                  sizeof( AFSFileCleanupCB),
+                                                  pResultCB,
+                                                  &ulResultLen);
+
+                    if ( NT_SUCCESS( ntStatus))
+                    {
+
+                        if ( pObjectInfo->ParentObjectInformation != NULL)
+                        {
+
+                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                              TRUE);
+
+                            if ( pObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart)
+                            {
+
+                                SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                                pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+                            }
+
+                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                        }
+                    }
+
+                    ntStatus = STATUS_SUCCESS;
                 }
 
                 //
@@ -862,21 +955,25 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                     ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);
 
-                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                    lCount = InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCleanup (Dir) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                   pObjectInfo->ParentObjectInformation,
-                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                                  lCount);
                 }
 
-                //
-                // And finally, release the Fcb if we acquired it.
-                //
-
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+                lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanup (Dir) Decrement handle count on Fcb %08lX Cnt %d\n",
+                              pFcb,
+                              lCount);
+
                 break;
             }
 
@@ -905,14 +1002,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 ASSERT( pFcb->OpenHandleCount != 0);
 
-                InterlockedDecrement( &pFcb->OpenHandleCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCleanup (MP/SL) Decrement handle count on Fcb %08lX Cnt %d\n",
-                              pFcb,
-                              pFcb->OpenHandleCount);
-
                 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
                 {
 
@@ -952,11 +1041,12 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                 }
 
                 //
-                // If the count has dropped to zero and there is a pending delete
-                // then delete the node
+                // If the count has dropped to one and there is a pending delete
+                // then delete the node.  The final count will be decremented just
+                // before the Fcb->NPFcb->Resource is released.
                 //
 
-                if( pFcb->OpenHandleCount == 0 &&
+                if( pFcb->OpenHandleCount == 1 &&
                     BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                 {
 
@@ -983,8 +1073,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                                   &pObjectInfo->FileId,
                                                   &stFileCleanup,
                                                   sizeof( AFSFileCleanupCB),
-                                                  NULL,
-                                                  NULL);
+                                                  pResultCB,
+                                                  &ulResultLen);
 
                     if( !NT_SUCCESS( ntStatus) &&
                         ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
@@ -1015,10 +1105,20 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                         ASSERT( pObjectInfo->ParentObjectInformation != NULL);
 
-                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
-                                                        pCcb,
-                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
-                                                        (ULONG)FILE_ACTION_REMOVED);
+                        AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                        TRUE);
+
+                        if ( pObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
+                        {
+
+                            SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                            pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+                        }
+                        else
+                        {
+                            pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = pResultCB->ParentDataVersion.QuadPart;
+                        }
 
                         //
                         // Now that the service has the entry has deleted we need to remove it from the parent
@@ -1028,13 +1128,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                         if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
                         {
 
-                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                                            TRUE);
-
                             AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
                                                 pCcb->DirectoryCB);
-
-                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
                         }
                         else
                         {
@@ -1045,6 +1140,14 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                           pCcb->DirectoryCB,
                                           &pCcb->DirectoryCB->NameInformation.FileName);
                         }
+
+                        AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
+                                                        pCcb,
+                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
+                                                        (ULONG)FILE_ACTION_REMOVED);
+
                     }
                 }
 
@@ -1081,15 +1184,38 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                     stFileCleanup.FileAccess = pCcb->FileAccess;
 
-                    AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
-                                       ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                       &pCcb->AuthGroup,
-                                       &pCcb->DirectoryCB->NameInformation.FileName,
-                                       &pObjectInfo->FileId,
-                                       &stFileCleanup,
-                                       sizeof( AFSFileCleanupCB),
-                                       NULL,
-                                       NULL);
+                    ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
+                                                  ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
+                                                  &pCcb->AuthGroup,
+                                                  &pCcb->DirectoryCB->NameInformation.FileName,
+                                                  &pObjectInfo->FileId,
+                                                  &stFileCleanup,
+                                                  sizeof( AFSFileCleanupCB),
+                                                  pResultCB,
+                                                  &ulResultLen);
+
+                    if ( NT_SUCCESS( ntStatus))
+                    {
+
+                        if ( pObjectInfo->ParentObjectInformation != NULL)
+                        {
+
+                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                              TRUE);
+
+                            if ( pObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart)
+                            {
+
+                                SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                                pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+                            }
+
+                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                        }
+                    }
+
+                    ntStatus = STATUS_SUCCESS;
                 }
 
                 //
@@ -1120,21 +1246,25 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                     ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);
 
-                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                    lCount = InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCleanup (MP/SL) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                   pObjectInfo->ParentObjectInformation,
-                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                                  lCount);
                 }
 
-                //
-                // And finally, release the Fcb if we acquired it.
-                //
-
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+                lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanup (MP/SL) Decrement handle count on Fcb %08lX Cnt %d\n",
+                              pFcb,
+                              lCount);
+
                 break;
             }
 
@@ -1152,14 +1282,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 ASSERT( pFcb->OpenHandleCount != 0);
 
-                InterlockedDecrement( &pFcb->OpenHandleCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCleanup (Share) Decrement handle count on Fcb %08lX Cnt %d\n",
-                              pFcb,
-                              pFcb->OpenHandleCount);
-
                 //
                 // Decrement the open child handle count
                 //
@@ -1168,21 +1290,25 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                     pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
                 {
 
-                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                    lCount = InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCleanup (Share) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                   pObjectInfo->ParentObjectInformation,
-                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                                  lCount);
                 }
 
-                //
-                // And finally, release the Fcb if we acquired it.
-                //
-
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+                lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanup (Share) Decrement handle count on Fcb %08lX Cnt %d\n",
+                              pFcb,
+                              lCount);
+
                 break;
             }
 
@@ -1199,6 +1325,12 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
 try_exit:
 
+        if( pResultCB != NULL)
+        {
+
+            AFSExFreePool( pResultCB);
+        }
+
         if( pFileObject != NULL)
         {