Windows: Trace DirectoryCB allocations
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFcbSupport.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSFcbSupport.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 //
42 // Function: AFSInitFcb
43 //
44 // Description:
45 //
46 //      This function performs Fcb initialization
47 //
48 // Return:
49 //
50 //      Return Fcb->NPFcb->Resource held exclusive
51 //
52
53 NTSTATUS
54 AFSInitFcb( IN AFSDirectoryCB  *DirEntry)
55 {
56
57     NTSTATUS ntStatus = STATUS_SUCCESS;
58     AFSFcb *pFcb = NULL;
59     AFSNonPagedFcb *pNPFcb = NULL;
60     USHORT  usFcbLength = 0;
61     AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL;
62     AFSVolumeCB *pVolumeCB = NULL;
63
64     __Enter
65     {
66
67         pObjectInfo = DirEntry->ObjectInformation;
68
69         pParentObjectInfo = pObjectInfo->ParentObjectInformation;
70
71         pVolumeCB = pObjectInfo->VolumeCB;
72
73         if ( pObjectInfo->Fcb != NULL)
74         {
75
76             AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
77                             TRUE);
78
79             try_return( ntStatus = STATUS_SUCCESS);
80         }
81
82         //
83         // Allocate the Fcb and the nonpaged portion of the Fcb.
84         //
85
86         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
87                       AFS_TRACE_LEVEL_VERBOSE_2,
88                       "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
89                       &DirEntry->NameInformation.FileName,
90                       pObjectInfo->FileId.Cell,
91                       pObjectInfo->FileId.Volume,
92                       pObjectInfo->FileId.Vnode,
93                       pObjectInfo->FileId.Unique);
94
95         usFcbLength = sizeof( AFSFcb);
96
97         pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
98                                                    usFcbLength,
99                                                    AFS_FCB_ALLOCATION_TAG);
100
101         if( pFcb == NULL)
102         {
103
104             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
105                           AFS_TRACE_LEVEL_ERROR,
106                           "AFSInitFcb Failed to allocate fcb\n");
107
108             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
109         }
110
111         RtlZeroMemory( pFcb,
112                        usFcbLength);
113
114         pFcb->Header.NodeByteSize = usFcbLength;
115
116         pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
117                                                              sizeof( AFSNonPagedFcb),
118                                                              AFS_FCB_NP_ALLOCATION_TAG);
119
120         if( pNPFcb == NULL)
121         {
122
123             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
124                           AFS_TRACE_LEVEL_ERROR,
125                           "AFSInitFcb Failed to allocate non-paged fcb\n");
126
127             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
128         }
129
130         RtlZeroMemory( pNPFcb,
131                        sizeof( AFSNonPagedFcb));
132
133         pNPFcb->Size = sizeof( AFSNonPagedFcb);
134
135         pNPFcb->Type = AFS_NON_PAGED_FCB;
136
137         //
138         // Initialize the advanced header
139         //
140
141         ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
142
143         FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
144
145         //
146         // OK, initialize the entry
147         //
148
149         ExInitializeResourceLite( &pNPFcb->Resource);
150
151         ExInitializeResourceLite( &pNPFcb->PagingResource);
152
153         ExInitializeResourceLite( &pNPFcb->SectionObjectResource);
154
155         ExInitializeResourceLite( &pNPFcb->CcbListLock);
156
157         pFcb->Header.Resource = &pNPFcb->Resource;
158
159         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
160
161         //
162         // Grab the Fcb for processing
163         //
164
165         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
166                       AFS_TRACE_LEVEL_VERBOSE,
167                       "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
168                       &pNPFcb->Resource,
169                       PsGetCurrentThread());
170
171         AFSAcquireExcl( &pNPFcb->Resource,
172                         TRUE);
173
174         pFcb->NPFcb = pNPFcb;
175
176         //
177         // Set type specific information
178         //
179
180         if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
181         {
182
183             //
184             // Reset the type to a directory type
185             //
186
187             pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
188         }
189         else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
190         {
191
192             pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
193
194             //
195             // Initialize the file specific information
196             //
197
198             FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
199                                      NULL,
200                                      NULL);
201
202             //
203             // Initialize the header file sizes to our dir entry information
204             //
205
206             pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
207             pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
208             pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
209
210             //
211             // Initialize the Extents resources and so forth.  The
212             // quiescent state is that no one has the extents for
213             // IO (do the extents are not busy) and there is no
214             // extents request outstanding (and hence the "last
215             // one" is complete).
216             //
217             ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
218
219             KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
220                                NotificationEvent,
221                                TRUE );
222
223             for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
224             {
225                 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
226             }
227
228             pNPFcb->Specific.File.DirtyListHead = NULL;
229             pNPFcb->Specific.File.DirtyListTail = NULL;
230
231             ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
232
233             KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
234                                SynchronizationEvent,
235                                TRUE);
236
237             KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
238                                NotificationEvent,
239                                TRUE);
240         }
241         else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
242         {
243
244             pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
245         }
246         else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
247         {
248
249             pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
250         }
251         else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
252         {
253
254             pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
255         }
256         else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
257         {
258
259             pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
260         }
261         else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
262         {
263             pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
264         }
265         else
266         {
267             pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
268         }
269
270         pFcb->ObjectInformation = pObjectInfo;
271
272         AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
273                           TRUE);
274         //
275         // Swap the allocated FCB into the ObjectInformation structure if it
276         // does not already have one.
277         //
278
279         if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
280         {
281
282             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
283                           AFS_TRACE_LEVEL_WARNING,
284                           "AFSInitFcb Raced Fcb %p pFcb %p Name %wZ\n",
285                           pObjectInfo->Fcb,
286                           pFcb,
287                           &DirEntry->NameInformation.FileName);
288
289             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
290                           AFS_TRACE_LEVEL_VERBOSE,
291                           "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
292                           &pObjectInfo->Fcb->NPFcb->Resource,
293                           PsGetCurrentThread());
294
295             AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
296
297             AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
298                             TRUE);
299
300             try_return( ntStatus = STATUS_REPARSE);
301         }
302
303         AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
304
305         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
306                       AFS_TRACE_LEVEL_VERBOSE,
307                       "AFSInitFcb Initialized Fcb %p Name %wZ\n",
308                       &pObjectInfo->Fcb,
309                       &DirEntry->NameInformation.FileName);
310
311 try_exit:
312
313         if( ntStatus != STATUS_SUCCESS)
314         {
315
316             if ( !NT_SUCCESS( ntStatus))
317             {
318
319                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
320                               AFS_TRACE_LEVEL_ERROR,
321                               "AFSInitFcb Failed to initialize fcb Status %08lX\n",
322                               ntStatus);
323             }
324
325             if( pFcb != NULL)
326             {
327
328                 if( pNPFcb != NULL)
329                 {
330
331                     AFSReleaseResource( &pNPFcb->Resource);
332
333                     FsRtlTeardownPerStreamContexts( &pFcb->Header);
334
335                     if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
336                     {
337
338                         FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
339
340                         ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
341
342                         ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
343                     }
344
345                     ExDeleteResourceLite( &pNPFcb->SectionObjectResource);
346
347                     ExDeleteResourceLite( &pNPFcb->PagingResource);
348
349                     ExDeleteResourceLite( &pNPFcb->CcbListLock);
350
351                     ExDeleteResourceLite( &pNPFcb->Resource);
352
353                     AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG);
354                 }
355
356                 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
357             }
358         }
359     }
360
361     return ntStatus;
362 }
363
364 NTSTATUS
365 AFSInitVolume( IN GUID *AuthGroup,
366                IN AFSFileID *RootFid,
367                OUT AFSVolumeCB **VolumeCB)
368 {
369
370     NTSTATUS ntStatus = STATUS_SUCCESS;
371     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
372     AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
373     AFSVolumeCB *pVolumeCB = NULL;
374     AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
375     ULONGLONG ullIndex = 0;
376     BOOLEAN bReleaseLocks = FALSE;
377     AFSVolumeInfoCB stVolumeInformation = {0};
378     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
379     LONG lCount;
380
381     __Enter
382     {
383
384         //
385         // Before grabbing any locks ask the service for the volume information
386         // This may be a waste but we need to get this information prior to
387         // taking any volume tree locks. Don't do this for any 'reserved' cell entries
388         //
389
390         if( RootFid->Cell != 0)
391         {
392
393             RtlZeroMemory( &stVolumeInformation,
394                            sizeof( AFSVolumeInfoCB));
395
396             ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
397                                                      RootFid,
398                                                      &stVolumeInformation);
399
400             if( !NT_SUCCESS( ntStatus))
401             {
402
403                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
404                               AFS_TRACE_LEVEL_ERROR,
405                               "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
406                               ntStatus);
407
408                 try_return( ntStatus);
409             }
410
411             //
412             // Grab our tree locks and see if we raced with someone else
413             //
414
415             AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
416                             TRUE);
417
418             AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
419                             TRUE);
420
421             bReleaseLocks = TRUE;
422
423             ullIndex = AFSCreateHighIndex( RootFid);
424
425             ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
426                                            ullIndex,
427                                            (AFSBTreeEntry **)&pVolumeCB);
428
429             if( NT_SUCCESS( ntStatus) &&
430                 pVolumeCB != NULL)
431             {
432
433                 //
434                 // So we don't lock with an invalidation call ...
435                 //
436
437                 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
438
439                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
440                               AFS_TRACE_LEVEL_VERBOSE,
441                               "AFSInitVolume Increment count on volume %p Cnt %d\n",
442                               pVolumeCB,
443                               lCount);
444
445                 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
446
447                 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
448
449                 bReleaseLocks = FALSE;
450
451                 AFSAcquireExcl( pVolumeCB->VolumeLock,
452                                 TRUE);
453
454                 *VolumeCB = pVolumeCB;
455
456                 try_return( ntStatus);
457             }
458
459             //
460             // Revert our status from the above call back to success.
461             //
462
463             ntStatus = STATUS_SUCCESS;
464         }
465
466         //
467         // For the global root we allocate out volume node and insert it
468         // into the volume tree ...
469         //
470
471         pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( PagedPool,
472                                                              sizeof( AFSVolumeCB),
473                                                              AFS_VCB_ALLOCATION_TAG);
474
475         if( pVolumeCB == NULL)
476         {
477
478             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
479                           AFS_TRACE_LEVEL_ERROR,
480                           "AFSInitVolume Failed to allocate the root volume cb\n");
481
482             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
483         }
484
485         RtlZeroMemory( pVolumeCB,
486                        sizeof( AFSVolumeCB));
487
488         //
489         // The non paged portion
490         //
491
492         pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
493                                                                         sizeof( AFSNonPagedVolumeCB),
494                                                                         AFS_VCB_NP_ALLOCATION_TAG);
495
496         if( pNonPagedVcb == NULL)
497         {
498
499             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
500                           AFS_TRACE_LEVEL_ERROR,
501                           "AFSInitVolume Failed to allocate the root non paged volume cb\n");
502
503             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
504         }
505
506         RtlZeroMemory( pNonPagedVcb,
507                        sizeof( AFSNonPagedVolumeCB));
508
509         ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
510
511         ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
512
513         pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
514                                                                                sizeof( AFSNonPagedObjectInfoCB),
515                                                                                AFS_NP_OBJECT_INFO_TAG);
516
517         if( pNonPagedObject == NULL)
518         {
519
520             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
521                           AFS_TRACE_LEVEL_ERROR,
522                           "AFSInitVolume Failed to allocate the root non paged object cb\n");
523
524             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
525         }
526
527         RtlZeroMemory( pNonPagedObject,
528                        sizeof( AFSNonPagedObjectInfoCB));
529
530         ExInitializeResourceLite( &pNonPagedObject->ObjectInfoLock);
531
532         ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
533
534         pVolumeCB->NonPagedVcb = pNonPagedVcb;
535
536         pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
537
538         pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
539
540         pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
541
542         pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
543
544         //
545         // Bias our reference by 1
546         //
547
548         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
549                       AFS_TRACE_LEVEL_VERBOSE,
550                       "AFSInitVolume Initializing count (2) on volume %p\n",
551                       pVolumeCB);
552
553         pVolumeCB->VolumeReferenceCount = 2;
554
555         AFSAcquireExcl( pVolumeCB->VolumeLock,
556                         TRUE);
557
558         pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
559                                                                              sizeof( AFSDirectoryCB) + sizeof( WCHAR),
560                                                                              AFS_DIR_ENTRY_TAG);
561
562         if( pVolumeCB->DirectoryCB == NULL)
563         {
564
565             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
566         }
567
568         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
569                       AFS_TRACE_LEVEL_VERBOSE,
570                       "AFSInitVolume AFS_DIR_ENTRY_TAG allocated %p\n",
571                       pVolumeCB->DirectoryCB);
572
573         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
574                                                                                 sizeof( AFSNonPagedDirectoryCB),
575                                                                                 AFS_DIR_ENTRY_NP_TAG);
576
577         if( pNonPagedDirEntry == NULL)
578         {
579
580             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
581         }
582
583         RtlZeroMemory( pVolumeCB->DirectoryCB,
584                        sizeof( AFSDirectoryCB) + sizeof( WCHAR));
585
586         RtlZeroMemory( pNonPagedDirEntry,
587                        sizeof( AFSNonPagedDirectoryCB));
588
589         ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
590
591         pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
592
593         //
594         // Initialize the non-paged portion of the directory entry
595         //
596
597         KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
598         KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
599         KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
600
601         pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
602
603         SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
604
605         pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
606         pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
607         pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
608         pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
609         pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
610
611         pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
612
613         pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
614
615         pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
616
617         pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
618
619         RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
620                        L"\\",
621                        sizeof( WCHAR));
622
623         //
624         // Copy in the volume information retrieved above
625         //
626
627         RtlCopyMemory( &pVolumeCB->VolumeInformation,
628                        &stVolumeInformation,
629                        sizeof( AFSVolumeInfoCB));
630
631         //
632         // Setup pointers
633         //
634
635         pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
636
637         pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
638
639         //
640         // Insert the volume into our volume tree. Don't insert any reserved entries
641         //
642
643         if( RootFid->Cell != 0)
644         {
645
646             pVolumeCB->TreeEntry.HashIndex = ullIndex;
647
648             if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
649             {
650
651                 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
652
653                 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
654             }
655             else
656             {
657
658                 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
659                                                      &pVolumeCB->TreeEntry)))
660                 {
661
662                     SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
663                 }
664             }
665
666             if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
667             {
668
669                 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
670             }
671             else
672             {
673
674                 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
675
676                 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
677             }
678
679             pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
680         }
681
682         *VolumeCB = pVolumeCB;
683
684 try_exit:
685
686         if( !NT_SUCCESS( ntStatus))
687         {
688
689             if( pNonPagedVcb != NULL)
690             {
691
692                 AFSReleaseResource( pVolumeCB->VolumeLock);
693
694                 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
695
696                 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
697
698                 AFSExFreePoolWithTag( pNonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
699             }
700
701             if( pNonPagedObject != NULL)
702             {
703
704                 ExDeleteResourceLite( &pNonPagedObject->ObjectInfoLock);
705
706                 AFSExFreePoolWithTag( pNonPagedObject, AFS_NP_OBJECT_INFO_TAG);
707             }
708
709             if( pVolumeCB != NULL)
710             {
711
712                 if( pVolumeCB->DirectoryCB != NULL)
713                 {
714
715                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
716                                   AFS_TRACE_LEVEL_VERBOSE,
717                                   "AFSInitVolume AFS_DIR_ENTRY_TAG deallocating %p\n",
718                                   pVolumeCB->DirectoryCB);
719
720                     AFSExFreePoolWithTag( pVolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
721                 }
722
723                 AFSExFreePoolWithTag( pVolumeCB, AFS_VCB_ALLOCATION_TAG);
724             }
725
726             if( pNonPagedDirEntry != NULL)
727             {
728
729                 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
730
731                 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
732             }
733         }
734
735         if( bReleaseLocks)
736         {
737
738             AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
739
740             AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
741         }
742     }
743
744     return ntStatus;
745 }
746
747 NTSTATUS
748 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
749 {
750
751     NTSTATUS ntStatus = STATUS_SUCCESS;
752     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
753
754     __Enter
755     {
756
757         //
758         // Remove the volume from the tree and list
759         // Don't process the list information for reserved entries
760         //
761
762         if( VolumeCB->ObjectInformation.FileId.Cell != 0)
763         {
764
765             if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
766             {
767
768                 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
769                                     &VolumeCB->TreeEntry);
770             }
771
772             if( VolumeCB->ListEntry.fLink == NULL)
773             {
774
775                 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
776
777                 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
778                 {
779
780                     pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
781                 }
782             }
783             else
784             {
785
786                 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
787             }
788
789             if( VolumeCB->ListEntry.bLink == NULL)
790             {
791
792                 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
793
794                 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
795                 {
796
797                     pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
798                 }
799             }
800             else
801             {
802
803                 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
804             }
805         }
806
807         //
808         // Remove any PIOctl objects we have
809         //
810
811         if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
812         {
813
814             if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
815             {
816
817                 AFSAcquireExcl( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
818                                 TRUE);
819
820                 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
821
822                 AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
823             }
824
825             AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
826
827             ExDeleteResourceLite( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
828
829             AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
830
831             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
832                           AFS_TRACE_LEVEL_VERBOSE,
833                           "AFSRemoveVolume (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n",
834                           VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
835
836             AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
837         }
838
839         if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
840         {
841
842             //
843             // Release the fid in the service
844             //
845
846             AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
847         }
848
849         //
850         // Free up the memory
851         //
852
853         if( VolumeCB->NonPagedVcb != NULL)
854         {
855
856             if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
857             {
858                 AFSReleaseResource( VolumeCB->VolumeLock);
859             }
860
861             ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
862
863             ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
864
865             AFSExFreePoolWithTag( VolumeCB->NonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
866         }
867
868         if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
869         {
870
871             ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
872
873             ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
874
875             AFSExFreePoolWithTag( VolumeCB->ObjectInformation.NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
876         }
877
878         if( VolumeCB->DirectoryCB != NULL)
879         {
880
881             if( VolumeCB->DirectoryCB->NonPaged != NULL)
882             {
883
884                 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
885
886                 AFSExFreePoolWithTag( VolumeCB->DirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
887             }
888
889             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
890                           AFS_TRACE_LEVEL_VERBOSE,
891                           "AFSRemoveVolume AFS_DIR_ENTRY_TAG deallocating %p\n",
892                           VolumeCB->DirectoryCB);
893
894             AFSExFreePoolWithTag( VolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
895         }
896
897         AFSExFreePoolWithTag( VolumeCB, AFS_VCB_ALLOCATION_TAG);
898     }
899
900     return ntStatus;
901 }
902
903
904 //
905 // Function: AFSInitRootFcb
906 //
907 // Description:
908 //
909 //      This function performs Root node Fcb initialization
910 //
911 // Return:
912 //
913 //      A status is returned for the function
914 //
915
916 NTSTATUS
917 AFSInitRootFcb( IN ULONGLONG ProcessID,
918                 IN AFSVolumeCB *VolumeCB)
919 {
920
921     UNREFERENCED_PARAMETER(ProcessID);
922     NTSTATUS ntStatus = STATUS_SUCCESS;
923     AFSFcb *pFcb = NULL;
924     AFSNonPagedFcb *pNPFcb = NULL;
925
926     __Enter
927     {
928
929         //
930         // Initialize the root fcb
931         //
932
933         pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
934                                                    sizeof( AFSFcb),
935                                                    AFS_FCB_ALLOCATION_TAG);
936
937         if( pFcb == NULL)
938         {
939
940             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
941                           AFS_TRACE_LEVEL_ERROR,
942                           "AFSInitRootFcb Failed to allocate the root fcb\n");
943
944             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
945         }
946
947         RtlZeroMemory( pFcb,
948                        sizeof( AFSFcb));
949
950         pFcb->Header.NodeByteSize = sizeof( AFSFcb);
951         pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
952
953         pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
954                                                              sizeof( AFSNonPagedFcb),
955                                                              AFS_FCB_NP_ALLOCATION_TAG);
956
957         if( pNPFcb == NULL)
958         {
959
960             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
961                           AFS_TRACE_LEVEL_ERROR,
962                           "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
963
964             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
965         }
966
967         RtlZeroMemory( pNPFcb,
968                        sizeof( AFSNonPagedFcb));
969
970         pNPFcb->Size = sizeof( AFSNonPagedFcb);
971         pNPFcb->Type = AFS_NON_PAGED_FCB;
972
973         //
974         // OK, initialize the entry
975         //
976
977         ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
978
979         FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
980
981         ExInitializeResourceLite( &pNPFcb->Resource);
982
983         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
984                       AFS_TRACE_LEVEL_VERBOSE,
985                       "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
986                       &pNPFcb->Resource,
987                       PsGetCurrentThread());
988
989         AFSAcquireExcl( &pNPFcb->Resource,
990                         TRUE);
991
992         ExInitializeResourceLite( &pNPFcb->PagingResource);
993
994         ExInitializeResourceLite( &pNPFcb->CcbListLock);
995
996         pFcb->Header.Resource = &pNPFcb->Resource;
997
998         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
999
1000         pFcb->NPFcb = pNPFcb;
1001
1002         //
1003         // Save the root Fcb in the VolumeCB
1004         //
1005
1006         VolumeCB->ObjectInformation.Fcb = pFcb;
1007
1008         VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
1009
1010         VolumeCB->RootFcb = pFcb;
1011
1012         pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
1013
1014 try_exit:
1015
1016         if( !NT_SUCCESS( ntStatus))
1017         {
1018
1019             if( pFcb != NULL)
1020             {
1021
1022                 AFSRemoveRootFcb( pFcb);
1023             }
1024         }
1025     }
1026
1027     return ntStatus;
1028 }
1029
1030 //
1031 // Function: AFSRemoveRootFcb
1032 //
1033 // Description:
1034 //
1035 //      This function performs root Fcb removal/deallocation
1036 //
1037 // Return:
1038 //
1039 //      A status is returned for the function
1040 //
1041
1042 void
1043 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
1044 {
1045
1046     if( RootFcb->NPFcb != NULL)
1047     {
1048
1049         //
1050         // Now the resource
1051         //
1052
1053         ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1054
1055         ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1056
1057         ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1058
1059         //
1060         // The non paged region
1061         //
1062
1063         AFSExFreePoolWithTag( RootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1064     }
1065
1066     //
1067     // And the Fcb itself
1068     //
1069
1070     AFSExFreePoolWithTag( RootFcb, AFS_FCB_ALLOCATION_TAG);
1071
1072     return;
1073 }
1074
1075 //
1076 // Function: AFSRemoveFcb
1077 //
1078 // Description:
1079 //
1080 //      This function performs Fcb removal/deallocation
1081 //
1082 // Return:
1083 //
1084 //      A status is returned for the function
1085 //
1086
1087 void
1088 AFSRemoveFcb( IN AFSFcb **ppFcb)
1089 {
1090
1091     AFSFcb * pFcb;
1092
1093     pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1094
1095     if ( pFcb == NULL)
1096     {
1097
1098         return;
1099     }
1100
1101     //
1102     // Uninitialize the file lock if it is a file
1103     //
1104
1105     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1106                   AFS_TRACE_LEVEL_VERBOSE,
1107                   "AFSRemoveFcb Removing Fcb %p\n",
1108                   pFcb);
1109
1110     if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1111     {
1112
1113         FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1114
1115         //
1116         // The resource we allocated
1117         //
1118
1119         ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1120
1121         ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1122
1123     }
1124     else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1125     {
1126
1127
1128     }
1129
1130     //
1131     // Tear down the FM specific contexts
1132     //
1133
1134     FsRtlTeardownPerStreamContexts( &pFcb->Header);
1135
1136     //
1137     // Delete the resources
1138     //
1139
1140     ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1141
1142     ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1143
1144     ExDeleteResourceLite( &pFcb->NPFcb->SectionObjectResource);
1145
1146     ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1147
1148     //
1149     // The non paged region
1150     //
1151
1152     AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1153
1154     //
1155     // And the Fcb itself, which includes the name
1156     //
1157
1158     AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
1159
1160     return;
1161 }
1162
1163 NTSTATUS
1164 AFSInitCcb( IN OUT AFSCcb **Ccb,
1165             IN     AFSDirectoryCB *DirectoryCB,
1166             IN     ACCESS_MASK     GrantedAccess,
1167             IN     ULONG           FileAccess)
1168 {
1169
1170     NTSTATUS Status = STATUS_SUCCESS;
1171     AFSCcb *pCcb = NULL;
1172     LONG lCount;
1173
1174     __Enter
1175     {
1176
1177         //
1178         // Allocate our context control block
1179         //
1180
1181         pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1182                                                    sizeof( AFSCcb),
1183                                                    AFS_CCB_ALLOCATION_TAG);
1184
1185         if( pCcb == NULL)
1186         {
1187
1188             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1189                           AFS_TRACE_LEVEL_ERROR,
1190                           "AFSInitCcb Failed to allocate Ccb\n");
1191
1192             try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1193         }
1194
1195         RtlZeroMemory( pCcb,
1196                        sizeof( AFSCcb));
1197
1198         pCcb->Size = sizeof( AFSCcb);
1199
1200         pCcb->Type = AFS_CCB;
1201
1202         pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
1203                                                      sizeof( AFSNonPagedCcb),
1204                                                      AFS_CCB_NP_ALLOCATION_TAG);
1205
1206         if( pCcb->NPCcb == NULL)
1207         {
1208
1209             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1210                           AFS_TRACE_LEVEL_ERROR,
1211                           "AFSInitCcb Failed to allocate NPCcb\n");
1212
1213             try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1214         }
1215
1216         ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
1217
1218         pCcb->DirectoryCB = DirectoryCB;
1219
1220         lCount = InterlockedIncrement( &pCcb->DirectoryCB->DirOpenReferenceCount);
1221
1222         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1223                       AFS_TRACE_LEVEL_VERBOSE,
1224                       "AFSInitCcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1225                       &pCcb->DirectoryCB->NameInformation.FileName,
1226                       pCcb->DirectoryCB,
1227                       pCcb,
1228                       lCount);
1229
1230         pCcb->GrantedAccess = GrantedAccess;
1231
1232         pCcb->FileAccess = FileAccess;
1233
1234         //
1235         // Return the Ccb
1236         //
1237
1238         *Ccb = pCcb;
1239
1240 try_exit:
1241
1242         if( !NT_SUCCESS( Status))
1243         {
1244
1245             if( pCcb != NULL)
1246             {
1247
1248                 if ( pCcb->NPCcb != NULL)
1249                 {
1250
1251                     AFSExFreePoolWithTag( pCcb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1252                 }
1253
1254                 AFSExFreePoolWithTag( pCcb, AFS_CCB_ALLOCATION_TAG);
1255             }
1256
1257             *Ccb = NULL;
1258         }
1259     }
1260
1261     return Status;
1262 }
1263
1264 //
1265 // Function: AFSRemoveCcb
1266 //
1267 // Description:
1268 //
1269 //      This function performs Ccb removal/deallocation
1270 //
1271 // Return:
1272 //
1273 //      None
1274 //
1275
1276 void
1277 AFSRemoveCcb( IN AFSFcb *Fcb,
1278               IN AFSCcb *Ccb)
1279 {
1280
1281     LONG lCount;
1282
1283     AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1284                     TRUE);
1285
1286     if( Fcb != NULL &&
1287         BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1288     {
1289
1290         AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1291                         TRUE);
1292
1293         if( Ccb->ListEntry.fLink == NULL)
1294         {
1295
1296             Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1297
1298             if( Fcb->CcbListTail != NULL)
1299             {
1300                 Fcb->CcbListTail->ListEntry.fLink = NULL;
1301             }
1302         }
1303         else
1304         {
1305             ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1306         }
1307
1308         if( Ccb->ListEntry.bLink == NULL)
1309         {
1310
1311             Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1312
1313             if( Fcb->CcbListHead != NULL)
1314             {
1315                 Fcb->CcbListHead->ListEntry.bLink = NULL;
1316             }
1317         }
1318         else
1319         {
1320             ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1321         }
1322
1323         AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1324     }
1325
1326     if( Ccb->MaskName.Buffer != NULL)
1327     {
1328
1329         AFSExFreePoolWithTag( Ccb->MaskName.Buffer, AFS_GENERIC_MEMORY_6_TAG);
1330     }
1331
1332     if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1333     {
1334
1335         AFSExFreePoolWithTag( Ccb->FullFileName.Buffer, 0);
1336     }
1337
1338     //
1339     // If we have a name array then delete it
1340     //
1341
1342     if( Ccb->NameArray != NULL)
1343     {
1344
1345         AFSFreeNameArray( Ccb->NameArray);
1346
1347         Ccb->NameArray = NULL;
1348     }
1349
1350     if( Ccb->DirectorySnapshot != NULL)
1351     {
1352
1353         AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
1354
1355         Ccb->DirectorySnapshot = NULL;
1356     }
1357
1358     if( Ccb->NotifyMask.Buffer != NULL)
1359     {
1360
1361         AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
1362     }
1363
1364     if ( Ccb->DirectoryCB != NULL)
1365     {
1366
1367         lCount = InterlockedDecrement( &Ccb->DirectoryCB->DirOpenReferenceCount);
1368
1369         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1370                       AFS_TRACE_LEVEL_VERBOSE,
1371                       "AFSRemoveCcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1372                       &Ccb->DirectoryCB->NameInformation.FileName,
1373                       Ccb->DirectoryCB,
1374                       Ccb,
1375                       lCount);
1376
1377         ASSERT( lCount >= 0);
1378     }
1379
1380     AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1381
1382     //
1383     // Free up the Ccb
1384     //
1385
1386     ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
1387
1388     AFSExFreePoolWithTag( Ccb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1389
1390     AFSExFreePoolWithTag( Ccb, AFS_CCB_ALLOCATION_TAG);
1391 }
1392
1393 NTSTATUS
1394 AFSInsertCcb( IN AFSFcb *Fcb,
1395               IN AFSCcb *Ccb)
1396 {
1397
1398     NTSTATUS ntStatus = STATUS_SUCCESS;
1399
1400     AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1401                     TRUE);
1402
1403     AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1404                     TRUE);
1405
1406     if( Fcb->CcbListHead == NULL)
1407     {
1408         Fcb->CcbListHead = Ccb;
1409     }
1410     else
1411     {
1412         Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1413
1414         Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1415     }
1416
1417     Fcb->CcbListTail = Ccb;
1418
1419     SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1420
1421     AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1422
1423     AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1424
1425     return ntStatus;
1426 }