00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "cc.h"
00023
00024
00025
00026
00027
00028 #define BugCheckFileId (CACHE_BUG_CHECK_FSSUP)
00029
00030
00031
00032
00033
00034 #define me 0x00000001
00035
00036
00037
00038
00039
00040 #define IsSyscacheFile(FO) (((FO) != NULL) && \
00041
(*(PUSHORT)(FO)->FsContext == 0X705) && \
00042
FlagOn(*(PULONG)((PCHAR)(FO)->FsContext + 0x48), 0x80000000))
00043
00044 extern POBJECT_TYPE IoFileObjectType;
00045 extern ULONG
MmLargeSystemCache;
00046
00047
VOID
00048
CcUnmapAndPurge(
00049 IN
PSHARED_CACHE_MAP SharedCacheMap
00050 );
00051
00052
VOID
00053
CcDeleteMbcb(
00054 IN
PSHARED_CACHE_MAP SharedCacheMap
00055 );
00056
00057
VOID
00058
CcPurgeAndClearCacheSection (
00059 IN
PSHARED_CACHE_MAP SharedCacheMap,
00060 IN PLARGE_INTEGER FileOffset
00061 );
00062
00063
#ifdef ALLOC_PRAGMA
00064
#pragma alloc_text(INIT,CcInitializeCacheManager)
00065
#endif
00066
00067
00068 BOOLEAN
00069 CcInitializeCacheManager (
00070 )
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 {
00092 CLONG i;
00093 ULONG
Index;
00094
PNPAGED_LOOKASIDE_LIST Lookaside;
00095
USHORT NumberOfItems;
00096 PKPRCB Prcb;
00097
PWORK_QUEUE_ITEM WorkItem;
00098
00099
#ifdef CCDBG_LOCK
00100
KeInitializeSpinLock( &
CcDebugTraceLock );
00101
#endif
00102
00103
#if DBG
00104
CcBcbCount = 0;
00105 InitializeListHead( &CcBcbList );
00106
KeInitializeSpinLock( &
CcBcbSpinLock );
00107
#endif
00108
00109
00110
00111
00112
00113
CcIdleDelayTick =
LAZY_WRITER_IDLE_DELAY /
KeQueryTimeIncrement();
00114
00115
00116
00117
00118
00119
KeInitializeSpinLock( &
CcMasterSpinLock );
00120 InitializeListHead( &
CcCleanSharedCacheMapList );
00121 InitializeListHead( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks );
00122
CcDirtySharedCacheMapList.
Flags =
IS_CURSOR;
00123 InsertTailList( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks,
00124 &
CcLazyWriterCursor.
SharedCacheMapLinks );
00125
CcLazyWriterCursor.
Flags =
IS_CURSOR;
00126
00127
00128
00129
00130
00131
KeInitializeSpinLock( &
CcWorkQueueSpinlock );
00132 InitializeListHead( &
CcIdleWorkerThreadList );
00133 InitializeListHead( &
CcExpressWorkQueue );
00134 InitializeListHead( &
CcRegularWorkQueue );
00135 InitializeListHead( &
CcPostTickWorkQueue );
00136
00137
00138
00139
00140
00141
CcCapturedSystemSize =
MmQuerySystemSize();
00142
if (
CcNumberWorkerThreads == 0) {
00143
00144
switch (
CcCapturedSystemSize) {
00145
case MmSmallSystem:
00146
CcNumberWorkerThreads =
ExCriticalWorkerThreads - 1;
00147
CcDirtyPageThreshold =
MmNumberOfPhysicalPages / 8;
00148
CcAggressiveZeroThreshold = 1;
00149
break;
00150
00151
case MmMediumSystem:
00152
CcNumberWorkerThreads =
ExCriticalWorkerThreads - 1;
00153
CcDirtyPageThreshold =
MmNumberOfPhysicalPages / 4;
00154
CcAggressiveZeroThreshold = 2;
00155
break;
00156
00157
case MmLargeSystem:
00158
CcNumberWorkerThreads =
ExCriticalWorkerThreads - 2;
00159
CcDirtyPageThreshold =
MmNumberOfPhysicalPages / 4 +
00160
MmNumberOfPhysicalPages / 8;
00161
CcAggressiveZeroThreshold = 4;
00162
#if 0
00163
00164
00165
00166
00167
if ((
MmLargeSystemCache != 0) &&
00168 (
CcDirtyPageThreshold < (
MmNumberOfPhysicalPages - (0xE00000 /
PAGE_SIZE)))) {
00169
00170
CcDirtyPageThreshold =
MmNumberOfPhysicalPages - (0xE00000 /
PAGE_SIZE);
00171 }
00172
#endif
00173
break;
00174
00175
default:
00176
CcNumberWorkerThreads = 1;
00177
CcDirtyPageThreshold =
MmNumberOfPhysicalPages / 8;
00178 }
00179
00180
00181
00182
if (
MmSystemCacheWs.
MaximumWorkingSetSize > ((4*1024*1024)/
PAGE_SIZE)) {
00183
CcDirtyPageThreshold =
MmSystemCacheWs.
MaximumWorkingSetSize -
00184 ((2*1024*1024)/
PAGE_SIZE);
00185 }
00186
00187
CcDirtyPageTarget =
CcDirtyPageThreshold / 2 +
00188
CcDirtyPageThreshold / 4;
00189 }
00190
00191
CcAggressiveZeroCount = 0;
00192
00193
00194
00195
00196
00197
00198
for (i = 0; i <
CcNumberWorkerThreads; i++) {
00199
00200 WorkItem =
ExAllocatePoolWithTag(
NonPagedPool,
sizeof(
WORK_QUEUE_ITEM), 'qWcC' );
00201
00202
if (WorkItem ==
NULL) {
00203
00204
CcBugCheck( 0, 0, 0 );
00205 }
00206
00207
00208
00209
00210
00211
00212
ExInitializeWorkItem( WorkItem,
CcWorkerThread, WorkItem );
00213 InsertTailList( &
CcIdleWorkerThreadList, &WorkItem->
List );
00214 }
00215
00216
00217
00218
00219
00220 RtlZeroMemory( &
LazyWriter,
sizeof(
LAZY_WRITER) );
00221
00222
KeInitializeSpinLock( &
CcWorkQueueSpinlock );
00223 InitializeListHead( &
LazyWriter.
WorkQueue );
00224
00225
00226
00227
00228
00229
LazyWriter.
OurProcess =
PsGetCurrentProcess();
00230
00231
00232
00233
00234
00235
KeInitializeDpc( &
LazyWriter.
ScanDpc, &
CcScanDpc,
NULL );
00236
KeInitializeTimer( &
LazyWriter.
ScanTimer );
00237
00238
00239
00240
00241
00242
switch (
CcCapturedSystemSize ) {
00243
00244
00245
00246
00247
00248
case MmSmallSystem :
00249 NumberOfItems = 32;
00250
break;
00251
00252
00253
00254
00255
00256
case MmMediumSystem :
00257 NumberOfItems = 64;
00258
break;
00259
00260
00261
00262
00263
00264
case MmLargeSystem :
00265 NumberOfItems = 128;
00266
if (
MmIsThisAnNtAsSystem()) {
00267 NumberOfItems += 128;
00268 }
00269
00270
break;
00271 }
00272
00273
ExInitializeNPagedLookasideList( &
CcTwilightLookasideList,
00274
NULL,
00275
NULL,
00276 0,
00277
sizeof(
WORK_QUEUE_ENTRY ),
00278 'kWcC',
00279 NumberOfItems );
00280
00281
00282
00283
00284
00285
for (
Index = 0;
Index < (ULONG)
KeNumberProcessors;
Index += 1) {
00286 Prcb =
KiProcessorBlock[
Index];
00287
00288
00289
00290
00291
00292 Prcb->PPLookasideList[
LookasideTwilightList].L = &
CcTwilightLookasideList;
00293 Lookaside = (
PNPAGED_LOOKASIDE_LIST)
ExAllocatePoolWithTag(
NonPagedPool,
00294
sizeof(
NPAGED_LOOKASIDE_LIST),
00295 'KWcC');
00296
00297
if (Lookaside !=
NULL) {
00298
ExInitializeNPagedLookasideList( Lookaside,
00299
NULL,
00300
NULL,
00301 0,
00302
sizeof(
WORK_QUEUE_ENTRY ),
00303 'KWcC',
00304 NumberOfItems );
00305
00306 }
else {
00307 Lookaside = &
CcTwilightLookasideList;
00308 }
00309
00310 Prcb->PPLookasideList[
LookasideTwilightList].P = Lookaside;
00311 }
00312
00313
00314
00315
00316
00317 {
00318 PVOID InitialSegment;
00319 ULONG InitialSegmentSize;
00320 ULONG RoundedBcbSize = (
sizeof(
BCB) + 7) & ~7;
00321
00322
switch (
CcCapturedSystemSize ) {
00323
00324
00325
00326
00327
00328
case MmSmallSystem :
00329 InitialSegmentSize =
sizeof(
ZONE_SEGMENT_HEADER) + RoundedBcbSize * 8;
00330
break;
00331
00332
00333
00334
00335
00336
case MmMediumSystem :
00337 InitialSegmentSize =
PAGE_SIZE;
00338
break;
00339
00340
00341
00342
00343
00344
case MmLargeSystem :
00345 InitialSegmentSize = 3 *
PAGE_SIZE;
00346
break;
00347 }
00348
00349
00350
00351
00352
00353
00354
if ((InitialSegment =
ExAllocatePoolWithTag(
NonPagedPool,
00355 InitialSegmentSize,
00356 'zBcC' )) ==
NULL) {
00357
00358
CcBugCheck( 0, 0, 0 );
00359 }
00360
00361
if (!
NT_SUCCESS(
ExInitializeZone( &
LazyWriter.
BcbZone,
00362 RoundedBcbSize,
00363 InitialSegment,
00364 InitialSegmentSize ))) {
00365
CcBugCheck( 0, 0, 0 );
00366 }
00367 }
00368
00369
00370
00371
00372
00373
KeInitializeSpinLock( &
CcDeferredWriteSpinLock );
00374 InitializeListHead( &
CcDeferredWrites );
00375
00376
00377
00378
00379
00380
CcInitializeVacbs();
00381
00382
return TRUE;
00383 }
00384
00385
00386
VOID
00387 CcInitializeCacheMap (
00388 IN
PFILE_OBJECT FileObject,
00389 IN
PCC_FILE_SIZES FileSizes,
00390 IN BOOLEAN PinAccess,
00391 IN
PCACHE_MANAGER_CALLBACKS Callbacks,
00392 IN PVOID LazyWriteContext
00393 )
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 {
00428 KIRQL OldIrql;
00429
PSHARED_CACHE_MAP SharedCacheMap =
NULL;
00430 PVOID CacheMapToFree =
NULL;
00431
CC_FILE_SIZES LocalSizes;
00432 BOOLEAN WeSetBeingCreated =
FALSE;
00433 BOOLEAN SharedListOwned =
FALSE;
00434 BOOLEAN MustUninitialize =
FALSE;
00435 BOOLEAN WeCreated =
FALSE;
00436
00437
DebugTrace(+1,
me,
"CcInitializeCacheMap:\n", 0 );
00438
DebugTrace( 0,
me,
" FileObject = %08lx\n", FileObject );
00439
DebugTrace( 0,
me,
" FileSizes = %08lx\n", FileSizes );
00440
00441
00442
00443
00444
00445
00446 LocalSizes = *FileSizes;
00447
00448
00449
00450
00451
00452
if (LocalSizes.
AllocationSize.QuadPart == 0) {
00453 LocalSizes.
AllocationSize.LowPart += 1;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
if (FileObject->WriteAccess ) {
00464
00465 LocalSizes.
AllocationSize.QuadPart = LocalSizes.
AllocationSize.QuadPart + (LONGLONG)(
DEFAULT_CREATE_MODULO - 1);
00466 LocalSizes.
AllocationSize.LowPart &= ~(
DEFAULT_CREATE_MODULO - 1);
00467
00468 }
else {
00469
00470 LocalSizes.
AllocationSize.QuadPart = LocalSizes.
AllocationSize.QuadPart + (LONGLONG)(
VACB_MAPPING_GRANULARITY - 1);
00471 LocalSizes.
AllocationSize.LowPart &= ~(
VACB_MAPPING_GRANULARITY - 1);
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
if (FileObject->SectionObjectPointer->SharedCacheMap ==
NULL) {
00481 CacheMapToFree =
ExAllocatePoolWithTag(
NonPagedPool,
sizeof(
SHARED_CACHE_MAP), 'cScC' );
00482 }
00483
00484
00485
00486
00487
00488
CcAcquireMasterLock( &OldIrql );
00489 SharedListOwned =
TRUE;
00490
00491
00492
00493
00494
00495
try {
00496
00497
00498
00499
00500
00501
if (FileObject->PrivateCacheMap !=
NULL) {
00502
00503
DebugTrace( 0, 0,
"CacheMap already initialized\n", 0 );
00504
try_return( NOTHING );
00505 }
00506
00507
00508
00509
00510
00511
00512
00513 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
00514
00515
00516
00517
00518
00519
00520
if (SharedCacheMap ==
NULL) {
00521
00522
00523
00524
00525
00526 WeCreated =
TRUE;
00527
00528
if (CacheMapToFree ==
NULL) {
00529 CacheMapToFree = (
PSHARED_CACHE_MAP)
ExAllocatePoolWithTag(
NonPagedPool,
00530
sizeof(
SHARED_CACHE_MAP),
00531 'cScC' );
00532 }
00533
00534 SharedCacheMap = CacheMapToFree;
00535 CacheMapToFree =
NULL;
00536
00537
if (SharedCacheMap ==
NULL) {
00538
00539
DebugTrace( 0, 0,
"Failed to allocate SharedCacheMap\n", 0 );
00540
00541
CcReleaseMasterLock( OldIrql );
00542 SharedListOwned =
FALSE;
00543
00544
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
00545 }
00546
00547
00548
00549
00550
00551 RtlZeroMemory( SharedCacheMap,
sizeof(
SHARED_CACHE_MAP) );
00552
00553
#if DANLO
00554
SharedCacheMap->OpenCountLog.Size =
sizeof(SharedCacheMap->OpenCountLog.Log)/
sizeof(CC_LOG_ENTRY);
00555
#endif
00556
00557
00558
00559
00560
00561 SharedCacheMap->
NodeTypeCode =
CACHE_NTC_SHARED_CACHE_MAP;
00562 SharedCacheMap->
NodeByteSize =
sizeof(
SHARED_CACHE_MAP);
00563 SharedCacheMap->
FileObject = FileObject;
00564 SharedCacheMap->
FileSize = LocalSizes.
FileSize;
00565 SharedCacheMap->
ValidDataLength = LocalSizes.
ValidDataLength;
00566 SharedCacheMap->
ValidDataGoal = LocalSizes.
ValidDataLength;
00567
00568
00569
00570
00571
00572
00573
KeInitializeSpinLock( &SharedCacheMap->
ActiveVacbSpinLock );
00574
KeInitializeSpinLock( &SharedCacheMap->
BcbSpinLock );
00575
00576
if (PinAccess) {
00577
SetFlag(SharedCacheMap->
Flags,
PIN_ACCESS);
00578 }
00579
00580
00581
00582
00583
00584 SharedCacheMap->
LocalEvent = &SharedCacheMap->
Event;
00585
00586
00587
00588
00589
00590
00591
if (
FlagOn(FileObject->Flags,
FO_SEQUENTIAL_ONLY)) {
00592
SetFlag(SharedCacheMap->
Flags,
ONLY_SEQUENTIAL_ONLY_SEEN);
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602 InitializeListHead( &SharedCacheMap->
BcbList );
00603 SharedCacheMap->
Callbacks = Callbacks;
00604 SharedCacheMap->
LazyWriteContext = LazyWriteContext;
00605
00606
00607
00608
00609
00610 InitializeListHead( &SharedCacheMap->
PrivateList );
00611
00612
00613
00614
00615
00616 InsertTailList( &
CcCleanSharedCacheMapList,
00617 &SharedCacheMap->
SharedCacheMapLinks );
00618
00619
00620
00621
00622
00623
00624 FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;
00625
00626
00627
00628
00629
00630
00631
00632
00633
ObReferenceObject ( FileObject );
00634
00635 }
else {
00636
00637
00638
00639
00640
00641
00642
if (!
FlagOn(FileObject->Flags,
FO_SEQUENTIAL_ONLY)) {
00643
ClearFlag(SharedCacheMap->
Flags,
ONLY_SEQUENTIAL_ONLY_SEEN);
00644 }
00645 }
00646
00647
00648
00649
00650
00651
00652
if (
FlagOn(FileObject->Flags,
FO_RANDOM_ACCESS)) {
00653
SetFlag(SharedCacheMap->
Flags,
RANDOM_ACCESS_SEEN);
00654 }
00655
00656
00657
00658
00659
00660
00661
ClearFlag(SharedCacheMap->
Flags,
TRUNCATE_REQUIRED);
00662
00663
00664
00665
00666
00667
00668
if ((SharedCacheMap->
Vacbs ==
NULL) &&
00669 !
FlagOn(SharedCacheMap->
Flags,
BEING_CREATED)) {
00670
00671
00672
00673
00674
00675
CcIncrementOpenCount( SharedCacheMap, 'onnI' );
00676 MustUninitialize =
TRUE;
00677
00678
00679
00680
00681
00682
SetFlag(SharedCacheMap->
Flags,
BEING_CREATED);
00683 WeSetBeingCreated =
TRUE;
00684
00685
00686
00687
00688
00689
00690
00691
if (SharedCacheMap->
CreateEvent !=
NULL) {
00692
00693
KeInitializeEvent( SharedCacheMap->
CreateEvent,
00694 NotificationEvent,
00695
FALSE );
00696 }
00697
00698
00699
00700
00701
00702
CcReleaseMasterLock( OldIrql );
00703 SharedListOwned =
FALSE;
00704
00705
00706
00707
00708
00709
if (SharedCacheMap->
Section ==
NULL) {
00710
00711 LARGE_INTEGER LargeZero = {0,0};
00712
00713
00714
00715
00716
00717
00718
00719
00720
DebugTrace( 0,
mm,
"MmCreateSection:\n", 0 );
00721
DebugTrace2(0,
mm,
" MaximumSize = %08lx, %08lx\n",
00722 LocalSizes.
AllocationSize.LowPart,
00723 LocalSizes.
AllocationSize.HighPart );
00724
DebugTrace( 0,
mm,
" FileObject = %08lx\n", FileObject );
00725
00726 SharedCacheMap->
Status =
MmCreateSection( &SharedCacheMap->
Section,
00727 SECTION_MAP_READ
00728 | SECTION_MAP_WRITE
00729 | SECTION_QUERY,
00730
NULL,
00731 &LocalSizes.
AllocationSize,
00732 PAGE_READWRITE,
00733 SEC_COMMIT,
00734
NULL,
00735 FileObject );
00736
00737
DebugTrace( 0,
mm,
" <Section = %08lx\n", SharedCacheMap->
Section );
00738
00739
if (!
NT_SUCCESS( SharedCacheMap->
Status )){
00740
DebugTrace( 0, 0,
"Error from MmCreateSection = %08lx\n",
00741 SharedCacheMap->
Status );
00742
00743 SharedCacheMap->
Section =
NULL;
00744
ExRaiseStatus(
FsRtlNormalizeNtstatus( SharedCacheMap->
Status,
00745 STATUS_UNEXPECTED_MM_CREATE_ERR ));
00746 }
00747
00748
ObDeleteCapturedInsertInfo(SharedCacheMap->
Section);
00749
00750
00751
00752
00753
00754
00755
if (!
FlagOn(((
PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->Flags2,
00756
FSRTL_FLAG2_DO_MODIFIED_WRITE) &&
00757 (FileObject->FsContext2 ==
NULL)) {
00758
00759 BOOLEAN Disabled;
00760
00761 Disabled =
MmDisableModifiedWriteOfSection( FileObject->SectionObjectPointer );
00762
CcAcquireMasterLock( &OldIrql );
00763
SetFlag(SharedCacheMap->
Flags,
MODIFIED_WRITE_DISABLED);
00764
CcReleaseMasterLock( OldIrql );
00765
00766
00767 }
00768
00769
00770
00771
00772
00773
CcCreateVacbArray( SharedCacheMap, LocalSizes.
AllocationSize );
00774 }
00775
00776
00777
00778
00779
00780
00781
else {
00782
00783
if ( LocalSizes.
AllocationSize.QuadPart > SharedCacheMap->
SectionSize.QuadPart ) {
00784
00785
NTSTATUS Status;
00786
00787
DebugTrace( 0,
mm,
"MmExtendSection:\n", 0 );
00788
DebugTrace( 0,
mm,
" Section = %08lx\n", SharedCacheMap->
Section );
00789
DebugTrace2(0,
mm,
" Size = %08lx, %08lx\n",
00790 LocalSizes.
AllocationSize.LowPart,
00791 LocalSizes.
AllocationSize.HighPart );
00792
00793
Status =
MmExtendSection( SharedCacheMap->
Section,
00794 &LocalSizes.
AllocationSize,
00795
TRUE );
00796
00797
if (!
NT_SUCCESS(
Status)) {
00798
00799
DebugTrace( 0, 0,
"Error from MmExtendSection, Status = %08lx\n",
00800
Status );
00801
00802
ExRaiseStatus(
FsRtlNormalizeNtstatus(
Status,
00803 STATUS_UNEXPECTED_MM_EXTEND_ERR ));
00804 }
00805 }
00806
00807
00808
00809
00810
00811
CcExtendVacbArray( SharedCacheMap, LocalSizes.
AllocationSize );
00812 }
00813
00814
00815
00816
00817
00818
CcAcquireMasterLock( &OldIrql );
00819
ClearFlag(SharedCacheMap->
Flags,
BEING_CREATED);
00820 WeSetBeingCreated =
FALSE;
00821
if (SharedCacheMap->
CreateEvent !=
NULL) {
00822
KeSetEvent( SharedCacheMap->
CreateEvent, 0,
FALSE );
00823 }
00824
CcReleaseMasterLock( OldIrql );
00825 }
00826
00827
00828
00829
00830
00831
00832
else {
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
if (
FlagOn(SharedCacheMap->
Flags,
BEING_CREATED)) {
00843
00844
if (SharedCacheMap->
CreateEvent ==
NULL) {
00845
00846
00847
00848
00849
00850
00851 SharedCacheMap->
CreateEvent = InterlockedExchangePointer( &SharedCacheMap->
LocalEvent,
NULL );
00852
00853
if (SharedCacheMap->
CreateEvent ==
NULL) {
00854
00855 SharedCacheMap->
CreateEvent = (
PKEVENT)
ExAllocatePoolWithTag(
NonPagedPool,
00856
sizeof(
KEVENT),
00857 'vEcC' );
00858 }
00859
00860
if (SharedCacheMap->
CreateEvent ==
NULL) {
00861
DebugTrace( 0, 0,
"Failed to allocate CreateEvent\n", 0 );
00862
00863
CcReleaseMasterLock( OldIrql );
00864 SharedListOwned =
FALSE;
00865
00866
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
00867 }
00868
00869
KeInitializeEvent( SharedCacheMap->
CreateEvent,
00870 NotificationEvent,
00871
FALSE );
00872 }
00873
00874
00875
00876
00877
00878
CcIncrementOpenCount( SharedCacheMap, 'ecnI' );
00879 MustUninitialize =
TRUE;
00880
00881
00882
00883
00884
00885
CcReleaseMasterLock( OldIrql );
00886 SharedListOwned =
FALSE;
00887
00888
DebugTrace( 0, 0,
"Waiting on CreateEvent\n", 0 );
00889
00890
KeWaitForSingleObject( SharedCacheMap->
CreateEvent,
00891
Executive,
00892
KernelMode,
00893
FALSE,
00894 (PLARGE_INTEGER)
NULL);
00895
00896
00897
00898
00899
00900
00901
if (!
NT_SUCCESS(SharedCacheMap->
Status)) {
00902
ExRaiseStatus(
FsRtlNormalizeNtstatus( SharedCacheMap->
Status,
00903 STATUS_UNEXPECTED_MM_CREATE_ERR ));
00904 }
00905 }
00906
else {
00907
00908
PCACHE_UNINITIALIZE_EVENT CUEvent, EventNext;
00909
00910
00911
00912
00913
00914
CcIncrementOpenCount( SharedCacheMap, 'esnI' );
00915 MustUninitialize =
TRUE;
00916
00917
00918
00919
00920
00921
00922 CUEvent = SharedCacheMap->
UninitializeEvent;
00923
00924
while (CUEvent !=
NULL) {
00925 EventNext = CUEvent->
Next;
00926
KeSetEvent(&CUEvent->
Event, 0,
FALSE);
00927 CUEvent = EventNext;
00928 }
00929
00930 SharedCacheMap->
UninitializeEvent =
NULL;
00931
00932
00933
00934
00935
00936
CcReleaseMasterLock( OldIrql );
00937 SharedListOwned =
FALSE;
00938 }
00939 }
00940
00941 {
00942
PPRIVATE_CACHE_MAP PrivateCacheMap;
00943
00944
00945
00946
00947
00948
00949 PrivateCacheMap = &SharedCacheMap->
PrivateCacheMap;
00950
00951
00952
00953
00954
00955
00956
if (CacheMapToFree !=
NULL) {
00957
ExFreePool( CacheMapToFree );
00958 CacheMapToFree =
NULL;
00959 }
00960
00961
if (PrivateCacheMap->
NodeTypeCode != 0) {
00962 CacheMapToFree =
ExAllocatePoolWithTag(
NonPagedPool,
sizeof(
PRIVATE_CACHE_MAP), 'cPcC' );
00963 }
00964
00965
00966
00967
00968
00969
CcAcquireMasterLock( &OldIrql );
00970 SharedListOwned =
TRUE;
00971
00972
00973
00974
00975
00976
if (FileObject->PrivateCacheMap ==
NULL) {
00977
00978
00979
00980
00981
00982
if (PrivateCacheMap->
NodeTypeCode != 0) {
00983
00984
00985
00986
00987
00988
if (CacheMapToFree ==
NULL) {
00989 CacheMapToFree =
00990 (
PPRIVATE_CACHE_MAP)
ExAllocatePoolWithTag(
NonPagedPool,
00991
sizeof(
PRIVATE_CACHE_MAP),
00992 'cPcC' );
00993 }
00994 PrivateCacheMap = CacheMapToFree;
00995 CacheMapToFree =
NULL;
00996 }
00997
00998
if (PrivateCacheMap ==
NULL) {
00999
01000
DebugTrace( 0, 0,
"Failed to allocate PrivateCacheMap\n", 0 );
01001
01002
CcReleaseMasterLock( OldIrql );
01003 SharedListOwned =
FALSE;
01004
01005
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
01006 }
01007
01008 RtlZeroMemory( PrivateCacheMap,
sizeof(
PRIVATE_CACHE_MAP) );
01009
01010 PrivateCacheMap->
NodeTypeCode =
CACHE_NTC_PRIVATE_CACHE_MAP;
01011 PrivateCacheMap->
NodeByteSize =
sizeof(
PRIVATE_CACHE_MAP);
01012 PrivateCacheMap->
FileObject = FileObject;
01013 PrivateCacheMap->
ReadAheadMask =
PAGE_SIZE - 1;
01014
01015
01016
01017
01018
01019
KeInitializeSpinLock( &PrivateCacheMap->
ReadAheadSpinLock );
01020
01021 InsertTailList( &SharedCacheMap->
PrivateList, &PrivateCacheMap->
PrivateLinks );
01022
01023 FileObject->PrivateCacheMap = PrivateCacheMap;
01024
01025 }
else {
01026
01027
01028
01029
01030
01031
01032
ASSERT( SharedCacheMap->
OpenCount > 1 );
01033
01034
CcDecrementOpenCount( SharedCacheMap, 'rpnI' );
01035 SharedCacheMap =
NULL;
01036 }
01037 }
01038
01039 MustUninitialize =
FALSE;
01040 try_exit: NOTHING;
01041 }
01042 finally {
01043
01044
01045
01046
01047
01048
if (MustUninitialize) {
01049
01050
if (!SharedListOwned) {
01051
CcAcquireMasterLock( &OldIrql );
01052 }
01053
if (WeSetBeingCreated) {
01054
if (SharedCacheMap->
CreateEvent !=
NULL) {
01055
KeSetEvent( SharedCacheMap->
CreateEvent, 0,
FALSE );
01056 }
01057
ClearFlag(SharedCacheMap->
Flags,
BEING_CREATED);
01058 }
01059
01060
01061
01062
01063
01064
CcDecrementOpenCount( SharedCacheMap, 'umnI' );
01065
01066
if ((SharedCacheMap->
OpenCount == 0) &&
01067 !
FlagOn(SharedCacheMap->
Flags,
WRITE_QUEUED) &&
01068 (SharedCacheMap->
DirtyPages == 0)) {
01069
01070
01071
01072
01073
01074
01075
if (PinAccess) {
01076
01077
CcDeleteSharedCacheMap( SharedCacheMap, OldIrql,
FALSE );
01078
01079
01080
01081
01082
01083
01084
01085 }
else {
01086
01087
01088
01089
01090
01091
01092 RemoveEntryList( &SharedCacheMap->
SharedCacheMapLinks );
01093 InsertTailList( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks,
01094 &SharedCacheMap->
SharedCacheMapLinks );
01095
01096
01097
01098
01099
01100
01101
LazyWriter.
OtherWork =
TRUE;
01102
if (!
LazyWriter.
ScanActive) {
01103
CcScheduleLazyWriteScan();
01104 }
01105
01106
CcReleaseMasterLock( OldIrql );
01107 }
01108
01109 }
else {
01110
01111
CcReleaseMasterLock( OldIrql );
01112 }
01113
01114 SharedListOwned =
FALSE;
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 }
else if (!WeCreated &&
01126 (SharedCacheMap !=
NULL)) {
01127
01128
if (!SharedListOwned) {
01129
01130
CcAcquireMasterLock( &OldIrql );
01131 SharedListOwned =
TRUE;
01132 }
01133
01134
if ((SharedCacheMap->
DirtyPages == 0) &&
01135 (SharedCacheMap->
OpenCount != 0)) {
01136
01137 RemoveEntryList( &SharedCacheMap->
SharedCacheMapLinks );
01138 InsertTailList( &
CcCleanSharedCacheMapList,
01139 &SharedCacheMap->
SharedCacheMapLinks );
01140 }
01141 }
01142
01143
01144
01145
01146
01147
if (SharedListOwned) {
01148
CcReleaseMasterLock( OldIrql );
01149 }
01150
01151
if (CacheMapToFree !=
NULL) {
01152
ExFreePool(CacheMapToFree);
01153 }
01154
01155 }
01156
01157
DebugTrace(-1,
me,
"CcInitializeCacheMap -> VOID\n", 0 );
01158
01159
return;
01160 }
01161
01162
01163 BOOLEAN
01164 CcUninitializeCacheMap (
01165 IN
PFILE_OBJECT FileObject,
01166 IN PLARGE_INTEGER TruncateSize OPTIONAL,
01167 IN
PCACHE_UNINITIALIZE_EVENT UninitializeEvent OPTIONAL
01168 )
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227 {
01228 KIRQL OldIrql;
01229
PSHARED_CACHE_MAP SharedCacheMap;
01230 ULONG ActivePage;
01231 ULONG PageIsDirty;
01232
PVACB ActiveVacb =
NULL;
01233 BOOLEAN SectionClosed =
FALSE;
01234 BOOLEAN SharedListAcquired =
FALSE;
01235
PPRIVATE_CACHE_MAP PrivateCacheMap;
01236
01237
DebugTrace(+1,
me,
"CcUninitializeCacheMap:\n", 0 );
01238
DebugTrace( 0,
me,
" FileObject = %08lx\n", FileObject );
01239
DebugTrace( 0,
me,
" &TruncateSize = %08lx\n", TruncateSize );
01240
01241
01242
01243
01244
01245
try {
01246
01247
01248
01249
01250
01251
CcAcquireMasterLock( &OldIrql );
01252 SharedListAcquired =
TRUE;
01253
01254
01255
01256
01257
01258 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
01259 PrivateCacheMap = FileObject->PrivateCacheMap;
01260
01261
01262
01263
01264
01265
01266
if (PrivateCacheMap !=
NULL) {
01267
01268
ASSERT( PrivateCacheMap->
FileObject == FileObject );
01269
01270
CcDecrementOpenCount( SharedCacheMap, 'ninU' );
01271
01272
01273
01274
01275
01276 RemoveEntryList( &PrivateCacheMap->
PrivateLinks );
01277
01278
01279
01280
01281
01282
if (PrivateCacheMap == &SharedCacheMap->
PrivateCacheMap) {
01283 PrivateCacheMap->
NodeTypeCode = 0;
01284 PrivateCacheMap =
NULL;
01285 }
01286
01287 FileObject->PrivateCacheMap = (
PPRIVATE_CACHE_MAP)
NULL;
01288 }
01289
01290
01291
01292
01293
01294
01295
if (SharedCacheMap !=
NULL) {
01296
01297
01298
01299
01300
01301
01302
01303
if (ARGUMENT_PRESENT(TruncateSize)) {
01304
01305
if ( (TruncateSize->QuadPart == 0) && (SharedCacheMap->
FileSize.QuadPart != 0) ) {
01306
01307
SetFlag(SharedCacheMap->
Flags,
TRUNCATE_REQUIRED);
01308
01309 }
else
01310
01311
01312
01313
01314
01315
01316
if (IsListEmpty(&SharedCacheMap->
PrivateList)) {
01317 SharedCacheMap->
FileSize = *TruncateSize;
01318 }
01319 }
01320
01321
01322
01323
01324
01325
01326
if (SharedCacheMap->
OpenCount != 0) {
01327
01328
DebugTrace(-1,
me,
"SharedCacheMap OpenCount != 0\n", 0);
01329
01330
01331
01332
01333
01334
01335
01336
01337
if (ARGUMENT_PRESENT(UninitializeEvent)) {
01338
01339
if (!IsListEmpty(&SharedCacheMap->
PrivateList)) {
01340
KeSetEvent(&UninitializeEvent->Event, 0,
FALSE);
01341 }
else {
01342 UninitializeEvent->Next = SharedCacheMap->
UninitializeEvent;
01343 SharedCacheMap->
UninitializeEvent = UninitializeEvent;
01344 }
01345 }
01346
01347
try_return( SectionClosed =
FALSE );
01348 }
01349
01350
01351
01352
01353
01354
ASSERT(IsListEmpty(&SharedCacheMap->
PrivateList));
01355
01356
01357
01358
01359
01360
01361
if (ARGUMENT_PRESENT(UninitializeEvent)) {
01362 UninitializeEvent->Next = SharedCacheMap->
UninitializeEvent;
01363 SharedCacheMap->
UninitializeEvent = UninitializeEvent;
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
if ((!
FlagOn(SharedCacheMap->
Flags,
PIN_ACCESS) &&
01375 !ARGUMENT_PRESENT(UninitializeEvent))
01376
01377 ||
01378
01379
FlagOn(SharedCacheMap->
Flags,
WRITE_QUEUED)
01380
01381 ||
01382
01383 (SharedCacheMap->
DirtyPages != 0)) {
01384
01385
01386
01387
01388
01389
01390
if (!
FlagOn(SharedCacheMap->
Flags,
WRITE_QUEUED)) {
01391 RemoveEntryList( &SharedCacheMap->
SharedCacheMapLinks );
01392 InsertTailList( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks,
01393 &SharedCacheMap->
SharedCacheMapLinks );
01394 }
01395
01396
01397
01398
01399
01400
01401
LazyWriter.
OtherWork =
TRUE;
01402
if (!
LazyWriter.
ScanActive) {
01403
CcScheduleLazyWriteScan();
01404 }
01405
01406
01407
01408
01409
01410
01411
GetActiveVacbAtDpcLevel( SharedCacheMap, ActiveVacb, ActivePage, PageIsDirty );
01412
01413
DebugTrace(-1,
me,
"SharedCacheMap has Bcbs and not purging to 0\n", 0);
01414
01415
try_return( SectionClosed =
FALSE );
01416 }
01417
01418
01419
01420
01421
01422
01423
01424
CcDeleteSharedCacheMap( SharedCacheMap, OldIrql,
FALSE );
01425
01426 SharedListAcquired =
FALSE;
01427
01428
try_return( SectionClosed =
TRUE );
01429 }
01430
01431
01432
01433
01434
01435
01436
01437
else {
01438
if (ARGUMENT_PRESENT(TruncateSize) &&
01439 ( TruncateSize->QuadPart == 0 ) &&
01440 (*(PCHAR *)FileObject->SectionObjectPointer !=
NULL)) {
01441
01442
CcReleaseMasterLock( OldIrql );
01443 SharedListAcquired =
FALSE;
01444
01445
DebugTrace( 0,
mm,
"MmPurgeSection:\n", 0 );
01446
DebugTrace( 0,
mm,
" SectionObjectPointer = %08lx\n",
01447 FileObject->SectionObjectPointer );
01448
DebugTrace2(0,
mm,
" Offset = %08lx\n",
01449 TruncateSize->LowPart,
01450 TruncateSize->HighPart );
01451
01452
01453
01454
01455
01456
CcPurgeCacheSection( FileObject->SectionObjectPointer,
01457 TruncateSize,
01458 0,
01459
FALSE );
01460 }
01461
01462
01463
01464
01465
01466
01467
01468
if (ARGUMENT_PRESENT(UninitializeEvent)) {
01469
KeSetEvent(&UninitializeEvent->Event, 0,
FALSE);
01470 }
01471
01472 }
01473
01474 try_exit: NOTHING;
01475 }
01476 finally {
01477
01478
01479
01480
01481
01482
if (SharedListAcquired) {
01483
CcReleaseMasterLock( OldIrql );
01484 }
01485
01486
01487
01488
01489
01490
if (ActiveVacb !=
NULL) {
01491
01492
CcFreeActiveVacb( ActiveVacb->
SharedCacheMap, ActiveVacb, ActivePage, PageIsDirty );
01493 }
01494
01495
01496
01497
01498
01499
if (PrivateCacheMap !=
NULL) {
01500
ExFreePool( PrivateCacheMap );
01501 }
01502 }
01503
01504
DebugTrace(-1,
me,
"CcUnitializeCacheMap -> %02lx\n", SectionClosed );
01505
01506
return SectionClosed;
01507
01508 }
01509
01510
01511
01512
01513
01514
01515
VOID
01516
FASTCALL
01517 CcDeleteSharedCacheMap (
01518 IN
PSHARED_CACHE_MAP SharedCacheMap,
01519 IN KIRQL ListIrql,
01520 IN ULONG ReleaseFile
01521 )
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550 {
01551 LIST_ENTRY LocalList;
01552 PLIST_ENTRY NextEntry;
01553
PFILE_OBJECT FileObject;
01554
PVACB ActiveVacb;
01555 ULONG ActivePage;
01556 ULONG PageIsDirty;
01557 KIRQL OldIrql;
01558
PMBCB Mbcb;
01559
01560
DebugTrace(+1,
me,
"CcDeleteSharedCacheMap:\n", 0 );
01561
DebugTrace( 0,
me,
" SharedCacheMap = %08lx\n", SharedCacheMap );
01562
01563
01564
01565
01566
01567
01568 RemoveEntryList( &SharedCacheMap->SharedCacheMapLinks );
01569
01570
01571
01572
01573
01574
01575 FileObject = SharedCacheMap->FileObject;
01576
01577 FileObject->
SectionObjectPointer->
SharedCacheMap = (
PSHARED_CACHE_MAP)
NULL;
01578
SetFlag( SharedCacheMap->Flags,
WRITE_QUEUED );
01579
01580
01581
01582
01583
01584
01585
if ((SharedCacheMap->VacbActiveCount != 0) || (SharedCacheMap->NeedToZero !=
NULL)) {
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595 InitializeListHead( &LocalList );
01596 InsertTailList( &LocalList, &SharedCacheMap->SharedCacheMapLinks );
01597
01598
01599
01600
01601
01602
GetActiveVacbAtDpcLevel( SharedCacheMap, ActiveVacb, ActivePage, PageIsDirty );
01603
01604
CcReleaseMasterLock( ListIrql );
01605
01606
01607
01608
01609
01610
01611
CcFreeActiveVacb( SharedCacheMap, ActiveVacb, ActivePage,
FALSE );
01612
01613
while (SharedCacheMap->VacbActiveCount != 0) {
01614
CcWaitOnActiveCount( SharedCacheMap );
01615 }
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
CcAcquireMasterLock( &ListIrql );
01627 RemoveEntryList( &SharedCacheMap->SharedCacheMapLinks );
01628 }
01629
01630
CcReleaseMasterLock( ListIrql );
01631
01632
01633
01634
01635
01636
01637 NextEntry = SharedCacheMap->BcbList.Flink;
01638
while (NextEntry != &SharedCacheMap->BcbList) {
01639
01640
PBCB Bcb;
01641
01642 Bcb = (
PBCB)CONTAINING_RECORD( NextEntry,
01643
BCB,
01644 BcbLinks );
01645 NextEntry = Bcb->
BcbLinks.Flink;
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
if (Bcb->
NodeTypeCode ==
CACHE_NTC_BCB) {
01658
01659
ASSERT( Bcb->
PinCount == 0 );
01660
01661 RemoveEntryList( &Bcb->
BcbLinks );
01662
01663
01664
01665
01666
01667
01668
01669
CcUnlockVacbLevel( SharedCacheMap, Bcb->
FileOffset.QuadPart );
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
if (Bcb->
BaseAddress !=
NULL) {
01680
CcFreeVirtualAddress( Bcb->
Vacb );
01681 }
01682
01683
01684
01685
01686
01687
#if LIST_DBG
01688
01689 {
01690 KIRQL OldIrql;
01691
01692 ExAcquireSpinLock( &
CcBcbSpinLock, &OldIrql );
01693
01694
if (Bcb->CcBcbLinks.Flink !=
NULL) {
01695
01696 RemoveEntryList( &Bcb->CcBcbLinks );
01697 CcBcbCount -= 1;
01698 }
01699
01700 ExReleaseSpinLock( &
CcBcbSpinLock, OldIrql );
01701 }
01702
01703
#endif
01704
01705
01706
01707
01708
01709
01710
CcAcquireMasterLock( &ListIrql );
01711
if (Bcb->
Dirty) {
01712
01713 SharedCacheMap->DirtyPages -= Bcb->
ByteLength >>
PAGE_SHIFT;
01714
CcTotalDirtyPages -= Bcb->
ByteLength >>
PAGE_SHIFT;
01715 }
01716
01717
CcReleaseMasterLock( ListIrql );
01718
01719
CcDeallocateBcb( Bcb );
01720 }
01721 }
01722
01723
01724
01725
01726
01727
CcUnmapAndPurge( SharedCacheMap );
01728
01729
01730
01731
01732
01733
if (ReleaseFile) {
01734
FsRtlReleaseFile( SharedCacheMap->FileObject );
01735 }
01736
01737
01738
01739
01740
01741
01742
01743
01744
if (SharedCacheMap->Section !=
NULL) {
01745
ObDereferenceObject( SharedCacheMap->Section );
01746 }
01747
ObDereferenceObject( FileObject );
01748
01749
01750
01751
01752
01753
if (SharedCacheMap->Mbcb !=
NULL) {
01754
CcDeleteMbcb( SharedCacheMap );
01755 }
01756
01757
01758
01759
01760
01761
01762
01763
if (SharedCacheMap->UninitializeEvent !=
NULL) {
01764
PCACHE_UNINITIALIZE_EVENT CUEvent, EventNext;
01765
01766 CUEvent = SharedCacheMap->UninitializeEvent;
01767
while (CUEvent !=
NULL) {
01768 EventNext = CUEvent->
Next;
01769
KeSetEvent(&CUEvent->
Event, 0,
FALSE);
01770 CUEvent = EventNext;
01771 }
01772 }
01773
01774
01775
01776
01777
01778
if ((SharedCacheMap->Vacbs != &SharedCacheMap->InitialVacbs[0])
01779
01780 &&
01781
01782 (SharedCacheMap->Vacbs !=
NULL)) {
01783
01784
01785
01786
01787
01788
ASSERT((SharedCacheMap->SectionSize.QuadPart <=
VACB_SIZE_OF_FIRST_LEVEL) ||
01789 !
IsVacbLevelReferenced( SharedCacheMap, SharedCacheMap->Vacbs, 1 ));
01790
01791
ExFreePool( SharedCacheMap->Vacbs );
01792 }
01793
01794
01795
01796
01797
01798
01799
if ((SharedCacheMap->CreateEvent !=
NULL) && (SharedCacheMap->CreateEvent != &SharedCacheMap->Event)) {
01800
ExFreePool( SharedCacheMap->CreateEvent );
01801 }
01802
01803
if ((SharedCacheMap->WaitOnActiveCount !=
NULL) && (SharedCacheMap->WaitOnActiveCount != &SharedCacheMap->Event)) {
01804
ExFreePool( SharedCacheMap->WaitOnActiveCount );
01805 }
01806
01807
01808
01809
01810
01811
ExFreePool( SharedCacheMap );
01812
01813
DebugTrace(-1,
me,
"CcDeleteSharedCacheMap -> VOID\n", 0 );
01814
01815
return;
01816
01817 }
01818
01819
01820
VOID
01821 CcSetFileSizes (
01822 IN
PFILE_OBJECT FileObject,
01823 IN
PCC_FILE_SIZES FileSizes
01824 )
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861 {
01862 LARGE_INTEGER NewSectionSize;
01863 LARGE_INTEGER NewFileSize;
01864 LARGE_INTEGER NewValidDataLength;
01865 IO_STATUS_BLOCK IoStatus;
01866
PSHARED_CACHE_MAP SharedCacheMap;
01867
NTSTATUS Status;
01868 KIRQL OldIrql;
01869
PVACB ActiveVacb;
01870 ULONG ActivePage;
01871 ULONG PageIsDirty;
01872
01873
DebugTrace(+1,
me,
"CcSetFileSizes:\n", 0 );
01874
DebugTrace( 0,
me,
" FileObject = %08lx\n", FileObject );
01875
DebugTrace( 0,
me,
" FileSizes = %08lx\n", FileSizes );
01876
01877
01878
01879
01880
01881 NewSectionSize = FileSizes->AllocationSize;
01882 NewFileSize = FileSizes->FileSize;
01883 NewValidDataLength = FileSizes->ValidDataLength;
01884
01885
01886
01887
01888
01889
CcAcquireMasterLock( &OldIrql );
01890
01891
01892
01893
01894
01895 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
01896
01897
01898
01899
01900
01901
if ((SharedCacheMap ==
NULL) || (SharedCacheMap->
Section ==
NULL)) {
01902
01903
CcReleaseMasterLock( OldIrql );
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
if (NewFileSize.LowPart & (
PAGE_SIZE - 1)) {
01918
MmFlushSection( FileObject->SectionObjectPointer, &NewFileSize, 1, &IoStatus,
FALSE );
01919 }
01920
01921
CcPurgeCacheSection( FileObject->SectionObjectPointer,
01922 &NewFileSize,
01923 0,
01924
FALSE );
01925
01926
DebugTrace(-1,
me,
"CcSetFileSizes -> VOID\n", 0 );
01927
01928
return;
01929 }
01930
01931
01932
01933
01934
01935
if ( NewSectionSize.QuadPart > SharedCacheMap->
SectionSize.QuadPart ) {
01936
01937
01938
01939
01940
01941
01942
CcIncrementOpenCount( SharedCacheMap, '1fSS' );
01943
CcReleaseMasterLock( OldIrql );
01944
01945
01946
01947
01948
01949 NewSectionSize.QuadPart = NewSectionSize.QuadPart + (LONGLONG)(
DEFAULT_EXTEND_MODULO - 1);
01950 NewSectionSize.LowPart &= ~(
DEFAULT_EXTEND_MODULO - 1);
01951
01952
01953
01954
01955
01956
try {
01957
01958
01959
01960
01961
01962
DebugTrace( 0,
mm,
"MmExtendSection:\n", 0 );
01963
DebugTrace( 0,
mm,
" Section = %08lx\n", SharedCacheMap->
Section );
01964
DebugTrace2(0,
mm,
" Size = %08lx, %08lx\n",
01965 NewSectionSize.LowPart, NewSectionSize.HighPart );
01966
01967
Status =
MmExtendSection( SharedCacheMap->
Section, &NewSectionSize,
TRUE );
01968
01969
if (!
NT_SUCCESS(
Status)) {
01970
01971
DebugTrace( 0, 0,
"Error from MmExtendSection, Status = %08lx\n",
01972
Status );
01973
01974
ExRaiseStatus(
FsRtlNormalizeNtstatus(
Status,
01975 STATUS_UNEXPECTED_MM_EXTEND_ERR ));
01976 }
01977
01978
01979
01980
01981
01982
CcExtendVacbArray( SharedCacheMap, NewSectionSize );
01983
01984 } finally {
01985
01986
01987
01988
01989
01990
CcAcquireMasterLock( &OldIrql );
01991
01992
CcDecrementOpenCount( SharedCacheMap, '1fSF' );
01993
01994
if ((SharedCacheMap->
OpenCount == 0) &&
01995 !
FlagOn(SharedCacheMap->
Flags,
WRITE_QUEUED) &&
01996 (SharedCacheMap->
DirtyPages == 0)) {
01997
01998
01999
02000
02001
02002 RemoveEntryList( &SharedCacheMap->
SharedCacheMapLinks );
02003 InsertTailList( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks,
02004 &SharedCacheMap->
SharedCacheMapLinks );
02005
02006
02007
02008
02009
02010
02011
LazyWriter.
OtherWork =
TRUE;
02012
if (!
LazyWriter.
ScanActive) {
02013
CcScheduleLazyWriteScan();
02014 }
02015 }
02016
02017
CcReleaseMasterLock( OldIrql );
02018 }
02019
02020
02021
02022
02023
02024
02025
CcAcquireMasterLock( &OldIrql );
02026
02027
02028
02029
02030
02031 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
02032
02033
02034
02035
02036
02037
if (SharedCacheMap ==
NULL) {
02038
02039
CcReleaseMasterLock( OldIrql );
02040
02041
DebugTrace(-1,
me,
"CcSetFileSizes -> VOID\n", 0 );
02042
02043
return;
02044 }
02045 }
02046
02047
02048
02049
02050
02051
02052
CcIncrementOpenCount( SharedCacheMap, '2fSS' );
02053
02054
try {
02055
02056
if ( ( NewFileSize.QuadPart < SharedCacheMap->
ValidDataGoal.QuadPart ) ||
02057 ( NewFileSize.QuadPart < SharedCacheMap->
FileSize.QuadPart )) {
02058
02059
GetActiveVacbAtDpcLevel( SharedCacheMap, ActiveVacb, ActivePage, PageIsDirty );
02060
02061
if ((ActiveVacb !=
NULL) || (SharedCacheMap->
NeedToZero !=
NULL)) {
02062
02063
CcReleaseMasterLock( OldIrql );
02064
02065
CcFreeActiveVacb( SharedCacheMap, ActiveVacb, ActivePage, PageIsDirty );
02066
02067
02068
02069
02070
02071
02072
CcAcquireMasterLock( &OldIrql );
02073 }
02074 }
02075
02076
02077
02078
02079
02080
02081
if ( SharedCacheMap->
ValidDataLength.QuadPart != MAXLONGLONG ) {
02082
02083
if ( NewFileSize.QuadPart < SharedCacheMap->
ValidDataLength.QuadPart ) {
02084 SharedCacheMap->
ValidDataLength = NewFileSize;
02085 }
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
if (NewValidDataLength.QuadPart > SharedCacheMap->
ValidDataGoal.QuadPart) {
02096 SharedCacheMap->
ValidDataGoal = NewValidDataLength;
02097 }
02098 }
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
if ( (NewFileSize.QuadPart < SharedCacheMap->
FileSize.QuadPart ) &&
02118 !
FlagOn(SharedCacheMap->
Flags,
PIN_ACCESS) &&
02119 (SharedCacheMap->
VacbActiveCount == 0)) {
02120
02121
02122
02123
02124
02125
CcReleaseMasterLock( OldIrql );
02126
02127
02128
02129
02130
02131
02132
02133
if ((NewFileSize.QuadPart == 0) && (SharedCacheMap->
Mbcb !=
NULL)) {
02134
CcDeleteMbcb( SharedCacheMap );
02135 }
02136
02137
CcPurgeAndClearCacheSection( SharedCacheMap, &NewFileSize );
02138
02139
02140
02141
02142
02143
CcAcquireMasterLock( &OldIrql );
02144 }
02145
02146 } finally {
02147
02148
02149
02150
02151
02152
if (AbnormalTermination()) {
02153
02154
CcAcquireMasterLock( &OldIrql );
02155 }
02156
02157
CcDecrementOpenCount( SharedCacheMap, '2fSF' );
02158
02159 SharedCacheMap->
FileSize = NewFileSize;
02160
02161
if ((SharedCacheMap->
OpenCount == 0) &&
02162 !
FlagOn(SharedCacheMap->
Flags,
WRITE_QUEUED) &&
02163 (SharedCacheMap->
DirtyPages == 0)) {
02164
02165
02166
02167
02168
02169 RemoveEntryList( &SharedCacheMap->
SharedCacheMapLinks );
02170 InsertTailList( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks,
02171 &SharedCacheMap->
SharedCacheMapLinks );
02172
02173
02174
02175
02176
02177
02178
LazyWriter.
OtherWork =
TRUE;
02179
if (!
LazyWriter.
ScanActive) {
02180
CcScheduleLazyWriteScan();
02181 }
02182 }
02183
02184
CcReleaseMasterLock( OldIrql );
02185 }
02186
02187
DebugTrace(-1,
me,
"CcSetFileSizes -> VOID\n", 0 );
02188
02189
return;
02190 }
02191
02192
02193
VOID
02194 CcPurgeAndClearCacheSection (
02195 IN
PSHARED_CACHE_MAP SharedCacheMap,
02196 IN PLARGE_INTEGER FileOffset
02197 )
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222 {
02223 ULONG TempLength, Length;
02224 LARGE_INTEGER LocalFileOffset;
02225 IO_STATUS_BLOCK IoStatus;
02226 PVOID TempVa;
02227
PVACB Vacb;
02228
02229
02230
02231
02232
02233
02234
if ((FileOffset->LowPart & (
PAGE_SIZE - 1)) != 0) {
02235
02236
02237
02238
02239
02240
02241 LocalFileOffset = *FileOffset;
02242 FileOffset = &LocalFileOffset;
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
if ((SharedCacheMap->Section !=
NULL) &&
02253 (SharedCacheMap->Vacbs !=
NULL)) {
02254
02255
02256
02257
02258
02259
02260 TempLength =
PAGE_SIZE - (FileOffset->LowPart & (
PAGE_SIZE - 1));
02261
02262 TempVa =
CcGetVirtualAddress( SharedCacheMap, *FileOffset, &Vacb, &Length );
02263
02264
try {
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276 RtlZeroMemory( TempVa, TempLength );
02277
02278
if (FileOffset->QuadPart <= SharedCacheMap->ValidDataGoal.QuadPart) {
02279
02280
02281
02282
02283
02284
CcSetDirtyInMask( SharedCacheMap, FileOffset, TempLength );
02285
02286
02287
02288
02289
02290
02291 }
else {
02292
02293
MmSetAddressRangeModified( TempVa, 1 );
02294 }
02295
02296 FileOffset->QuadPart += (LONGLONG)TempLength;
02297
02298
02299
02300
02301
02302
02303
02304
02305 } except(
EXCEPTION_EXECUTE_HANDLER) {
02306
02307 NOTHING;
02308 }
02309
02310
CcFreeVirtualAddress( Vacb );
02311
02312 }
else {
02313
02314
02315
02316
02317
02318
02319
MmFlushSection( SharedCacheMap->FileObject->SectionObjectPointer, FileOffset, 1, &IoStatus,
FALSE );
02320 }
02321 }
02322
02323
CcPurgeCacheSection( SharedCacheMap->FileObject->SectionObjectPointer,
02324 FileOffset,
02325 0,
02326
FALSE );
02327 }
02328
02329
02330 BOOLEAN
02331 CcPurgeCacheSection (
02332 IN
PSECTION_OBJECT_POINTERS SectionObjectPointer,
02333 IN PLARGE_INTEGER FileOffset,
02334 IN ULONG Length,
02335 IN BOOLEAN UninitializeCacheMaps
02336 )
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380 {
02381 KIRQL OldIrql;
02382
PSHARED_CACHE_MAP SharedCacheMap;
02383
PPRIVATE_CACHE_MAP PrivateCacheMap;
02384 ULONG ActivePage;
02385 ULONG PageIsDirty;
02386 BOOLEAN PurgeWorked =
TRUE;
02387
PVACB Vacb =
NULL;
02388
02389
DebugTrace(+1,
me,
"CcPurgeCacheSection:\n", 0 );
02390
DebugTrace( 0,
mm,
" SectionObjectPointer = %08lx\n", SectionObjectPointer );
02391
DebugTrace2(0,
me,
" FileOffset = %08lx, %08lx\n",
02392 ARGUMENT_PRESENT(FileOffset) ? FileOffset->LowPart
02393 : 0,
02394 ARGUMENT_PRESENT(FileOffset) ? FileOffset->HighPart
02395 : 0 );
02396
DebugTrace( 0,
me,
" Length = %08lx\n", Length );
02397
02398
02399
02400
02401
02402
02403
02404
ASSERT(!UninitializeCacheMaps || (Length == 0) || (Length >=
PAGE_SIZE * 2));
02405
02406
02407
02408
02409
02410
CcAcquireMasterLock( &OldIrql );
02411
02412
02413
02414
02415
02416 SharedCacheMap = SectionObjectPointer->SharedCacheMap;
02417
02418
02419
02420
02421
02422
02423
if (SharedCacheMap !=
NULL) {
02424
02425
CcIncrementOpenCount( SharedCacheMap, 'scPS' );
02426
02427
02428
02429
02430
02431
GetActiveVacbAtDpcLevel( SharedCacheMap, Vacb, ActivePage, PageIsDirty );
02432 }
02433
02434
CcReleaseMasterLock( OldIrql );
02435
02436
if (Vacb !=
NULL) {
02437
02438
CcFreeActiveVacb( SharedCacheMap, Vacb, ActivePage, PageIsDirty );
02439 }
02440
02441
02442
02443
02444
02445
02446
try {
02447
02448
02449
02450
02451
02452
02453
if (SharedCacheMap !=
NULL) {
02454
02455
02456
02457
02458
02459
if (UninitializeCacheMaps) {
02460
02461
while (!IsListEmpty( &SharedCacheMap->
PrivateList )) {
02462
02463 PrivateCacheMap = CONTAINING_RECORD( SharedCacheMap->
PrivateList.Flink,
02464
PRIVATE_CACHE_MAP,
02465 PrivateLinks );
02466
02467
CcUninitializeCacheMap( PrivateCacheMap->
FileObject,
NULL,
NULL );
02468 }
02469 }
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
while ((SharedCacheMap->
Vacbs !=
NULL) &&
02482 !
CcUnmapVacbArray( SharedCacheMap, FileOffset, Length,
FALSE )) {
02483
02484
CcWaitOnActiveCount( SharedCacheMap );
02485 }
02486 }
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
while (!(PurgeWorked =
MmPurgeSection(SectionObjectPointer,
02499 FileOffset,
02500 Length,
02501 (BOOLEAN)((SharedCacheMap !=
NULL) &&
02502 ARGUMENT_PRESENT(FileOffset)))) &&
02503 (Length == 0) &&
02504
MmCanFileBeTruncated(SectionObjectPointer, FileOffset)) {
02505
02506 (
VOID)
KeDelayExecutionThread(
KernelMode,
FALSE, &
CcCollisionDelay );
02507 }
02508
02509 } finally {
02510
02511
02512
02513
02514
02515
if (SharedCacheMap !=
NULL) {
02516
02517
02518
02519
02520
02521
CcAcquireMasterLock( &OldIrql );
02522
02523
CcDecrementOpenCount( SharedCacheMap, 'scPF' );
02524
02525
if ((SharedCacheMap->
OpenCount == 0) &&
02526 !
FlagOn(SharedCacheMap->
Flags,
WRITE_QUEUED) &&
02527 (SharedCacheMap->
DirtyPages == 0)) {
02528
02529
02530
02531
02532
02533 RemoveEntryList( &SharedCacheMap->
SharedCacheMapLinks );
02534 InsertTailList( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks,
02535 &SharedCacheMap->
SharedCacheMapLinks );
02536
02537
02538
02539
02540
02541
02542
LazyWriter.
OtherWork =
TRUE;
02543
if (!
LazyWriter.
ScanActive) {
02544
CcScheduleLazyWriteScan();
02545 }
02546 }
02547
02548
CcReleaseMasterLock( OldIrql );
02549 }
02550 }
02551
02552
DebugTrace(-1,
me,
"CcPurgeCacheSection -> %02lx\n", PurgeWorked );
02553
02554
return PurgeWorked;
02555 }
02556
02557
02558
02559
02560
02561
02562
VOID
02563 CcUnmapAndPurge(
02564 IN
PSHARED_CACHE_MAP SharedCacheMap
02565 )
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584 {
02585
PFILE_OBJECT FileObject;
02586 KIRQL OldIrql;
02587
02588 FileObject = SharedCacheMap->FileObject;
02589
02590
02591
02592
02593
02594
if (SharedCacheMap->Vacbs !=
NULL) {
02595 (
VOID)
CcUnmapVacbArray( SharedCacheMap,
NULL, 0,
FALSE );
02596 }
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
if (
FlagOn(SharedCacheMap->Flags,
TRUNCATE_REQUIRED)) {
02609
02610
DebugTrace( 0,
mm,
"MmPurgeSection:\n", 0 );
02611
DebugTrace( 0,
mm,
" SectionObjectPointer = %08lx\n",
02612 FileObject->
SectionObjectPointer );
02613
DebugTrace2(0,
mm,
" Offset = %08lx\n",
02614 SharedCacheMap->FileSize.LowPart,
02615 SharedCacheMap->FileSize.HighPart );
02616
02617
CcPurgeCacheSection( FileObject->
SectionObjectPointer,
02618
NULL,
02619 0,
02620
FALSE );
02621 }
02622 }
02623
02624
02625
VOID
02626 CcDeleteMbcb(
02627 IN
PSHARED_CACHE_MAP SharedCacheMap
02628 )
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647 {
02648
PMBCB Mbcb;
02649
PBITMAP_RANGE BitmapRange;
02650 KIRQL OldIrql;
02651 ULONG DoDrain =
FALSE;
02652
02653 ExAcquireSpinLock( &SharedCacheMap->BcbSpinLock, &OldIrql );
02654
02655 Mbcb = SharedCacheMap->Mbcb;
02656
02657
02658
02659
02660
02661
if (Mbcb !=
NULL) {
02662
02663
02664
02665
02666
02667
CcAcquireMasterLockAtDpcLevel();
02668
CcTotalDirtyPages -= Mbcb->
DirtyPages;
02669 SharedCacheMap->DirtyPages -= Mbcb->
DirtyPages;
02670
CcReleaseMasterLockFromDpcLevel();
02671
02672
02673
02674
02675
02676
while (!IsListEmpty(&Mbcb->
BitmapRanges)) {
02677
02678
02679
02680
02681
02682 BitmapRange = (
PBITMAP_RANGE)CONTAINING_RECORD( Mbcb->
BitmapRanges.Flink,
02683
BITMAP_RANGE,
02684 Links );
02685
02686 RemoveEntryList( &BitmapRange->
Links );
02687
02688
02689
02690
02691
02692
02693
if ((BitmapRange->
Bitmap !=
NULL) &&
02694 (BitmapRange->
Bitmap != (PULONG)&Mbcb->
BitmapRange2)) {
02695
02696 DoDrain =
TRUE;
02697
02698
02699
02700
02701
02702
if (BitmapRange->
DirtyPages != 0) {
02703 RtlZeroMemory( BitmapRange->
Bitmap,
MBCB_BITMAP_BLOCK_SIZE );
02704 }
02705
CcAcquireVacbLockAtDpcLevel();
02706
CcDeallocateVacbLevel( (
PVACB *)BitmapRange->
Bitmap,
FALSE );
02707
CcReleaseVacbLockFromDpcLevel();
02708 }
02709
02710
02711
02712
02713
02714
if ((BitmapRange < (
PBITMAP_RANGE)Mbcb) &&
02715 (BitmapRange > (
PBITMAP_RANGE)((PCHAR)Mbcb +
sizeof(
MBCB)))) {
02716
02717
ExFreePool( BitmapRange );
02718 }
02719 }
02720
02721
02722
02723
02724
02725 SharedCacheMap->Mbcb =
NULL;
02726
02727 ExReleaseSpinLock( &SharedCacheMap->BcbSpinLock, OldIrql );
02728
02729
02730
02731
02732
02733
CcDeallocateBcb( (
PBCB)Mbcb );
02734
02735 }
else {
02736
02737 ExReleaseSpinLock( &SharedCacheMap->BcbSpinLock, OldIrql );
02738 }
02739
02740
if (DoDrain) {
02741
CcDrainVacbLevelZone();
02742 }
02743 }
02744
02745
02746
VOID
02747 CcSetDirtyPageThreshold (
02748 IN
PFILE_OBJECT FileObject,
02749 IN ULONG DirtyPageThreshold
02750 )
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780 {
02781 KIRQL OldIrql;
02782
PSHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
02783
02784
if (SharedCacheMap !=
NULL) {
02785
02786 SharedCacheMap->
DirtyPageThreshold = DirtyPageThreshold;
02787 }
02788
02789
02790
02791
02792
02793
02794
if (!
FlagOn(((
PFSRTL_COMMON_FCB_HEADER)(FileObject->FsContext))->Flags,
02795
FSRTL_FLAG_LIMIT_MODIFIED_PAGES)) {
02796
02797
SetFlag(((
PFSRTL_COMMON_FCB_HEADER)(FileObject->FsContext))->Flags,
02798
FSRTL_FLAG_LIMIT_MODIFIED_PAGES);
02799 }
02800 }
02801
02802
02803
VOID
02804 CcZeroEndOfLastPage (
02805 IN
PFILE_OBJECT FileObject
02806 )
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825 {
02826
PSHARED_CACHE_MAP SharedCacheMap;
02827 ULONG ActivePage;
02828 ULONG PageIsDirty;
02829 KIRQL OldIrql;
02830 PVOID NeedToZero =
NULL;
02831
PVACB ActiveVacb =
NULL;
02832 IO_STATUS_BLOCK Iosb;
02833 BOOLEAN PurgeResult;
02834
02835
02836
02837
02838
02839
FsRtlAcquireFileExclusive( FileObject );
02840
CcAcquireMasterLock( &OldIrql );
02841 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
02842
02843
if (SharedCacheMap !=
NULL) {
02844
02845
02846
02847
02848
02849
if ((SharedCacheMap->
ActiveVacb !=
NULL) || ((NeedToZero = SharedCacheMap->
NeedToZero) !=
NULL)) {
02850
02851
CcIncrementOpenCount( SharedCacheMap, 'peZS' );
02852
GetActiveVacbAtDpcLevel( SharedCacheMap, ActiveVacb, ActivePage, PageIsDirty );
02853 }
02854 }
02855
02856
CcReleaseMasterLock( OldIrql );
02857
02858
02859
02860
02861
02862
02863
02864
if (
FlagOn( ((
PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->Flags,
02865
FSRTL_FLAG_ADVANCED_HEADER )) {
02866
02867 ExAcquireFastMutex( ((
PFSRTL_ADVANCED_FCB_HEADER)FileObject->FsContext)->FastMutex );
02868
02869
SetFlag( ((
PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->Flags,
02870
FSRTL_FLAG_USER_MAPPED_FILE );
02871
02872 ExReleaseFastMutex( ((
PFSRTL_ADVANCED_FCB_HEADER)FileObject->FsContext)->FastMutex );
02873
02874 }
else {
02875
02876
SetFlag( ((
PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->Flags,
02877
FSRTL_FLAG_USER_MAPPED_FILE );
02878 }
02879
02880
02881
02882
02883
02884
02885
if ((ActiveVacb !=
NULL) || (NeedToZero !=
NULL)) {
02886
CcFreeActiveVacb( SharedCacheMap, ActiveVacb, ActivePage, PageIsDirty );
02887 }
02888
02889
02890
if (
FlagOn( ((
PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->Flags2,
FSRTL_FLAG2_PURGE_WHEN_MAPPED )) {
02891
02892
if (FileObject->SectionObjectPointer->SharedCacheMap) {
02893
ASSERT( ((
PSHARED_CACHE_MAP)(FileObject->SectionObjectPointer->SharedCacheMap))->VacbActiveCount == 0 );
02894 }
02895
02896
CcFlushCache( FileObject->SectionObjectPointer,
NULL, 0, &Iosb );
02897 PurgeResult =
CcPurgeCacheSection( FileObject->SectionObjectPointer,
NULL, 0,
FALSE );
02898
02899
if (FileObject->SectionObjectPointer->SharedCacheMap) {
02900
ASSERT( ((
PSHARED_CACHE_MAP)(FileObject->SectionObjectPointer->SharedCacheMap))->VacbActiveCount == 0 );
02901 }
02902 }
02903
02904
02905
FsRtlReleaseFile( FileObject );
02906
02907
02908
02909
02910
02911
02912
02913
if ((ActiveVacb !=
NULL) || (NeedToZero !=
NULL)) {
02914
02915
02916
02917
02918
02919
CcAcquireMasterLock( &OldIrql );
02920
02921
CcDecrementOpenCount( SharedCacheMap, 'peZF' );
02922
02923
if ((SharedCacheMap->
OpenCount == 0) &&
02924 !
FlagOn(SharedCacheMap->
Flags,
WRITE_QUEUED) &&
02925 (SharedCacheMap->
DirtyPages == 0)) {
02926
02927
02928
02929
02930
02931 RemoveEntryList( &SharedCacheMap->
SharedCacheMapLinks );
02932 InsertTailList( &
CcDirtySharedCacheMapList.
SharedCacheMapLinks,
02933 &SharedCacheMap->
SharedCacheMapLinks );
02934
02935
02936
02937
02938
02939
02940
LazyWriter.
OtherWork =
TRUE;
02941
if (!
LazyWriter.
ScanActive) {
02942
CcScheduleLazyWriteScan();
02943 }
02944 }
02945
02946
CcReleaseMasterLock( OldIrql );
02947 }
02948 }
02949
02950
02951 BOOLEAN
02952 CcZeroData (
02953 IN
PFILE_OBJECT FileObject,
02954 IN PLARGE_INTEGER StartOffset,
02955 IN PLARGE_INTEGER EndOffset,
02956 IN BOOLEAN Wait
02957 )
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028 {
03029
PSHARED_CACHE_MAP SharedCacheMap;
03030 PVOID CacheBuffer;
03031 LARGE_INTEGER FOffset;
03032 LARGE_INTEGER ToGo;
03033 ULONG ZeroBytes, ZeroTransfer;
03034 ULONG SectorMask;
03035 ULONG i;
03036 BOOLEAN WriteThrough;
03037 BOOLEAN AggressiveZero =
FALSE;
03038 ULONG SavedState = 0;
03039 ULONG MaxZerosInCache =
MAX_ZEROS_IN_CACHE;
03040 ULONG NumberOfColors = 1;
03041
03042
PBCB Bcb =
NULL;
03043 PCHAR Zeros =
NULL;
03044
PMDL ZeroMdl =
NULL;
03045 ULONG MaxBytesMappedInMdl = 0;
03046 BOOLEAN Result =
TRUE;
03047
03048 PPFN_NUMBER Page;
03049 ULONG SavedByteCount;
03050 LARGE_INTEGER SizeLeft;
03051
03052
DebugTrace(+1,
me,
"CcZeroData\n", 0 );
03053
03054 WriteThrough = (BOOLEAN)(((FileObject->Flags &
FO_WRITE_THROUGH) != 0) ||
03055 (FileObject->PrivateCacheMap ==
NULL));
03056
03057
03058
03059
03060
03061
03062
if (WriteThrough && !Wait) {
03063
03064
DebugTrace(-1,
me,
"CcZeroData->FALSE (WriteThrough && !Wait)\n", 0 );
03065
03066
return FALSE;
03067 }
03068
03069 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
03070
03071 SectorMask =
IoGetRelatedDeviceObject(FileObject)->
SectorSize - 1;
03072
03073 FOffset = *StartOffset;
03074
03075
03076
03077
03078
03079 ToGo.QuadPart = EndOffset->QuadPart - FOffset.QuadPart;
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
ASSERT( ToGo.QuadPart <= 0x2000 ||
03090 ((ToGo.LowPart & SectorMask) == 0 &&
03091 (FOffset.LowPart & SectorMask) == 0));
03092
03093
03094
03095
03096
03097
03098
03099
03100
if (((ToGo.QuadPart <= 0x2000) ||
03101 (
MmAvailablePages >= ((
MAX_ZEROS_IN_CACHE /
PAGE_SIZE) * 4))) && !WriteThrough) {
03102
03103
try {
03104
03105
while (MaxZerosInCache != 0) {
03106
03107 ULONG ReceivedLength;
03108 LARGE_INTEGER BeyondLastByte;
03109
03110
if ( ToGo.QuadPart > (LONGLONG)MaxZerosInCache ) {
03111
03112
03113
03114
03115
03116
03117
03118
03119
if (!Wait) {
03120
03121
DebugTrace(-1,
me,
"CcZeroData -> FALSE\n", 0 );
03122
03123
try_return( Result =
FALSE );
03124 }
03125 }
03126
else {
03127 MaxZerosInCache = ToGo.LowPart;
03128 }
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
if (!
CcPinFileData( FileObject,
03143 &FOffset,
03144 MaxZerosInCache,
03145
FALSE,
03146
TRUE,
03147 Wait,
03148 &Bcb,
03149 &CacheBuffer,
03150 &BeyondLastByte )) {
03151
03152
DebugTrace(-1,
me,
"CcZeroData -> FALSE\n", 0 );
03153
03154
try_return( Result =
FALSE );
03155 }
03156
03157
03158
03159
03160
03161
03162
03163 ReceivedLength = (ULONG)(BeyondLastByte.QuadPart - FOffset.QuadPart );
03164
03165
03166
03167
03168
03169 ZeroMdl =
IoAllocateMdl( CacheBuffer,
03170 ReceivedLength,
03171
FALSE,
03172
FALSE,
03173
NULL );
03174
03175
if (ZeroMdl ==
NULL) {
03176
03177
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
03178 }
03179
03180
03181
03182
03183
03184
03185
03186
MmDisablePageFaultClustering(&SavedState);
03187
MmProbeAndLockPages( ZeroMdl,
KernelMode,
IoReadAccess );
03188
MmEnablePageFaultClustering(SavedState);
03189 SavedState = 0;
03190
03191
03192
03193
03194
03195
03196 FOffset = BeyondLastByte;
03197
03198
03199
03200
03201
03202
03203
03204
if (MaxZerosInCache <= ReceivedLength) {
03205 MaxZerosInCache = 0;
03206 }
03207
else {
03208 MaxZerosInCache -= ReceivedLength;
03209 }
03210
03211
03212
03213
03214
03215
03216
03217
MmSetAddressRangeModified( CacheBuffer, ReceivedLength );
03218
CcSetDirtyPinnedData( Bcb,
NULL );
03219
03220
03221
03222
03223
03224
CcUnpinFileData( Bcb,
FALSE,
UNPIN );
03225 Bcb =
NULL;
03226
03227
03228
03229
03230
03231
03232
MmUnlockPages( ZeroMdl );
03233
IoFreeMdl( ZeroMdl );
03234 ZeroMdl =
NULL;
03235 }
03236
03237 try_exit: NOTHING;
03238 } finally {
03239
03240
if (SavedState != 0) {
03241
MmEnablePageFaultClustering(SavedState);
03242 }
03243
03244
03245
03246
03247
03248
if (Bcb !=
NULL) {
03249
03250
CcUnpinFileData( Bcb,
FALSE,
UNPIN );
03251 }
03252
03253
03254
03255
03256
03257
03258
03259
if (ZeroMdl !=
NULL) {
03260
03261
IoFreeMdl( ZeroMdl );
03262 }
03263 }
03264
03265
03266
03267
03268
03269
if (!Result) {
03270
return FALSE;
03271 }
03272
03273
03274
03275
03276
03277
if ( FOffset.QuadPart >= EndOffset->QuadPart ) {
03278
return TRUE;
03279 }
03280 }
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
ASSERT( (FOffset.LowPart & SectorMask) == 0 );
03297
03298 FOffset.QuadPart += (LONGLONG)SectorMask;
03299 FOffset.LowPart &= ~SectorMask;
03300 SizeLeft.QuadPart = EndOffset->QuadPart + (LONGLONG)SectorMask;
03301 SizeLeft.LowPart &= ~SectorMask;
03302 SizeLeft.QuadPart -= FOffset.QuadPart;
03303
03304
ASSERT( (FOffset.LowPart & SectorMask) == 0 );
03305
ASSERT( (SizeLeft.LowPart & SectorMask) == 0 );
03306
03307
if (SizeLeft.QuadPart == 0) {
03308
return TRUE;
03309 }
03310
03311
03312
03313
03314
03315
try {
03316
03317
03318
03319
03320
03321
03322 ZeroBytes = NumberOfColors *
PAGE_SIZE;
03323
03324
if (SizeLeft.HighPart == 0 && SizeLeft.LowPart < ZeroBytes) {
03325 ZeroBytes = SizeLeft.LowPart;
03326 }
03327
03328 Zeros = (PCHAR)
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned, ZeroBytes, 'eZcC' );
03329
03330
if (Zeros !=
NULL) {
03331
03332
03333
03334
03335
03336
03337
03338
03339
if (SizeLeft.HighPart == 0 && SizeLeft.LowPart <
MAX_ZERO_TRANSFER) {
03340
03341 ZeroTransfer = SizeLeft.LowPart;
03342
03343 }
else {
03344
03345
03346
03347
03348
03349
if (InterlockedIncrement( &
CcAggressiveZeroCount ) <=
CcAggressiveZeroThreshold) {
03350 AggressiveZero =
TRUE;
03351 ZeroTransfer =
MAX_ZERO_TRANSFER;
03352 }
else {
03353 InterlockedDecrement( &
CcAggressiveZeroCount );
03354 ZeroTransfer =
MIN_ZERO_TRANSFER;
03355 }
03356 }
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
while (
TRUE) {
03370
03371
03372
03373
03374
03375
while (
TRUE) {
03376
03377 ZeroMdl =
IoAllocateMdl( Zeros, ZeroTransfer,
FALSE,
FALSE,
NULL );
03378
03379
03380
03381
03382
03383
03384
03385
if (ZeroMdl || ZeroTransfer == ZeroBytes) {
03386
03387
break;
03388 }
03389
03390 Fall_Back:
03391
03392
03393
03394
03395
03396 ZeroTransfer /= 2;
03397 ZeroTransfer &= ~SectorMask;
03398
if (ZeroTransfer < ZeroBytes) {
03399 ZeroTransfer = ZeroBytes;
03400 }
03401
03402
ASSERT( (ZeroTransfer & SectorMask) == 0 && ZeroTransfer != 0);
03403 }
03404
03405
if (ZeroMdl ==
NULL) {
03406
03407
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
03408 }
03409
03410
03411
03412
03413
03414
03415
if (ZeroTransfer == ZeroBytes) {
03416
03417
MmBuildMdlForNonPagedPool( ZeroMdl );
03418
break;
03419 }
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431 SavedByteCount = ZeroMdl->
ByteCount;
03432 ZeroMdl->
ByteCount = ZeroBytes;
03433
MmBuildMdlForNonPagedPool( ZeroMdl );
03434
03435 ZeroMdl->
MdlFlags &= ~
MDL_SOURCE_IS_NONPAGED_POOL;
03436 ZeroMdl->
MdlFlags |=
MDL_PAGES_LOCKED;
03437 ZeroMdl->
MappedSystemVa =
NULL;
03438 ZeroMdl->
ByteCount = SavedByteCount;
03439 Page =
MmGetMdlPfnArray( ZeroMdl );
03440
for (i = NumberOfColors;
03441 i < (
COMPUTE_PAGES_SPANNED( 0, SavedByteCount ));
03442 i++) {
03443
03444 *(Page + i) = *(Page + i - NumberOfColors);
03445 }
03446
03447
if (
MmGetSystemAddressForMdlSafe( ZeroMdl,
LowPagePriority ) ==
NULL) {
03448
03449
03450
03451
03452
03453
03454
IoFreeMdl( ZeroMdl );
03455
goto Fall_Back;
03456 }
03457
03458
break;
03459 }
03460
03461
03462
03463
03464
03465
03466 }
else {
03467
03468
03469
03470
03471
03472
03473
if (
IoGetRelatedDeviceObject(FileObject)->
SectorSize <
PAGE_SIZE / 2) {
03474
03475 ZeroBytes =
PAGE_SIZE / 2;
03476 Zeros = (PCHAR)
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned, ZeroBytes, 'eZcC' );
03477 }
03478
03479
03480
03481
03482
03483
if (Zeros ==
NULL) {
03484
03485 ZeroBytes =
IoGetRelatedDeviceObject(FileObject)->
SectorSize;
03486 Zeros = (PCHAR)
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned, ZeroBytes, 'eZcC' );
03487
03488
03489
03490
03491
03492
if (Zeros ==
NULL) {
03493
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
03494 }
03495 }
03496
03497
03498
03499
03500
03501
03502
03503
03504 ZeroTransfer = ZeroBytes;
03505 ZeroMdl =
IoAllocateMdl( Zeros, ZeroBytes,
FALSE,
FALSE,
NULL );
03506
03507
ASSERT( (ZeroTransfer & SectorMask) == 0 );
03508
03509
if (ZeroMdl ==
NULL) {
03510
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
03511 }
03512
03513
03514
03515
03516
03517
MmBuildMdlForNonPagedPool( ZeroMdl );
03518
03519
ASSERT( ZeroMdl->
MappedSystemVa == Zeros );
03520 }
03521
03522
#ifdef MIPS
03523
#ifdef MIPS_PREFILL
03524
RtlFillMemory( Zeros, ZeroBytes, 0xDD );
03525
KeSweepDcache(
TRUE );
03526
#endif
03527
#endif
03528
03529
03530
03531
03532
03533 RtlZeroMemory( Zeros, ZeroBytes );
03534
03535
03536
03537
03538
03539
03540
03541
ASSERT(
MmGetSystemAddressForMdl(ZeroMdl) );
03542 MaxBytesMappedInMdl = ZeroMdl->
ByteCount;
03543
03544
03545
03546
03547
03548
03549
ASSERT( ZeroTransfer != 0 &&
03550 (ZeroTransfer & SectorMask) == 0 &&
03551 (SizeLeft.LowPart & SectorMask) == 0 );
03552
03553
while ( SizeLeft.QuadPart != 0 ) {
03554
03555 IO_STATUS_BLOCK IoStatus;
03556
NTSTATUS Status;
03557
KEVENT Event;
03558
03559
03560
03561
03562
03563
03564
if ( (LONGLONG)ZeroTransfer > SizeLeft.QuadPart ) {
03565
03566 ZeroTransfer = SizeLeft.LowPart;
03567 }
03568
03569
03570
03571
03572
03573
KeInitializeEvent( &
Event, NotificationEvent,
FALSE );
03574
03575
03576
03577
03578
03579 ZeroMdl->
ByteCount = ZeroTransfer;
03580
03581
Status =
IoSynchronousPageWrite( FileObject,
03582 ZeroMdl,
03583 &FOffset,
03584 &
Event,
03585 &IoStatus );
03586
03587
03588
03589
03590
03591
03592
if (
Status == STATUS_PENDING) {
03593
KeWaitForSingleObject( &
Event,
03594
Executive,
03595
KernelMode,
03596
FALSE,
03597 (PLARGE_INTEGER)
NULL);
03598 }
03599
03600
03601
03602
03603
03604
03605
03606
03607
if (!
NT_SUCCESS(
Status)) {
03608
ExRaiseStatus(
Status );
03609 }
03610
03611
if (!
NT_SUCCESS(IoStatus.Status)) {
03612
ExRaiseStatus( IoStatus.Status );
03613 }
03614
03615
03616
03617
03618
03619
03620 FOffset.QuadPart = FOffset.QuadPart + (LONGLONG)ZeroTransfer;
03621 SizeLeft.QuadPart = SizeLeft.QuadPart - (LONGLONG)ZeroTransfer;
03622 }
03623 }
03624 finally{
03625
03626
03627
03628
03629
03630
03631
if (ZeroMdl !=
NULL) {
03632
03633
if ((MaxBytesMappedInMdl != 0) &&
03634 !
FlagOn(ZeroMdl->
MdlFlags,
MDL_SOURCE_IS_NONPAGED_POOL)) {
03635 ZeroMdl->
ByteCount = MaxBytesMappedInMdl;
03636
MmUnmapLockedPages (ZeroMdl->
MappedSystemVa, ZeroMdl);
03637 }
03638
03639
IoFreeMdl( ZeroMdl );
03640 }
03641
03642
if (AggressiveZero) {
03643 InterlockedDecrement( &
CcAggressiveZeroCount );
03644 }
03645
03646
if (Zeros !=
NULL) {
03647
ExFreePool( Zeros );
03648 }
03649
03650
DebugTrace(-1,
me,
"CcZeroData -> TRUE\n", 0 );
03651 }
03652
03653
return TRUE;
03654 }
03655
03656
03657
PFILE_OBJECT
03658 CcGetFileObjectFromSectionPtrs (
03659 IN
PSECTION_OBJECT_POINTERS SectionObjectPointer
03660 )
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687 {
03688 KIRQL OldIrql;
03689
PFILE_OBJECT FileObject =
NULL;
03690
03691
03692
03693
03694
03695
CcAcquireMasterLock( &OldIrql );
03696
03697
if (SectionObjectPointer->SharedCacheMap !=
NULL) {
03698
03699 FileObject = ((
PSHARED_CACHE_MAP)SectionObjectPointer->SharedCacheMap)->FileObject;
03700 }
03701
03702
CcReleaseMasterLock( OldIrql );
03703
03704
return FileObject;
03705 }
03706
03707
03708
PFILE_OBJECT
03709 CcGetFileObjectFromBcb (
03710 IN PVOID Bcb
03711 )
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733 {
03734
return ((
PBCB)Bcb)->SharedCacheMap->FileObject;
03735 }