2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
11 /* INCLUDES *****************************************************************/
15 /* GLOBALS ***************************************************************/
17 extern PRFSD_GLOBAL RfsdGlobal
;
19 /* DEFINITIONS *************************************************************/
22 #pragma alloc_text(PAGE, RfsdAllocateIrpContext)
23 #pragma alloc_text(PAGE, RfsdFreeIrpContext)
24 #pragma alloc_text(PAGE, RfsdAllocateFcb)
25 #pragma alloc_text(PAGE, RfsdFreeFcb)
26 #pragma alloc_text(PAGE, RfsdAllocateMcb)
27 #pragma alloc_text(PAGE, RfsdSearchMcbTree)
28 #pragma alloc_text(PAGE, RfsdSearchMcb)
29 #pragma alloc_text(PAGE, RfsdGetFullFileName)
30 #pragma alloc_text(PAGE, RfsdRefreshMcb)
31 #pragma alloc_text(PAGE, RfsdAddMcbNode)
32 #pragma alloc_text(PAGE, RfsdDeleteMcbNode)
33 #pragma alloc_text(PAGE, RfsdFreeMcbTree)
35 #pragma alloc_text(PAGE, RfsdCheckBitmapConsistency)
36 #pragma alloc_text(PAGE, RfsdCheckSetBlock)
37 #endif // !RFSD_READ_ONLY
38 #pragma alloc_text(PAGE, RfsdInitializeVcb)
39 #pragma alloc_text(PAGE, RfsdFreeCcb)
40 #pragma alloc_text(PAGE, RfsdAllocateCcb)
41 #pragma alloc_text(PAGE, RfsdFreeVcb)
42 #pragma alloc_text(PAGE, RfsdCreateFcbFromMcb)
43 #pragma alloc_text(PAGE, RfsdSyncUninitializeCacheMap)
46 __drv_mustHoldCriticalRegion
48 RfsdAllocateIrpContext (IN PDEVICE_OBJECT DeviceObject
,
51 PIO_STACK_LOCATION IoStackLocation
;
52 PRFSD_IRP_CONTEXT IrpContext
;
56 ASSERT(DeviceObject
!= NULL
);
59 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
61 ExAcquireResourceExclusiveLite(
62 &RfsdGlobal
->LAResource
,
65 IrpContext
= (PRFSD_IRP_CONTEXT
) (
66 ExAllocateFromNPagedLookasideList(
67 &(RfsdGlobal
->RfsdIrpContextLookasideList
)));
69 ExReleaseResourceForThreadLite(
70 &RfsdGlobal
->LAResource
,
71 ExGetCurrentResourceThread() );
73 if (IrpContext
== NULL
) {
75 IrpContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(RFSD_IRP_CONTEXT
), RFSD_POOL_TAG
);
78 // Zero out the irp context and indicate that it is from pool and
79 // not region allocated
82 RtlZeroMemory(IrpContext
, sizeof(RFSD_IRP_CONTEXT
));
84 SetFlag(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FROM_POOL
);
89 // Zero out the irp context and indicate that it is from zone and
93 RtlZeroMemory(IrpContext
, sizeof(RFSD_IRP_CONTEXT
) );
100 IrpContext
->Identifier
.Type
= RFSDICX
;
101 IrpContext
->Identifier
.Size
= sizeof(RFSD_IRP_CONTEXT
);
103 IrpContext
->Irp
= Irp
;
105 IrpContext
->MajorFunction
= IoStackLocation
->MajorFunction
;
106 IrpContext
->MinorFunction
= IoStackLocation
->MinorFunction
;
108 IrpContext
->DeviceObject
= DeviceObject
;
110 IrpContext
->FileObject
= IoStackLocation
->FileObject
;
112 if (IrpContext
->FileObject
!= NULL
) {
113 IrpContext
->RealDevice
= IrpContext
->FileObject
->DeviceObject
;
114 } else if (IrpContext
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
) {
115 if (IoStackLocation
->Parameters
.MountVolume
.Vpb
) {
116 IrpContext
->RealDevice
=
117 IoStackLocation
->Parameters
.MountVolume
.Vpb
->RealDevice
;
121 if (IrpContext
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
122 IrpContext
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
123 IrpContext
->MajorFunction
== IRP_MJ_SHUTDOWN
) {
124 IrpContext
->IsSynchronous
= TRUE
;
125 } else if (IrpContext
->MajorFunction
== IRP_MJ_CLEANUP
||
126 IrpContext
->MajorFunction
== IRP_MJ_CLOSE
) {
127 IrpContext
->IsSynchronous
= FALSE
;
129 #if (_WIN32_WINNT >= 0x0500)
130 else if (IrpContext
->MajorFunction
== IRP_MJ_PNP
) {
131 if (IoGetCurrentIrpStackLocation(Irp
)->FileObject
== NULL
) {
132 IrpContext
->IsSynchronous
= TRUE
;
134 IrpContext
->IsSynchronous
= IoIsOperationSynchronous(Irp
);
137 #endif //(_WIN32_WINNT >= 0x0500)
139 IrpContext
->IsSynchronous
= IoIsOperationSynchronous(Irp
);
144 // Temporary workaround for a bug in close that makes it reference a
145 // fileobject when it is no longer valid.
147 if (IrpContext
->MajorFunction
== IRP_MJ_CLOSE
) {
148 IrpContext
->IsSynchronous
= TRUE
;
152 IrpContext
->IsTopLevel
= (IoGetTopLevelIrp() == Irp
);
154 IrpContext
->ExceptionInProgress
= FALSE
;
160 RfsdCompleteIrpContext (
161 IN PRFSD_IRP_CONTEXT IrpContext
,
167 Irp
= IrpContext
->Irp
;
171 if (NT_ERROR(Status
)) {
172 Irp
->IoStatus
.Information
= 0;
175 Irp
->IoStatus
.Status
= Status
;
176 bPrint
= !IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_REQUEUED
);
179 Irp
, bPrint
, (CCHAR
)(NT_SUCCESS(Status
)?
180 IO_DISK_INCREMENT
: IO_NO_INCREMENT
) );
182 IrpContext
->Irp
= NULL
;
185 RfsdFreeIrpContext(IrpContext
);
190 __drv_mustHoldCriticalRegion
192 RfsdFreeIrpContext (IN PRFSD_IRP_CONTEXT IrpContext
)
196 ASSERT(IrpContext
!= NULL
);
198 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
199 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
201 RfsdUnpinRepinnedBcbs(IrpContext
);
203 // Return the Irp context record to the region or to pool depending on
206 if (FlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FROM_POOL
)) {
208 IrpContext
->Identifier
.Type
= 0;
209 IrpContext
->Identifier
.Size
= 0;
211 ExFreePool( IrpContext
);
215 IrpContext
->Identifier
.Type
= 0;
216 IrpContext
->Identifier
.Size
= 0;
218 ExAcquireResourceExclusiveLite(
219 &RfsdGlobal
->LAResource
,
222 ExFreeToNPagedLookasideList(&(RfsdGlobal
->RfsdIrpContextLookasideList
), IrpContext
);
224 ExReleaseResourceForThreadLite(
225 &RfsdGlobal
->LAResource
,
226 ExGetCurrentResourceThread() );
233 IN PRFSD_IRP_CONTEXT IrpContext
,
237 PRFSD_REPINNED_BCBS Repinned
;
239 Repinned
= &IrpContext
->Repinned
;
249 for (i
= 0; i
< RFSD_REPINNED_BCBS_ARRAY_SIZE
; i
+= 1) {
250 if (Repinned
->Bcb
[i
] == Bcb
) {
255 Repinned
= Repinned
->Next
;
260 for (i
= 0; i
< RFSD_REPINNED_BCBS_ARRAY_SIZE
; i
+= 1) {
261 if (Repinned
->Bcb
[i
] == Bcb
) {
265 if (Repinned
->Bcb
[i
] == NULL
) {
266 Repinned
->Bcb
[i
] = Bcb
;
273 if (Repinned
->Next
== NULL
) {
274 Repinned
->Next
= ExAllocatePoolWithTag(PagedPool
, sizeof(RFSD_REPINNED_BCBS
), RFSD_POOL_TAG
);
275 RtlZeroMemory( Repinned
->Next
, sizeof(RFSD_REPINNED_BCBS
) );
278 Repinned
= Repinned
->Next
;
286 RfsdUnpinRepinnedBcbs (
287 IN PRFSD_IRP_CONTEXT IrpContext
290 IO_STATUS_BLOCK RaiseIosb
;
291 PRFSD_REPINNED_BCBS Repinned
;
292 BOOLEAN WriteThroughToDisk
;
293 PFILE_OBJECT FileObject
= NULL
;
294 BOOLEAN ForceVerify
= FALSE
;
297 Repinned
= &IrpContext
->Repinned
;
298 RaiseIosb
.Status
= STATUS_SUCCESS
;
300 WriteThroughToDisk
= (BOOLEAN
) (IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WRITE_THROUGH
) ||
301 IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FLOPPY
));
303 while (Repinned
!= NULL
) {
304 for (i
= 0; i
< RFSD_REPINNED_BCBS_ARRAY_SIZE
; i
+= 1) {
305 if (Repinned
->Bcb
[i
] != NULL
) {
306 IO_STATUS_BLOCK Iosb
;
308 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
310 if ( FlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FLOPPY
) ) {
311 FileObject
= CcGetFileObjectFromBcb( Repinned
->Bcb
[i
] );
314 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
316 CcUnpinRepinnedBcb( Repinned
->Bcb
[i
],
320 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
322 if ( !NT_SUCCESS(Iosb
.Status
) ) {
323 if (RaiseIosb
.Status
== STATUS_SUCCESS
) {
327 if (FlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FLOPPY
) &&
328 (IrpContext
->MajorFunction
!= IRP_MJ_CLEANUP
) &&
329 (IrpContext
->MajorFunction
!= IRP_MJ_FLUSH_BUFFERS
) &&
330 (IrpContext
->MajorFunction
!= IRP_MJ_SET_INFORMATION
)) {
332 CcPurgeCacheSection( FileObject
->SectionObjectPointer
,
341 Repinned
->Bcb
[i
] = NULL
;
349 if (Repinned
!= &IrpContext
->Repinned
)
351 PRFSD_REPINNED_BCBS Saved
;
353 Saved
= Repinned
->Next
;
354 ExFreePool( Repinned
);
359 Repinned
= Repinned
->Next
;
360 IrpContext
->Repinned
.Next
= NULL
;
364 if (!NT_SUCCESS(RaiseIosb
.Status
)) {
368 if (ForceVerify
&& FileObject
) {
369 SetFlag(FileObject
->DeviceObject
->Flags
, DO_VERIFY_VOLUME
);
370 IoSetHardErrorOrVerifyDevice( IrpContext
->Irp
,
371 FileObject
->DeviceObject
);
374 IrpContext
->Irp
->IoStatus
= RaiseIosb
;
375 RfsdNormalizeAndRaiseStatus(IrpContext
, RaiseIosb
.Status
);
381 __drv_mustHoldCriticalRegion
383 RfsdAllocateFcb (IN PRFSD_VCB Vcb
,
384 IN PRFSD_MCB RfsdMcb
,
385 IN PRFSD_INODE Inode
)
391 ExAcquireResourceExclusiveLite(
392 &RfsdGlobal
->LAResource
,
395 Fcb
= (PRFSD_FCB
) ExAllocateFromNPagedLookasideList(
396 &(RfsdGlobal
->RfsdFcbLookasideList
));
398 ExReleaseResourceForThreadLite(
399 &RfsdGlobal
->LAResource
,
400 ExGetCurrentResourceThread() );
403 Fcb
= (PRFSD_FCB
) ExAllocatePoolWithTag(NonPagedPool
, sizeof(RFSD_FCB
), RFSD_POOL_TAG
);
405 RtlZeroMemory(Fcb
, sizeof(RFSD_FCB
));
407 SetFlag(Fcb
->Flags
, FCB_FROM_POOL
);
409 RtlZeroMemory(Fcb
, sizeof(RFSD_FCB
));
416 Fcb
->Identifier
.Type
= RFSDFCB
;
417 Fcb
->Identifier
.Size
= sizeof(RFSD_FCB
);
419 FsRtlInitializeFileLock (
420 &Fcb
->FileLockAnchor
,
424 Fcb
->OpenHandleCount
= 0;
425 Fcb
->ReferenceCount
= 0;
431 Fcb
->AnsiFileName
.MaximumLength
= (USHORT
)
432 RfsdUnicodeToOEMSize(&(RfsdMcb
->ShortName
)) + 1;
434 Fcb
->AnsiFileName
.Buffer
= (PUCHAR
)
435 ExAllocatePoolWithTag(PagedPool
, Fcb
->AnsiFileName
.MaximumLength
, RFSD_POOL_TAG
);
437 if (!Fcb
->AnsiFileName
.Buffer
) {
441 RtlZeroMemory(Fcb
->AnsiFileName
.Buffer
, Fcb
->AnsiFileName
.MaximumLength
);
443 RfsdUnicodeToOEM( &(Fcb
->AnsiFileName
),
444 &(RfsdMcb
->ShortName
));
448 RfsdMcb
->FileAttr
= FILE_ATTRIBUTE_NORMAL
;
450 if (S_ISDIR(Inode
->i_mode
)) {
451 SetFlag(RfsdMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
);
454 if ( IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
455 RfsdIsReadOnly(Inode
->i_mode
)) {
456 SetFlag(RfsdMcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
);
461 Fcb
->RfsdMcb
= RfsdMcb
;
462 RfsdMcb
->RfsdFcb
= Fcb
;
464 RtlZeroMemory(&Fcb
->Header
, sizeof(FSRTL_COMMON_FCB_HEADER
));
466 Fcb
->Header
.NodeTypeCode
= (USHORT
) RFSDFCB
;
467 Fcb
->Header
.NodeByteSize
= sizeof(RFSD_FCB
);
468 Fcb
->Header
.IsFastIoPossible
= FastIoIsNotPossible
;
469 Fcb
->Header
.Resource
= &(Fcb
->MainResource
);
470 Fcb
->Header
.PagingIoResource
= &(Fcb
->PagingIoResource
);
472 // NOTE: In EXT2, the low part was stored in i_size (a 32-bit value); the high part would be stored in the acl field...
473 // However, on ReiserFS, the i_size is a 64-bit value.
474 Fcb
->Header
.FileSize
.QuadPart
= Fcb
->Inode
->i_size
;
477 Fcb
->Header
.AllocationSize
.QuadPart
=
478 CEILING_ALIGNED(Fcb
->Header
.FileSize
.QuadPart
, (ULONGLONG
)Vcb
->BlockSize
);
480 Fcb
->Header
.ValidDataLength
.QuadPart
= (LONGLONG
)(0x7fffffffffffffff);
482 Fcb
->SectionObject
.DataSectionObject
= NULL
;
483 Fcb
->SectionObject
.SharedCacheMap
= NULL
;
484 Fcb
->SectionObject
.ImageSectionObject
= NULL
;
486 ExInitializeResourceLite(&(Fcb
->MainResource
));
487 ExInitializeResourceLite(&(Fcb
->PagingIoResource
));
489 InsertTailList(&Vcb
->FcbList
, &Fcb
->Next
);
493 ExAcquireResourceExclusiveLite(
494 &RfsdGlobal
->CountResource
,
497 RfsdGlobal
->FcbAllocated
++;
499 ExReleaseResourceForThreadLite(
500 &RfsdGlobal
->CountResource
,
501 ExGetCurrentResourceThread() );
513 if (Fcb
->AnsiFileName
.Buffer
)
514 ExFreePool(Fcb
->AnsiFileName
.Buffer
);
517 if (FlagOn(Fcb
->Flags
, FCB_FROM_POOL
)) {
523 ExAcquireResourceExclusiveLite(
524 &RfsdGlobal
->LAResource
,
527 ExFreeToNPagedLookasideList(&(RfsdGlobal
->RfsdFcbLookasideList
), Fcb
);
529 ExReleaseResourceForThreadLite(
530 &RfsdGlobal
->LAResource
,
531 ExGetCurrentResourceThread() );
539 __drv_mustHoldCriticalRegion
541 RfsdFreeFcb (IN PRFSD_FCB Fcb
)
549 ASSERT((Fcb
->Identifier
.Type
== RFSDFCB
) &&
550 (Fcb
->Identifier
.Size
== sizeof(RFSD_FCB
)));
554 FsRtlUninitializeFileLock(&Fcb
->FileLockAnchor
);
556 ExDeleteResourceLite(&Fcb
->MainResource
);
558 ExDeleteResourceLite(&Fcb
->PagingIoResource
);
560 Fcb
->RfsdMcb
->RfsdFcb
= NULL
;
562 if(IsFlagOn(Fcb
->Flags
, FCB_FILE_DELETED
)) {
564 RfsdDeleteMcbNode(Vcb
, Fcb
->RfsdMcb
->Parent
, Fcb
->RfsdMcb
);
565 RfsdFreeMcb(Fcb
->RfsdMcb
);
569 if (Fcb
->LongName
.Buffer
) {
570 ExFreePool(Fcb
->LongName
.Buffer
);
571 Fcb
->LongName
.Buffer
= NULL
;
575 ExFreePool(Fcb
->AnsiFileName
.Buffer
);
578 ExFreePool(Fcb
->Inode
);
580 Fcb
->Header
.NodeTypeCode
= (SHORT
)0xCCCC;
581 Fcb
->Header
.NodeByteSize
= (SHORT
)0xC0C0;
583 if (FlagOn(Fcb
->Flags
, FCB_FROM_POOL
)) {
589 ExAcquireResourceExclusiveLite(
590 &RfsdGlobal
->LAResource
,
593 ExFreeToNPagedLookasideList(&(RfsdGlobal
->RfsdFcbLookasideList
), Fcb
);
595 ExReleaseResourceForThreadLite(
596 &RfsdGlobal
->LAResource
,
597 ExGetCurrentResourceThread() );
602 ExAcquireResourceExclusiveLite(
603 &RfsdGlobal
->CountResource
,
606 RfsdGlobal
->FcbAllocated
--;
608 ExReleaseResourceForThreadLite(
609 &RfsdGlobal
->CountResource
,
610 ExGetCurrentResourceThread() );
615 __drv_mustHoldCriticalRegion
617 RfsdAllocateCcb (VOID
)
623 ExAcquireResourceExclusiveLite(
624 &RfsdGlobal
->LAResource
,
627 Ccb
= (PRFSD_CCB
) (ExAllocateFromNPagedLookasideList( &(RfsdGlobal
->RfsdCcbLookasideList
)));
629 ExReleaseResourceForThreadLite(
630 &RfsdGlobal
->LAResource
,
631 ExGetCurrentResourceThread() );
634 Ccb
= (PRFSD_CCB
) ExAllocatePoolWithTag(NonPagedPool
, sizeof(RFSD_CCB
), RFSD_POOL_TAG
);
636 RtlZeroMemory(Ccb
, sizeof(RFSD_CCB
));
638 SetFlag(Ccb
->Flags
, CCB_FROM_POOL
);
640 RtlZeroMemory(Ccb
, sizeof(RFSD_CCB
));
647 Ccb
->Identifier
.Type
= RFSDCCB
;
648 Ccb
->Identifier
.Size
= sizeof(RFSD_CCB
);
650 Ccb
->CurrentByteOffset
= 0;
652 Ccb
->DirectorySearchPattern
.Length
= 0;
653 Ccb
->DirectorySearchPattern
.MaximumLength
= 0;
654 Ccb
->DirectorySearchPattern
.Buffer
= 0;
659 __drv_mustHoldCriticalRegion
661 RfsdFreeCcb (IN PRFSD_CCB Ccb
)
667 ASSERT((Ccb
->Identifier
.Type
== RFSDCCB
) &&
668 (Ccb
->Identifier
.Size
== sizeof(RFSD_CCB
)));
670 if (Ccb
->DirectorySearchPattern
.Buffer
!= NULL
) {
671 ExFreePool(Ccb
->DirectorySearchPattern
.Buffer
);
674 if (FlagOn(Ccb
->Flags
, CCB_FROM_POOL
)) {
680 ExAcquireResourceExclusiveLite(
681 &RfsdGlobal
->LAResource
,
684 ExFreeToNPagedLookasideList(&(RfsdGlobal
->RfsdCcbLookasideList
), Ccb
);
686 ExReleaseResourceForThreadLite(
687 &RfsdGlobal
->LAResource
,
688 ExGetCurrentResourceThread() );
692 __drv_mustHoldCriticalRegion
694 RfsdAllocateMcb (PRFSD_VCB Vcb
, PUNICODE_STRING FileName
, ULONG FileAttr
)
696 PRFSD_MCB Mcb
= NULL
;
697 PLIST_ENTRY List
= NULL
;
702 #define MCB_NUM_SHIFT 0x04
704 if (RfsdGlobal
->McbAllocated
> (RfsdGlobal
->MaxDepth
<< MCB_NUM_SHIFT
))
705 Extra
= RfsdGlobal
->McbAllocated
-
706 (RfsdGlobal
->MaxDepth
<< MCB_NUM_SHIFT
) +
707 RfsdGlobal
->MaxDepth
;
710 "RfsdAllocateMcb: CurrDepth=%xh/%xh/%xh FileName=%S\n",
711 RfsdGlobal
->McbAllocated
,
712 RfsdGlobal
->MaxDepth
<< MCB_NUM_SHIFT
,
713 RfsdGlobal
->FcbAllocated
,
716 List
= Vcb
->McbList
.Flink
;
718 while ((List
!= &(Vcb
->McbList
)) && (Extra
> 0)) {
719 Mcb
= CONTAINING_RECORD(List
, RFSD_MCB
, Link
);
722 if ((!RFSD_IS_ROOT_KEY(Mcb
->Key
)) && (Mcb
->Child
== NULL
) &&
723 (Mcb
->RfsdFcb
== NULL
) && (!IsMcbUsed(Mcb
))) {
724 RfsdPrint((DBG_INFO
, "RfsdAllocateMcb: Mcb %S will be freed.\n",
725 Mcb
->ShortName
.Buffer
));
727 if (RfsdDeleteMcbNode(Vcb
, Vcb
->McbTree
, Mcb
)) {
735 ExAcquireResourceExclusiveLite(
736 &RfsdGlobal
->LAResource
,
739 Mcb
= (PRFSD_MCB
) (ExAllocateFromPagedLookasideList(
740 &(RfsdGlobal
->RfsdMcbLookasideList
)));
742 ExReleaseResourceForThreadLite(
743 &RfsdGlobal
->LAResource
,
744 ExGetCurrentResourceThread() );
747 Mcb
= (PRFSD_MCB
) ExAllocatePoolWithTag(PagedPool
, sizeof(RFSD_MCB
), RFSD_POOL_TAG
);
749 RtlZeroMemory(Mcb
, sizeof(RFSD_MCB
));
751 SetFlag(Mcb
->Flags
, MCB_FROM_POOL
);
753 RtlZeroMemory(Mcb
, sizeof(RFSD_MCB
));
760 Mcb
->Identifier
.Type
= RFSDMCB
;
761 Mcb
->Identifier
.Size
= sizeof(RFSD_MCB
);
763 if (FileName
&& FileName
->Length
) {
765 Mcb
->ShortName
.Length
= FileName
->Length
;
766 Mcb
->ShortName
.MaximumLength
= Mcb
->ShortName
.Length
+ 2;
768 Mcb
->ShortName
.Buffer
= ExAllocatePoolWithTag(PagedPool
, Mcb
->ShortName
.MaximumLength
, RFSD_POOL_TAG
);
770 if (!Mcb
->ShortName
.Buffer
)
773 RtlZeroMemory(Mcb
->ShortName
.Buffer
, Mcb
->ShortName
.MaximumLength
);
774 RtlCopyMemory(Mcb
->ShortName
.Buffer
, FileName
->Buffer
, Mcb
->ShortName
.Length
);
777 Mcb
->FileAttr
= FileAttr
;
779 ExAcquireResourceExclusiveLite(
780 &RfsdGlobal
->CountResource
,
783 RfsdGlobal
->McbAllocated
++;
785 ExReleaseResourceForThreadLite(
786 &RfsdGlobal
->CountResource
,
787 ExGetCurrentResourceThread() );
795 if (Mcb
->ShortName
.Buffer
)
796 ExFreePool(Mcb
->ShortName
.Buffer
);
798 if (FlagOn(Mcb
->Flags
, MCB_FROM_POOL
)) {
804 ExAcquireResourceExclusiveLite(
805 &RfsdGlobal
->LAResource
,
808 ExFreeToPagedLookasideList(&(RfsdGlobal
->RfsdMcbLookasideList
), Mcb
);
810 ExReleaseResourceForThreadLite(
811 &RfsdGlobal
->LAResource
,
812 ExGetCurrentResourceThread() );
819 __drv_mustHoldCriticalRegion
821 RfsdFreeMcb (IN PRFSD_MCB Mcb
)
824 PRFSD_MCB Parent
= Mcb
->Parent
;
829 ASSERT((Mcb
->Identifier
.Type
== RFSDMCB
) &&
830 (Mcb
->Identifier
.Size
== sizeof(RFSD_MCB
)));
832 RfsdPrint((DBG_INFO
, "RfsdFreeMcb: Mcb %S will be freed.\n", Mcb
->ShortName
.Buffer
));
834 if (Mcb
->ShortName
.Buffer
)
835 ExFreePool(Mcb
->ShortName
.Buffer
);
837 if (FlagOn(Mcb
->Flags
, MCB_FROM_POOL
)) {
843 ExAcquireResourceExclusiveLite(
844 &RfsdGlobal
->LAResource
,
847 ExFreeToPagedLookasideList(&(RfsdGlobal
->RfsdMcbLookasideList
), Mcb
);
849 ExReleaseResourceForThreadLite(
850 &RfsdGlobal
->LAResource
,
851 ExGetCurrentResourceThread() );
854 ExAcquireResourceExclusiveLite(
855 &RfsdGlobal
->CountResource
,
858 RfsdGlobal
->McbAllocated
--;
860 ExReleaseResourceForThreadLite(
861 &RfsdGlobal
->CountResource
,
862 ExGetCurrentResourceThread() );
865 __drv_mustHoldCriticalRegion
867 RfsdCreateFcbFromMcb(PRFSD_VCB Vcb
, PRFSD_MCB Mcb
)
869 PRFSD_FCB Fcb
= NULL
;
877 if (RfsdLoadInode(Vcb
, &(Mcb
->Key
), &RfsdIno
)) {
878 PRFSD_INODE pTmpInode
= ExAllocatePoolWithTag(PagedPool
, sizeof(RFSD_INODE
), RFSD_POOL_TAG
);
883 RtlCopyMemory(pTmpInode
, &RfsdIno
, sizeof(RFSD_INODE
));
884 Fcb
= RfsdAllocateFcb(Vcb
, Mcb
, pTmpInode
);
886 ExFreePool(pTmpInode
);
896 RfsdGetFullFileName(PRFSD_MCB Mcb
, PUNICODE_STRING FileName
)
899 PRFSD_MCB TmpMcb
= Mcb
;
900 PUNICODE_STRING FileNames
[256];
901 SHORT Count
= 0 , i
= 0, j
= 0;
905 while(TmpMcb
&& Count
< 256) {
906 if (RFSD_IS_ROOT_KEY(TmpMcb
->Key
))
909 FileNames
[Count
++] = &TmpMcb
->ShortName
;
910 Length
+= (2 + TmpMcb
->ShortName
.Length
);
912 TmpMcb
= TmpMcb
->Parent
;
921 FileName
->Length
= Length
;
922 FileName
->MaximumLength
= Length
+ 2;
923 FileName
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Length
+ 2, RFSD_POOL_TAG
);
925 if (!FileName
->Buffer
) {
929 RtlZeroMemory(FileName
->Buffer
, FileName
->MaximumLength
);
932 FileName
->Buffer
[0] = L
'\\';
936 for (i
= Count
- 1; i
>= 0 && j
< (SHORT
)(FileName
->MaximumLength
); i
--) {
937 FileName
->Buffer
[j
++] = L
'\\';
939 RtlCopyMemory( &(FileName
->Buffer
[j
]),
940 FileNames
[i
]->Buffer
,
941 FileNames
[i
]->Length
);
943 j
+= FileNames
[i
]->Length
/ 2;
950 RfsdSearchMcbTree( PRFSD_VCB Vcb
,
952 PRFSD_KEY_IN_MEMORY Key
)
954 PRFSD_MCB Mcb
= NULL
;
955 PLIST_ENTRY List
= NULL
;
956 BOOLEAN bFind
= FALSE
;
960 List
= Vcb
->McbList
.Flink
;
962 while ((!bFind
) && (List
!= &(Vcb
->McbList
))) {
963 Mcb
= CONTAINING_RECORD(List
, RFSD_MCB
, Link
);
966 if (CompareShortKeys(&(Mcb
->Key
), Key
) == RFSD_KEYS_MATCH
) {
974 RfsdRefreshMcb(Vcb
, Mcb
);
983 Returns NULL is the parent has no child, or if we search through the child's brothers and hit a NULL
984 Otherwise, returns the MCB of one of the the parent's children, which matches FileName.
987 RfsdSearchMcb( PRFSD_VCB Vcb
,
989 PUNICODE_STRING FileName
)
991 PRFSD_MCB TmpMcb
= Parent
->Child
;
996 if (!RtlCompareUnicodeString(
997 &(TmpMcb
->ShortName
),
1001 TmpMcb
= TmpMcb
->Next
;
1005 RfsdRefreshMcb(Vcb
, TmpMcb
);
1012 RfsdRefreshMcb(PRFSD_VCB Vcb
, PRFSD_MCB Mcb
)
1016 ASSERT (IsFlagOn(Mcb
->Flags
, MCB_IN_TREE
));
1018 RemoveEntryList(&(Mcb
->Link
));
1019 InsertTailList(&(Vcb
->McbList
), &(Mcb
->Link
));
1023 RfsdAddMcbNode(PRFSD_VCB Vcb
, PRFSD_MCB Parent
, PRFSD_MCB Child
)
1025 PRFSD_MCB TmpMcb
= Parent
->Child
;
1029 if(IsFlagOn(Child
->Flags
, MCB_IN_TREE
)) {
1031 RfsdPrint((DBG_ERROR
, "RfsdAddMcbNode: Child Mcb is alreay in the tree.\n"));
1036 ASSERT(TmpMcb
->Parent
== Parent
);
1038 while (TmpMcb
->Next
) {
1039 TmpMcb
= TmpMcb
->Next
;
1040 ASSERT(TmpMcb
->Parent
== Parent
);
1043 TmpMcb
->Next
= Child
;
1044 Child
->Parent
= Parent
;
1047 Parent
->Child
= Child
;
1048 Child
->Parent
= Parent
;
1052 InsertTailList(&(Vcb
->McbList
), &(Child
->Link
));
1053 SetFlag(Child
->Flags
, MCB_IN_TREE
);
1057 RfsdDeleteMcbNode(PRFSD_VCB Vcb
, PRFSD_MCB McbTree
, PRFSD_MCB RfsdMcb
)
1063 if(!IsFlagOn(RfsdMcb
->Flags
, MCB_IN_TREE
)) {
1067 if (RfsdMcb
->Parent
) {
1068 if (RfsdMcb
->Parent
->Child
== RfsdMcb
) {
1069 RfsdMcb
->Parent
->Child
= RfsdMcb
->Next
;
1071 TmpMcb
= RfsdMcb
->Parent
->Child
;
1073 while (TmpMcb
&& TmpMcb
->Next
!= RfsdMcb
)
1074 TmpMcb
= TmpMcb
->Next
;
1077 TmpMcb
->Next
= RfsdMcb
->Next
;
1083 } else if (RfsdMcb
->Child
) {
1087 RemoveEntryList(&(RfsdMcb
->Link
));
1088 ClearFlag(RfsdMcb
->Flags
, MCB_IN_TREE
);
1093 __drv_mustHoldCriticalRegion
1094 VOID
RfsdFreeMcbTree(PRFSD_MCB McbTree
)
1101 if (McbTree
->Child
) {
1102 RfsdFreeMcbTree(McbTree
->Child
);
1105 if (McbTree
->Next
) {
1110 Current
= McbTree
->Next
;
1114 Next
= Current
->Next
;
1116 if (Current
->Child
) {
1117 RfsdFreeMcbTree(Current
->Child
);
1120 RfsdFreeMcb(Current
);
1125 RfsdFreeMcb(McbTree
);
1131 RfsdCheckSetBlock(PRFSD_IRP_CONTEXT IrpContext
, PRFSD_VCB Vcb
, ULONG Block
)
1133 ULONG Group
, dwBlk
, Length
;
1135 RTL_BITMAP BlockBitmap
;
1139 LARGE_INTEGER Offset
;
1141 BOOLEAN bModified
= FALSE
;
1145 Group
= (Block
- RFSD_FIRST_DATA_BLOCK
) / BLOCKS_PER_GROUP
;
1147 dwBlk
= (Block
- RFSD_FIRST_DATA_BLOCK
) % BLOCKS_PER_GROUP
;
1150 Offset
.QuadPart
= (LONGLONG
) Vcb
->BlockSize
;
1151 Offset
.QuadPart
= Offset
.QuadPart
* Vcb
->GroupDesc
[Group
].bg_block_bitmap
;
1153 if (Group
== Vcb
->NumOfGroups
- 1) {
1154 Length
= TOTAL_BLOCKS
% BLOCKS_PER_GROUP
;
1156 /* s_blocks_count is integer multiple of s_blocks_per_group */
1158 Length
= BLOCKS_PER_GROUP
;
1160 Length
= BLOCKS_PER_GROUP
;
1163 if (dwBlk
>= Length
)
1166 if (!CcPinRead( Vcb
->StreamObj
,
1173 RfsdPrint((DBG_ERROR
, "RfsdDeleteBlock: PinReading error ...\n"));
1177 RtlInitializeBitMap( &BlockBitmap
,
1181 if (RtlCheckBit(&BlockBitmap
, dwBlk
) == 0) {
1183 RtlSetBits(&BlockBitmap
, dwBlk
, 1);
1189 CcSetDirtyPinnedData(BitmapBcb
, NULL
);
1191 RfsdRepinBcb(IrpContext
, BitmapBcb
);
1193 RfsdAddMcbEntry(Vcb
, Offset
.QuadPart
, (LONGLONG
)Vcb
->BlockSize
);
1197 CcUnpinData(BitmapBcb
);
1201 RtlZeroMemory(&BlockBitmap
, sizeof(RTL_BITMAP
));
1204 return (!bModified
);
1208 RfsdCheckBitmapConsistency(PRFSD_IRP_CONTEXT IrpContext
, PRFSD_VCB Vcb
)
1210 ULONG i
, j
, InodeBlocks
;
1214 for (i
= 0; i
< Vcb
->NumOfGroups
; i
++) {
1216 RfsdCheckSetBlock(IrpContext
, Vcb
, Vcb
->GroupDesc
[i
].bg_block_bitmap
);
1217 RfsdCheckSetBlock(IrpContext
, Vcb
, Vcb
->GroupDesc
[i
].bg_inode_bitmap
);
1220 if (i
== Vcb
->NumOfGroups
- 1) {
1221 InodeBlocks
= ((INODES_COUNT
% INODES_PER_GROUP
) *
1222 sizeof(RFSD_INODE
) + Vcb
->BlockSize
- 1) /
1225 InodeBlocks
= (INODES_PER_GROUP
* sizeof(RFSD_INODE
) + Vcb
->BlockSize
- 1) / (Vcb
->BlockSize
);
1228 for (j
= 0; j
< InodeBlocks
; j
++ )
1229 RfsdCheckSetBlock(IrpContext
, Vcb
, Vcb
->GroupDesc
[i
].bg_inode_table
+ j
);
1235 #endif // !RFSD_READ_ONLY
1238 RfsdInsertVcb(PRFSD_VCB Vcb
)
1240 InsertTailList(&(RfsdGlobal
->VcbList
), &Vcb
->Next
);
1244 RfsdRemoveVcb(PRFSD_VCB Vcb
)
1246 RemoveEntryList(&Vcb
->Next
);
1249 __drv_mustHoldCriticalRegion
1251 RfsdInitializeVcb( IN PRFSD_IRP_CONTEXT IrpContext
,
1253 IN PRFSD_SUPER_BLOCK RfsdSb
,
1254 IN PDEVICE_OBJECT TargetDevice
,
1255 IN PDEVICE_OBJECT VolumeDevice
,
1258 BOOLEAN VcbResourceInitialized
= FALSE
;
1259 USHORT VolumeLabelLength
;
1261 BOOLEAN NotifySyncInitialized
= FALSE
;
1264 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1265 UNICODE_STRING RootNode
;
1268 char s_volume_name
[16] = "ReiserFS\0"; /* volume name */ // FUTURE: pull in from v2 superblock, if available
1277 Status
= STATUS_DEVICE_NOT_READY
;
1281 RfsdPrint((DBG_ERROR
, "RfsdInitializeVcb: Flink = %xh McbList = %xh\n",
1282 Vcb
->McbList
.Flink
, &(Vcb
->McbList
.Flink
)));
1285 SetFlag(Vcb
->Flags
, VCB_READ_ONLY
);
1288 if (IsFlagOn(Vpb
->RealDevice
->Characteristics
, FILE_REMOVABLE_MEDIA
)) {
1289 SetFlag(Vcb
->Flags
, VCB_REMOVABLE_MEDIA
);
1292 if (IsFlagOn(Vpb
->RealDevice
->Characteristics
, FILE_FLOPPY_DISKETTE
)) {
1293 SetFlag(Vcb
->Flags
, VCB_FLOPPY_DISK
);
1296 /*if (IsFlagOn(RfsdGlobal->Flags, RFSD_SUPPORT_WRITING)) {
1297 if ((IsFlagOn(RfsdSb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) ||
1298 IsFlagOn(RfsdSb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_RECOVER) ||
1299 IsFlagOn(RfsdSb->s_feature_compat, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) ) {
1300 if(IsFlagOn(RfsdGlobal->Flags, EXT3_FORCE_WRITING)) {
1301 ClearFlag(Vcb->Flags, VCB_READ_ONLY);
1303 SetFlag(Vcb->Flags, VCB_READ_ONLY);
1306 ClearFlag(Vcb->Flags, VCB_READ_ONLY);
1309 SetFlag(Vcb->Flags, VCB_READ_ONLY);
1311 // RFSD will be read only.
1312 SetFlag(Vcb
->Flags
, VCB_READ_ONLY
);
1314 ExInitializeResourceLite(&Vcb
->MainResource
);
1315 ExInitializeResourceLite(&Vcb
->PagingIoResource
);
1317 ExInitializeResourceLite(&Vcb
->McbResource
);
1319 VcbResourceInitialized
= TRUE
;
1323 Vcb
->RealDevice
= Vpb
->RealDevice
;
1324 Vpb
->DeviceObject
= VolumeDevice
;
1327 UNICODE_STRING LabelName
;
1332 LabelName
.MaximumLength
= 16 * 2;
1333 LabelName
.Length
= 0;
1334 LabelName
.Buffer
= Vcb
->Vpb
->VolumeLabel
;
1336 RtlZeroMemory(LabelName
.Buffer
, LabelName
.MaximumLength
);
1338 VolumeLabelLength
= 16;
1340 while( (VolumeLabelLength
> 0) &&
1341 ((s_volume_name
[VolumeLabelLength
-1] == '\0') ||
1342 (s_volume_name
[VolumeLabelLength
-1] == ' ')) ) {
1343 VolumeLabelLength
--;
1346 OemName
.Buffer
= s_volume_name
;
1347 OemName
.MaximumLength
= 16;
1348 OemName
.Length
= VolumeLabelLength
;
1350 templen
= RtlOemStringToUnicodeSize(&OemName
);
1352 Status
= RfsdOEMToUnicode( &LabelName
,
1355 if (!NT_SUCCESS(Status
)) {
1359 Vpb
->VolumeLabelLength
= LabelName
.Length
;
1363 Vpb
->SerialNumber
= ((ULONG
*)RfsdSb
->s_uuid
)[0] + ((ULONG
*)RfsdSb
->s_uuid
)[1] +
1364 ((ULONG
*)RfsdSb
->s_uuid
)[2] + ((ULONG
*)RfsdSb
->s_uuid
)[3];
1367 Vcb
->StreamObj
= IoCreateStreamFileObject( NULL
, Vcb
->Vpb
->RealDevice
);
1369 if (Vcb
->StreamObj
) {
1371 Vcb
->StreamObj
->SectionObjectPointer
= &(Vcb
->SectionObject
);
1372 Vcb
->StreamObj
->Vpb
= Vcb
->Vpb
;
1373 Vcb
->StreamObj
->ReadAccess
= TRUE
;
1374 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
))
1376 Vcb
->StreamObj
->WriteAccess
= FALSE
;
1377 Vcb
->StreamObj
->DeleteAccess
= FALSE
;
1381 Vcb
->StreamObj
->WriteAccess
= TRUE
;
1382 Vcb
->StreamObj
->DeleteAccess
= TRUE
;
1384 Vcb
->StreamObj
->FsContext
= (PVOID
) Vcb
;
1385 Vcb
->StreamObj
->FsContext2
= NULL
;
1386 Vcb
->StreamObj
->Vpb
= Vcb
->Vpb
;
1388 SetFlag(Vcb
->StreamObj
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
);
1393 InitializeListHead(&Vcb
->FcbList
);
1395 InitializeListHead(&Vcb
->NotifyList
);
1397 FsRtlNotifyInitializeSync(&Vcb
->NotifySync
);
1399 NotifySyncInitialized
= TRUE
;
1401 Vcb
->DeviceObject
= VolumeDevice
;
1403 Vcb
->TargetDeviceObject
= TargetDevice
;
1405 Vcb
->OpenFileHandleCount
= 0;
1407 Vcb
->ReferenceCount
= 0;
1409 Vcb
->SuperBlock
= RfsdSb
;
1411 Vcb
->Header
.NodeTypeCode
= (USHORT
) RFSDVCB
;
1412 Vcb
->Header
.NodeByteSize
= sizeof(RFSD_VCB
);
1413 Vcb
->Header
.IsFastIoPossible
= FastIoIsNotPossible
;
1414 Vcb
->Header
.Resource
= &(Vcb
->MainResource
);
1415 Vcb
->Header
.PagingIoResource
= &(Vcb
->PagingIoResource
);
1417 Vcb
->Vpb
->SerialNumber
= 'MATT';
1420 Vcb
->DiskGeometry
.Cylinders
.QuadPart
*
1421 Vcb
->DiskGeometry
.TracksPerCylinder
*
1422 Vcb
->DiskGeometry
.SectorsPerTrack
*
1423 Vcb
->DiskGeometry
.BytesPerSector
;
1425 IoctlSize
= sizeof(PARTITION_INFORMATION
);
1427 Status
= RfsdDiskIoControl(
1429 IOCTL_DISK_GET_PARTITION_INFO
,
1432 &Vcb
->PartitionInformation
,
1435 PartSize
= Vcb
->PartitionInformation
.PartitionLength
.QuadPart
;
1437 if (!NT_SUCCESS(Status
)) {
1438 Vcb
->PartitionInformation
.StartingOffset
.QuadPart
= 0;
1440 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
=
1443 PartSize
= DiskSize
;
1445 Status
= STATUS_SUCCESS
;
1448 IoctlSize
= sizeof(ULONG
);
1449 Status
= RfsdDiskIoControl(
1451 IOCTL_DISK_CHECK_VERIFY
,
1457 if (!NT_SUCCESS(Status
)) {
1461 Vcb
->ChangeCount
= ChangeCount
;
1463 Vcb
->Header
.AllocationSize
.QuadPart
=
1464 Vcb
->Header
.FileSize
.QuadPart
= PartSize
;
1466 Vcb
->Header
.ValidDataLength
.QuadPart
=
1467 (LONGLONG
)(0x7fffffffffffffff);
1469 Vcb->Header.AllocationSize.QuadPart = (LONGLONG)(rfsd_super_block->s_blocks_count - rfsd_super_block->s_free_blocks_count)
1470 * (RFSD_MIN_BLOCK << rfsd_super_block->s_log_block_size);
1471 Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart;
1472 Vcb->Header.ValidDataLength.QuadPart = Vcb->Header.AllocationSize.QuadPart;
1475 CC_FILE_SIZES FileSizes
;
1477 FileSizes
.AllocationSize
.QuadPart
=
1478 FileSizes
.FileSize
.QuadPart
=
1479 Vcb
->Header
.AllocationSize
.QuadPart
;
1481 FileSizes
.ValidDataLength
.QuadPart
= (LONGLONG
)(0x7fffffffffffffff);
1483 CcInitializeCacheMap( Vcb
->StreamObj
,
1486 &(RfsdGlobal
->CacheManagerNoOpCallbacks
),
1489 #if DISABLED // IN FFFS TOO
1490 if (!RfsdLoadGroup(Vcb
)) {
1491 Status
= STATUS_UNSUCCESSFUL
;
1496 FsRtlInitializeLargeMcb(&(Vcb
->DirtyMcbs
), PagedPool
);
1497 InitializeListHead(&(Vcb
->McbList
));
1501 // Now allocating the mcb for root ...
1507 RootNode
.Buffer
= Buffer
;
1508 RootNode
.MaximumLength
= RootNode
.Length
= 2;
1510 Vcb
->McbTree
= RfsdAllocateMcb( Vcb
, &RootNode
,
1511 FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_NORMAL
);
1513 if (!Vcb
->McbTree
) {
1517 // Set the root of the filesystem to the root directory's inode / stat data structure
1518 Vcb
->McbTree
->Key
.k_dir_id
= RFSD_ROOT_PARENT_ID
;
1519 Vcb
->McbTree
->Key
.k_objectid
= RFSD_ROOT_OBJECT_ID
;
1520 Vcb
->McbTree
->Key
.k_offset
= 0;
1521 Vcb
->McbTree
->Key
.k_type
= RFSD_KEY_TYPE_v1_STAT_DATA
;
1524 if (IsFlagOn(RfsdGlobal
->Flags
, RFSD_CHECKING_BITMAP
)) {
1525 RfsdCheckBitmapConsistency(IrpContext
, Vcb
);
1529 ULONG dwData
[RFSD_BLOCK_TYPES
] = {RFSD_NDIR_BLOCKS
, 1, 1, 1};
1530 ULONG dwMeta
[RFSD_BLOCK_TYPES
] = {0, 0, 0, 0};
1533 KdPrint(("Reminder: " __FUNCTION__
", dwData, dwMeta??\n"));
1535 for (i
= 0; i
< RFSD_BLOCK_TYPES
; i
++) {
1536 dwData
[i
] = dwData
[i
] << ((BLOCK_BITS
- 2) * i
);
1539 dwMeta
[i
] = 1 + (dwMeta
[i
- 1] << (BLOCK_BITS
- 2));
1542 Vcb
->dwData
[i
] = dwData
[i
];
1543 Vcb
->dwMeta
[i
] = dwMeta
[i
];
1548 SetFlag(Vcb
->Flags
, VCB_INITIALIZED
);
1552 if (!NT_SUCCESS(Status
)) {
1554 if (NotifySyncInitialized
) {
1555 FsRtlNotifyUninitializeSync(&Vcb
->NotifySync
);
1558 if (Vcb
->GroupDesc
) {
1559 ExFreePool(Vcb
->GroupDesc
);
1560 // CcUnpinData(Vcb->GroupDescBcb);
1561 Vcb
->GroupDesc
= NULL
;
1564 if (Vcb
->SuperBlock
) {
1565 ExFreePool(Vcb
->SuperBlock
);
1566 Vcb
->SuperBlock
= NULL
;
1569 if (VcbResourceInitialized
) {
1570 ExDeleteResourceLite(&Vcb
->MainResource
);
1571 ExDeleteResourceLite(&Vcb
->PagingIoResource
);
1579 __drv_mustHoldCriticalRegion
1581 RfsdFreeVcb (IN PRFSD_VCB Vcb
)
1585 ASSERT(Vcb
!= NULL
);
1587 ASSERT((Vcb
->Identifier
.Type
== RFSDVCB
) &&
1588 (Vcb
->Identifier
.Size
== sizeof(RFSD_VCB
)));
1590 FsRtlNotifyUninitializeSync(&Vcb
->NotifySync
);
1592 if (Vcb
->StreamObj
) {
1593 if (IsFlagOn(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
)) {
1594 IO_STATUS_BLOCK IoStatus
;
1596 CcFlushCache(&(Vcb
->SectionObject
), NULL
, 0, &IoStatus
);
1597 ClearFlag(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
);
1600 if (Vcb
->StreamObj
->PrivateCacheMap
)
1601 RfsdSyncUninitializeCacheMap(Vcb
->StreamObj
);
1603 ObDereferenceObject(Vcb
->StreamObj
);
1604 Vcb
->StreamObj
= NULL
;
1608 if (FsRtlNumberOfRunsInLargeMcb(&(Vcb
->DirtyMcbs
)) != 0) {
1611 LONGLONG DirtyLength
;
1614 for (i
= 0; FsRtlGetNextLargeMcbEntry (&(Vcb
->DirtyMcbs
), i
, &DirtyVba
, &DirtyLba
, &DirtyLength
); i
++)
1616 RfsdPrint((DBG_INFO
, "DirtyVba = %I64xh\n", DirtyVba
));
1617 RfsdPrint((DBG_INFO
, "DirtyLba = %I64xh\n", DirtyLba
));
1618 RfsdPrint((DBG_INFO
, "DirtyLen = %I64xh\n\n", DirtyLength
));
1625 FsRtlUninitializeLargeMcb(&(Vcb
->DirtyMcbs
));
1627 RfsdFreeMcbTree(Vcb
->McbTree
);
1629 if (Vcb
->GroupDesc
) {
1630 ExFreePool(Vcb
->GroupDesc
);
1631 // CcUnpinData(Vcb->GroupDescBcb);
1632 Vcb
->GroupDesc
= NULL
;
1635 if (Vcb
->SuperBlock
) {
1636 ExFreePool(Vcb
->SuperBlock
);
1637 Vcb
->SuperBlock
= NULL
;
1640 ExDeleteResourceLite(&Vcb
->McbResource
);
1642 ExDeleteResourceLite(&Vcb
->PagingIoResource
);
1644 ExDeleteResourceLite(&Vcb
->MainResource
);
1646 IoDeleteDevice(Vcb
->DeviceObject
);
1650 RfsdSyncUninitializeCacheMap (
1651 IN PFILE_OBJECT FileObject
1654 CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent
;
1655 NTSTATUS WaitStatus
;
1656 LARGE_INTEGER RfsdLargeZero
= {0,0};
1660 KeInitializeEvent( &UninitializeCompleteEvent
.Event
,
1661 SynchronizationEvent
,
1664 CcUninitializeCacheMap( FileObject
,
1666 &UninitializeCompleteEvent
);
1668 WaitStatus
= KeWaitForSingleObject( &UninitializeCompleteEvent
.Event
,
1674 ASSERT (NT_SUCCESS(WaitStatus
));