00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#ifndef _CCh_
00023
#define _CCh_
00024
00025
#include <ntos.h>
00026
#include <NtIoLogc.h>
00027
00028
#ifdef MEMPRINT
00029
#include <memprint.h>
00030
#endif
00031
00032
00033
00034
00035
00036
#if defined(_ALPHA_) || defined(_X86_)
00037
00038
#define CcAcquireMasterLock( OldIrql ) \
00039
*( OldIrql ) = KeAcquireQueuedSpinLock( LockQueueMasterLock )
00040
00041
#define CcReleaseMasterLock( OldIrql ) \
00042
KeReleaseQueuedSpinLock( LockQueueMasterLock, OldIrql )
00043
00044
#define CcAcquireMasterLockAtDpcLevel() \
00045
KiAcquireQueuedSpinLock( &KeGetCurrentPrcb()->LockQueue[LockQueueMasterLock] )
00046
00047
#define CcReleaseMasterLockFromDpcLevel() \
00048
KiReleaseQueuedSpinLock( &KeGetCurrentPrcb()->LockQueue[LockQueueMasterLock] )
00049
00050
#define CcAcquireVacbLock( OldIrql ) \
00051
*( OldIrql ) = KeAcquireQueuedSpinLock( LockQueueVacbLock )
00052
00053
#define CcReleaseVacbLock( OldIrql ) \
00054
KeReleaseQueuedSpinLock( LockQueueVacbLock, OldIrql )
00055
00056
#define CcAcquireVacbLockAtDpcLevel() \
00057
KiAcquireQueuedSpinLock( &KeGetCurrentPrcb()->LockQueue[LockQueueVacbLock] )
00058
00059
#define CcReleaseVacbLockFromDpcLevel() \
00060
KiReleaseQueuedSpinLock( &KeGetCurrentPrcb()->LockQueue[LockQueueVacbLock] )
00061
00062
#else
00063
00064 #define CcAcquireMasterLock( OldIrql ) \
00065
ExAcquireSpinLock( &CcMasterSpinLock, OldIrql )
00066
00067 #define CcReleaseMasterLock( OldIrql ) \
00068
ExReleaseSpinLock( &CcMasterSpinLock, OldIrql )
00069
00070 #define CcAcquireMasterLockAtDpcLevel() \
00071
ExAcquireSpinLockAtDpcLevel( &CcMasterSpinLock )
00072
00073 #define CcReleaseMasterLockFromDpcLevel() \
00074
ExReleaseSpinLockFromDpcLevel( &CcMasterSpinLock )
00075
00076 #define CcAcquireVacbLock( OldIrql ) \
00077
ExAcquireSpinLock( &CcVacbSpinLock, OldIrql )
00078
00079 #define CcReleaseVacbLock( OldIrql ) \
00080
ExReleaseSpinLock( &CcVacbSpinLock, OldIrql )
00081
00082 #define CcAcquireVacbLockAtDpcLevel() \
00083
ExAcquireSpinLockAtDpcLevel( &CcVacbSpinLock )
00084
00085 #define CcReleaseVacbLockFromDpcLevel() \
00086
ExReleaseSpinLockFromDpcLevel( &CcVacbSpinLock )
00087
00088
#endif
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
#if DBG
00103
#define LIST_DBG 0
00104
#endif
00105
00106
#include <FsRtl.h>
00107
#ifndef _USERKDX_ // Including stdlib.h build breaks ntos\w32\ntuser\kdexts\kd (!dso)
00108
#include <stdlib.h>
00109
#endif
00110
#include <string.h>
00111
#include <limits.h>
00112
00113
00114
00115
00116
00117
#undef FsRtlAllocatePool
00118
#undef FsRtlAllocatePoolWithQuota
00119
00120 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,' cC')
00121 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,' cC')
00122
00123
#undef ExAllocatePool
00124
#undef ExAllocatePoolWithQuota
00125
00126 #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,' cC')
00127 #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,' cC')
00128
00129
00130
00131
00132
00133
00134 extern PFN_COUNT
MmAvailablePages;
00135
00136
#if DBG
00137
00138
#endif
00139
00140
#ifdef MIPS
00141
#ifdef MIPS_PREFILL
00142
VOID
00143
KeSweepDcache (
00144 IN BOOLEAN AllProcessors
00145 );
00146
#endif
00147
#endif
00148
00149
00150
00151
00152
00153 #define CACHE_NTC_SHARED_CACHE_MAP (0x2FF)
00154 #define CACHE_NTC_PRIVATE_CACHE_MAP (0x2FE)
00155 #define CACHE_NTC_BCB (0x2FD)
00156 #define CACHE_NTC_DEFERRED_WRITE (0x2FC)
00157 #define CACHE_NTC_MBCB (0x2FB)
00158 #define CACHE_NTC_OBCB (0x2FA)
00159 #define CACHE_NTC_MBCB_GRANDE (0x2F9)
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 #define CACHE_BUG_CHECK_CACHEDAT (0x00010000)
00176 #define CACHE_BUG_CHECK_CACHESUB (0x00020000)
00177 #define CACHE_BUG_CHECK_COPYSUP (0x00030000)
00178 #define CACHE_BUG_CHECK_FSSUP (0x00040000)
00179 #define CACHE_BUG_CHECK_LAZYRITE (0x00050000)
00180 #define CACHE_BUG_CHECK_LOGSUP (0x00060000)
00181 #define CACHE_BUG_CHECK_MDLSUP (0x00070000)
00182 #define CACHE_BUG_CHECK_PINSUP (0x00080000)
00183 #define CACHE_BUG_CHECK_VACBSUP (0x00090000)
00184
00185 #define CcBugCheck(A,B,C) { KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | __LINE__, A, B, C ); }
00186
00187
00188
00189
00190
00191
00192 #define DEFAULT_CREATE_MODULO ((ULONG)(0x00100000))
00193 #define DEFAULT_EXTEND_MODULO ((ULONG)(0x00100000))
00194
00195
00196
00197
00198
00199
00200 #define SEQUENTIAL_MAP_LIMIT ((ULONG)(0x00080000))
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 #define MAX_READ_AHEAD (8 * 1024 * 1024)
00218
00219
00220
00221
00222
00223 #define MAX_WRITE_BEHIND (MM_MAXIMUM_DISK_IO_SIZE)
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 #define WRITE_CHARGE_THRESHOLD (64 * PAGE_SIZE)
00281
00282
00283
00284
00285
00286
00287
00288 #define MAX_ZERO_TRANSFER (PAGE_SIZE * 128)
00289 #define MIN_ZERO_TRANSFER (0x10000)
00290 #define MAX_ZEROS_IN_CACHE (0x10000)
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 #define VACB_LEVEL_SHIFT (7)
00308
00309
00310
00311
00312
00313
00314
00315 #define VACB_LEVEL_BLOCK_SIZE ((1 << VACB_LEVEL_SHIFT) * sizeof(PVOID))
00316
00317
00318
00319
00320
00321 #define VACB_LAST_INDEX_FOR_LEVEL ((1 << VACB_LEVEL_SHIFT) - 1)
00322
00323
00324
00325
00326
00327 #define VACB_SIZE_OF_FIRST_LEVEL (1 << (VACB_OFFSET_SHIFT + VACB_LEVEL_SHIFT))
00328
00329
00330
00331
00332
00333
00334 #define VACB_NUMBER_OF_LEVELS (((63 - VACB_OFFSET_SHIFT)/VACB_LEVEL_SHIFT) + 1)
00335
00336
00337
00338
00339
00340 typedef struct _VACB_LEVEL_REFERENCE {
00341
00342 LONG
Reference;
00343 LONG
SpecialReference;
00344
00345 }
VACB_LEVEL_REFERENCE, *
PVACB_LEVEL_REFERENCE;
00346
00347
00348
00349
00350
00351 #define MBCB_BITMAP_BLOCK_SIZE (VACB_LEVEL_BLOCK_SIZE)
00352
00353
00354
00355
00356
00357
00358 #define MBCB_BITMAP_RANGE (MBCB_BITMAP_BLOCK_SIZE * 8 * PAGE_SIZE)
00359
00360
00361
00362
00363
00364 #define MBCB_BITMAP_INITIAL_SIZE (2 * sizeof(BITMAP_RANGE))
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 #define BEGIN_BCB_LIST_ARRAY (0x200000)
00386 #define SIZE_PER_BCB_LIST (VACB_MAPPING_GRANULARITY * 2)
00387 #define BCB_LIST_SHIFT (VACB_OFFSET_SHIFT + 1)
00388
00389 #define GetBcbListHead(SCM,OFF,FAILSUCC) ( \
00390
(((SCM)->SectionSize.QuadPart > BEGIN_BCB_LIST_ARRAY) && \
00391
FlagOn((SCM)->Flags, MODIFIED_WRITE_DISABLED)) ? \
00392
(((SCM)->SectionSize.QuadPart > VACB_SIZE_OF_FIRST_LEVEL) ? \
00393
CcGetBcbListHeadLargeOffset((SCM),(OFF),(FAILSUCC)) : \
00394
(((OFF) >= (SCM)->SectionSize.QuadPart) ? &(SCM)->BcbList : \
00395
((PLIST_ENTRY)((SCM)->Vacbs) + (((SCM)->SectionSize.QuadPart + (OFF)) >> BCB_LIST_SHIFT)))) : \
00396
&(SCM)->BcbList \
00397
)
00398
00399
00400
00401
00402
00403 #define CcLockVacbLevel(SCM,OFF) { \
00404
if (((SCM)->SectionSize.QuadPart > VACB_SIZE_OF_FIRST_LEVEL) && \
00405
FlagOn(SharedCacheMap->Flags, MODIFIED_WRITE_DISABLED)) { \
00406
CcAdjustVacbLevelLockCount((SCM),(OFF), +1);} \
00407
}
00408
00409 #define CcUnlockVacbLevel(SCM,OFF) { \
00410
if (((SCM)->SectionSize.QuadPart > VACB_SIZE_OF_FIRST_LEVEL) && \
00411
FlagOn(SharedCacheMap->Flags, MODIFIED_WRITE_DISABLED)) { \
00412
CcAdjustVacbLevelLockCount((SCM),(OFF), -1);} \
00413
}
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 #define NOISE_BITS (0x7)
00424
00425
00426
00427
00428
00429 #define LAZY_WRITER_IDLE_DELAY ((LONG)(10000000))
00430 #define LAZY_WRITER_COLLISION_DELAY ((LONG)(1000000))
00431
00432
00433
00434
00435
00436 #define LAZY_WRITER_MAX_AGE_TARGET ((ULONG)(8))
00437
00438
00439
00440
00441
00442 #define CC_REQUEUE 35422
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 #define mm (0x100)
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 #define FlagOn(F,SF) ( \
00498
(((F) & (SF))) \
00499
)
00500
00501 #define BooleanFlagOn(F,SF) ( \
00502
(BOOLEAN)(((F) & (SF)) != 0) \
00503
)
00504
00505 #define SetFlag(F,SF) { \
00506
(F) |= (SF); \
00507
}
00508
00509 #define ClearFlag(F,SF) { \
00510
(F) &= ~(SF); \
00511
}
00512
00513 #define QuadAlign(P) ( \
00514
((((P)) + 7) & (-8)) \
00515
)
00516
00517
00518
00519
00520
00521
#if (!DBG && defined( CC_FREE_ASSERTS ))
00522
#undef ASSERT
00523
#undef ASSERTMSG
00524
#define ASSERT(exp) \
00525
((exp) ? TRUE : \
00526
(DbgPrint( "%s:%d %s\n",__FILE__,__LINE__,#exp ), \
00527
DbgBreakPoint(), \
00528
TRUE))
00529
#define ASSERTMSG(msg,exp) \
00530
((exp) ? TRUE : \
00531
(DbgPrint( "%s:%d %s %s\n",__FILE__,__LINE__,msg,#exp ), \
00532
DbgBreakPoint(), \
00533
TRUE))
00534
#endif
00535
00536
00537
#if DANLO
00538
typedef struct _CC_LOG_ENTRY {
00539 ULONG
Action;
00540 ULONG Reason;
00541 } CC_LOG_ENTRY;
00542
00543
typedef struct _CC_LOG {
00544
USHORT Current;
00545
USHORT Size;
00546 CC_LOG_ENTRY Log[48];
00547 } CC_LOG;
00548
00549
#define CcAddToLog( LOG, ACTION, REASON ) { \
00550
(LOG)->Current += 1; \
00551
if ((LOG)->Current == (LOG)->Size) { \
00552
(LOG)->Current = 0; \
00553
} \
00554
(LOG)->Log[(LOG)->Current].Action = (ACTION); \
00555
(LOG)->Log[(LOG)->Current].Reason = (REASON); \
00556
}
00557
#else
00558 #define CcAddToLog( LOG, ACTION, REASON )
00559
#endif
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 #define PREALLOCATED_VACBS (4)
00572
00573
00574
00575
00576
00577 typedef struct _VACB {
00578
00579
00580
00581
00582
00583 PVOID
BaseAddress;
00584
00585
00586
00587
00588
00589 struct _SHARED_CACHE_MAP *
SharedCacheMap;
00590
00591
00592
00593
00594
00595
00596
union {
00597
00598
00599
00600
00601
00602 LARGE_INTEGER FileOffset;
00603
00604
00605
00606
00607
00608
00609
00610
00611 USHORT ActiveCount;
00612
00613 } Overlay;
00614
00615
00616
00617
00618
00619 LIST_ENTRY
LruList;
00620
00621 }
VACB, *
PVACB;
00622
00623
00624
00625
00626
00627
00628 #define VACB_SPECIAL_REFERENCE ((PVACB) ~0)
00629 #define VACB_SPECIAL_DEREFERENCE ((PVACB) ~1)
00630
00631 #define VACB_SPECIAL_FIRST_VALID VACB_SPECIAL_DEREFERENCE
00632
00633
00634
00635
00636
00637
00638
00639 typedef struct _PRIVATE_CACHE_MAP {
00640
00641
00642
00643
00644
00645 CSHORT
NodeTypeCode;
00646 CSHORT
NodeByteSize;
00647
00648
00649
00650
00651
00652 PFILE_OBJECT FileObject;
00653
00654
00655
00656
00657
00658
00659
00660
00661 LARGE_INTEGER
FileOffset1;
00662 LARGE_INTEGER
BeyondLastByte1;
00663
00664 LARGE_INTEGER
FileOffset2;
00665 LARGE_INTEGER
BeyondLastByte2;
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 LARGE_INTEGER
ReadAheadOffset[2];
00677 ULONG
ReadAheadLength[2];
00678
00679
00680
00681
00682
00683 KSPIN_LOCK
ReadAheadSpinLock;
00684
00685
00686
00687
00688
00689 ULONG
ReadAheadMask;
00690
00691
00692
00693
00694
00695
00696 LIST_ENTRY
PrivateLinks;
00697
00698
00699
00700
00701
00702
00703
00704
00705 BOOLEAN
ReadAheadActive;
00706
00707
00708
00709
00710
00711
00712
00713 BOOLEAN
ReadAheadEnabled;
00714
00715 }
PRIVATE_CACHE_MAP;
00716
00717 typedef PRIVATE_CACHE_MAP *
PPRIVATE_CACHE_MAP;
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 typedef struct _SHARED_CACHE_MAP {
00728
00729
00730
00731
00732
00733 CSHORT
NodeTypeCode;
00734 CSHORT
NodeByteSize;
00735
00736
00737
00738
00739
00740 ULONG
OpenCount;
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 LARGE_INTEGER
FileSize;
00753
00754
00755
00756
00757
00758
00759
00760 LIST_ENTRY
BcbList;
00761
00762
00763
00764
00765
00766 LARGE_INTEGER
SectionSize;
00767
00768
00769
00770
00771
00772
00773 LARGE_INTEGER
ValidDataLength;
00774
00775
00776
00777
00778
00779
00780 LARGE_INTEGER
ValidDataGoal;
00781
00782
00783
00784
00785
00786
00787
00788 PVACB InitialVacbs[
PREALLOCATED_VACBS];
00789 PVACB *
Vacbs;
00790
00791
00792
00793
00794
00795
00796 PFILE_OBJECT FileObject;
00797
00798
00799
00800
00801
00802 volatile PVACB ActiveVacb;
00803 ULONG
ActivePage;
00804
00805
00806
00807
00808
00809 volatile PVOID
NeedToZero;
00810 ULONG
NeedToZeroPage;
00811
00812
00813
00814
00815
00816 KSPIN_LOCK
ActiveVacbSpinLock;
00817 ULONG
VacbActiveCount;
00818
00819
00820
00821
00822
00823
00824
00825
00826 LIST_ENTRY
SharedCacheMapLinks;
00827
00828
00829
00830
00831
00832 ULONG
Flags;
00833
00834
00835
00836
00837
00838
00839 struct _MBCB *
Mbcb;
00840
00841
00842
00843
00844
00845
00846 ULONG
DirtyPages;
00847
00848
00849
00850
00851
00852 PVOID
Section;
00853
00854
00855
00856
00857
00858 NTSTATUS Status;
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 PKEVENT CreateEvent;
00872
00873
00874
00875
00876
00877 PKEVENT WaitOnActiveCount;
00878
00879
00880
00881
00882
00883
00884
00885
00886 ULONG
PagesToWrite;
00887 LONGLONG
BeyondLastFlush;
00888
00889
#if 0
00890
00891
00892
00893
00894 LARGE_INTEGER LastViewMiss;
00895
#endif
00896
00897
00898
00899
00900
00901
00902
00903 PCACHE_MANAGER_CALLBACKS Callbacks;
00904
00905 PVOID
LazyWriteContext;
00906
00907
00908
00909
00910
00911 LIST_ENTRY
PrivateList;
00912
00913
00914
00915
00916
00917
00918 PVOID
LogHandle;
00919
00920
00921
00922
00923
00924 PFLUSH_TO_LSN FlushToLsnRoutine;
00925
00926
00927
00928
00929
00930 ULONG
DirtyPageThreshold;
00931
00932
00933
00934
00935
00936
00937
00938
00939 ULONG
LazyWritePassCount;
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 PCACHE_UNINITIALIZE_EVENT UninitializeEvent;
00951
00952
00953
00954
00955
00956
00957 PVACB NeedToZeroVacb;
00958
00959
00960
00961
00962
00963
00964
00965 KSPIN_LOCK
BcbSpinLock;
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 PKEVENT LocalEvent;
00979 KEVENT Event;
00980
00981
00982
00983
00984
00985 PRIVATE_CACHE_MAP PrivateCacheMap;
00986
00987
#if DANLO
00988
00989
00990
00991
00992 CC_LOG OpenCountLog;
00993
#endif
00994
00995 }
SHARED_CACHE_MAP;
00996
00997 typedef SHARED_CACHE_MAP *
PSHARED_CACHE_MAP;
00998
00999
01000
01001
01002
01003 #define CcIncrementOpenCount( SCM, REASON ) { \
01004
(SCM)->OpenCount += 1; \
01005
if (REASON != 0) { \
01006
CcAddToLog( &(SCM)->OpenCountLog, REASON, 1 ); \
01007
} \
01008
}
01009
01010 #define CcDecrementOpenCount( SCM, REASON ) { \
01011
(SCM)->OpenCount -= 1; \
01012
if (REASON != 0) { \
01013
CcAddToLog( &(SCM)->OpenCountLog, REASON, -1 ); \
01014
} \
01015
}
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 #define DISABLE_READ_AHEAD 0x0001
01026
01027
01028
01029
01030
01031 #define DISABLE_WRITE_BEHIND 0x0002
01032
01033
01034
01035
01036
01037
01038 #define PIN_ACCESS 0x0004
01039
01040
01041
01042
01043
01044
01045 #define TRUNCATE_REQUIRED 0x0010
01046
01047
01048
01049
01050
01051 #define WRITE_QUEUED 0x0020
01052
01053
01054
01055
01056
01057
01058
01059 #define ONLY_SEQUENTIAL_ONLY_SEEN 0x0040
01060
01061
01062
01063
01064
01065 #define ACTIVE_PAGE_IS_DIRTY 0x0080
01066
01067
01068
01069
01070
01071 #define BEING_CREATED 0x0100
01072
01073
01074
01075
01076
01077 #define MODIFIED_WRITE_DISABLED 0x0200
01078
01079
01080
01081
01082
01083 #define LAZY_WRITE_OCCURRED 0x0400
01084
01085
01086
01087
01088
01089
01090 #define IS_CURSOR 0x0800
01091
01092
01093
01094
01095
01096
01097
01098 #define RANDOM_ACCESS_SEEN 0x1000
01099
01100
01101
01102
01103
01104
01105
01106
01107 typedef struct _SHARED_CACHE_MAP_LIST_CURSOR {
01108
01109
01110
01111
01112
01113 LIST_ENTRY
SharedCacheMapLinks;
01114
01115
01116
01117
01118
01119 ULONG
Flags;
01120
01121 }
SHARED_CACHE_MAP_LIST_CURSOR, *
PSHARED_CACHE_MAP_LIST_CURSOR;
01122
01123
01124
01125
#ifndef KDEXT
01126
01127
01128
01129
01130
01131 typedef struct _BITMAP_RANGE {
01132
01133
01134
01135
01136
01137 LIST_ENTRY
Links;
01138
01139
01140
01141
01142
01143
01144 LONGLONG
BasePage;
01145
01146
01147
01148
01149
01150 ULONG
FirstDirtyPage;
01151 ULONG
LastDirtyPage;
01152
01153
01154
01155
01156
01157 ULONG
DirtyPages;
01158
01159
01160
01161
01162
01163 PULONG
Bitmap;
01164
01165 }
BITMAP_RANGE, *
PBITMAP_RANGE;
01166
#endif
01167
01168
01169
01170
01171
01172
01173
01174 typedef struct _MBCB {
01175
01176
01177
01178
01179
01180 CSHORT
NodeTypeCode;
01181 CSHORT
NodeIsInZone;
01182
01183
01184
01185
01186
01187
01188 ULONG
PagesToWrite;
01189
01190
01191
01192
01193
01194 ULONG
DirtyPages;
01195
01196
01197
01198
01199
01200 ULONG
Reserved;
01201
01202
01203
01204
01205
01206 LIST_ENTRY
BitmapRanges;
01207
01208
01209
01210
01211
01212
01213 LONGLONG
ResumeWritePage;
01214
01215
01216
01217
01218
01219
01220
01221
01222 BITMAP_RANGE BitmapRange1;
01223 BITMAP_RANGE BitmapRange2;
01224 BITMAP_RANGE BitmapRange3;
01225
01226 }
MBCB;
01227
01228 typedef MBCB *
PMBCB;
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 typedef struct _BCB {
01242
01243
01244
01245
01246
01247 CSHORT
NodeTypeCode;
01248 CSHORT
NodeIsInZone;
01249
01250
01251
01252
01253
01254 ULONG
ByteLength;
01255 LARGE_INTEGER
FileOffset;
01256
01257
01258
01259
01260
01261 LIST_ENTRY
BcbLinks;
01262
01263
01264
01265
01266
01267 LARGE_INTEGER
BeyondLastByte;
01268
01269
01270
01271
01272
01273 LARGE_INTEGER
OldestLsn;
01274
01275
01276
01277
01278
01279
01280 LARGE_INTEGER
NewestLsn;
01281
01282
01283
01284
01285
01286 PVACB Vacb;
01287
01288
01289
01290
01291
01292
#if LIST_DBG
01293
LIST_ENTRY CcBcbLinks;
01294 PVOID CallerAddress;
01295 PVOID CallersCallerAddress;
01296
#endif
01297
01298
01299
01300
01301
01302
01303
01304 ULONG
PinCount;
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315 ERESOURCE Resource;
01316
01317
01318
01319
01320
01321 PSHARED_CACHE_MAP SharedCacheMap;
01322
01323
01324
01325
01326
01327
01328
01329 PVOID
BaseAddress;
01330
01331
01332
01333
01334
01335 BOOLEAN
Dirty;
01336
01337 }
BCB;
01338
01339
#ifndef KDEXT
01340 typedef BCB *
PBCB;
01341
#endif
01342
01343
01344
01345
01346
01347
01348
01349
01350 typedef struct _OBCB {
01351
01352
01353
01354
01355
01356 CSHORT
NodeTypeCode;
01357 CSHORT
NodeByteSize;
01358
01359
01360
01361
01362
01363 ULONG
ByteLength;
01364 LARGE_INTEGER
FileOffset;
01365
01366
01367
01368
01369
01370 PBCB Bcbs[
ANYSIZE_ARRAY];
01371
01372 }
OBCB;
01373
01374 typedef OBCB *
POBCB;
01375
01376
01377
01378
01379
01380
01381 typedef struct _DEFERRED_WRITE {
01382
01383
01384
01385
01386
01387 CSHORT
NodeTypeCode;
01388 CSHORT
NodeByteSize;
01389
01390
01391
01392
01393
01394 PFILE_OBJECT FileObject;
01395
01396
01397
01398
01399
01400 ULONG
BytesToWrite;
01401
01402
01403
01404
01405
01406 LIST_ENTRY
DeferredWriteLinks;
01407
01408
01409
01410
01411
01412
01413
01414 PKEVENT Event;
01415
01416
01417
01418
01419
01420 PCC_POST_DEFERRED_WRITE PostRoutine;
01421 PVOID
Context1;
01422 PVOID
Context2;
01423
01424 BOOLEAN
LimitModifiedPages;
01425
01426 }
DEFERRED_WRITE, *
PDEFERRED_WRITE;
01427
01428
01429
01430
01431
01432
01433 typedef struct _LAZY_WRITER {
01434
01435
01436
01437
01438
01439 PEPROCESS OurProcess;
01440
01441
01442
01443
01444
01445 LIST_ENTRY
WorkQueue;
01446
01447
01448
01449
01450
01451 ZONE_HEADER BcbZone;
01452
01453
01454
01455
01456
01457 KDPC ScanDpc;
01458 KTIMER ScanTimer;
01459
01460
01461
01462
01463
01464 BOOLEAN
ScanActive;
01465
01466
01467
01468
01469
01470
01471 BOOLEAN
OtherWork;
01472
01473 }
LAZY_WRITER;
01474
01475
01476
#ifndef KDEXT
01477
01478
01479
01480
01481
01482 typedef enum _WORKER_FUNCTION {
01483
Noop = 0,
01484
ReadAhead,
01485
WriteBehind,
01486
LazyWriteScan,
01487
EventSet
01488 }
WORKER_FUNCTION;
01489
#endif
01490
01491 typedef struct _WORK_QUEUE_ENTRY {
01492
01493
01494
01495
01496
01497 LIST_ENTRY
WorkQueueLinks;
01498
01499
01500
01501
01502
01503
union {
01504
01505
01506
01507
01508
01509
struct {
01510 PFILE_OBJECT FileObject;
01511 } Read;
01512
01513
01514
01515
01516
01517
struct {
01518 PSHARED_CACHE_MAP SharedCacheMap;
01519 } Write;
01520
01521
01522
01523
01524
01525
struct {
01526 PKEVENT Event;
01527 } Event;
01528
01529 }
Parameters;
01530
01531
01532
01533
01534
01535 UCHAR
Function;
01536
01537 }
WORK_QUEUE_ENTRY, *
PWORK_QUEUE_ENTRY;
01538
01539
01540
01541
01542
01543 typedef struct _MDL_WRITE {
01544
01545
01546
01547
01548
01549 PVOID
ServerContext;
01550
01551
01552
01553
01554
01555 PERESOURCE Resource;
01556
01557
01558
01559
01560
01561
01562 ERESOURCE_THREAD Thread;
01563
01564
01565
01566
01567
01568 LIST_ENTRY
MdlLinks;
01569
01570 }
MDL_WRITE, *
PMDL_WRITE;
01571
01572
01573
01574
01575
01576
01577 #define GetActiveVacb(SCM,IRQ,V,P,D) { \
01578
ExAcquireFastLock(&(SCM)->ActiveVacbSpinLock, &(IRQ)); \
01579
(V) = (SCM)->ActiveVacb; \
01580
if ((V) != NULL) { \
01581
(P) = (SCM)->ActivePage; \
01582
(SCM)->ActiveVacb = NULL; \
01583
(D) = (SCM)->Flags & ACTIVE_PAGE_IS_DIRTY; \
01584
} \
01585
ExReleaseFastLock(&(SCM)->ActiveVacbSpinLock, (IRQ)); \
01586
}
01587
01588 #define GetActiveVacbAtDpcLevel(SCM,V,P,D) { \
01589
ExAcquireSpinLockAtDpcLevel(&(SCM)->ActiveVacbSpinLock); \
01590
(V) = (SCM)->ActiveVacb; \
01591
if ((V) != NULL) { \
01592
(P) = (SCM)->ActivePage; \
01593
(SCM)->ActiveVacb = NULL; \
01594
(D) = (SCM)->Flags & ACTIVE_PAGE_IS_DIRTY; \
01595
} \
01596
ExReleaseSpinLockFromDpcLevel(&(SCM)->ActiveVacbSpinLock); \
01597
}
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
#if !defined(NT_UP) \
01618
01619 #define SetActiveVacb(SCM,IRQ,V,P,D) { \
01620
if (D) { \
01621
CcAcquireMasterLock(&(IRQ)); \
01622
ExAcquireSpinLockAtDpcLevel(&(SCM)->ActiveVacbSpinLock); \
01623
} else { \
01624
ExAcquireSpinLock(&(SCM)->ActiveVacbSpinLock, &(IRQ)); \
01625
} \
01626
do { \
01627
if ((SCM)->ActiveVacb == NULL) { \
01628
if (((SCM)->Flags & ACTIVE_PAGE_IS_DIRTY) != (D)) { \
01629
if (D) { \
01630
(SCM)->ActiveVacb = (V); \
01631
(SCM)->ActivePage = (P); \
01632
(V) = NULL; \
01633
SetFlag((SCM)->Flags, ACTIVE_PAGE_IS_DIRTY); \
01634
CcTotalDirtyPages += 1; \
01635
(SCM)->DirtyPages += 1; \
01636
if ((SCM)->DirtyPages == 1) { \
01637
PLIST_ENTRY Blink; \
01638
PLIST_ENTRY Entry; \
01639
PLIST_ENTRY Flink; \
01640
PLIST_ENTRY Head; \
01641
Entry = &(SCM)->SharedCacheMapLinks; \
01642
Blink = Entry->Blink; \
01643
Flink = Entry->Flink; \
01644
Blink->Flink = Flink; \
01645
Flink->Blink = Blink; \
01646
Head = &CcDirtySharedCacheMapList.SharedCacheMapLinks; \
01647
Blink = Head->Blink; \
01648
Entry->Flink = Head; \
01649
Entry->Blink = Blink; \
01650
Blink->Flink = Entry; \
01651
Head->Blink = Entry; \
01652
if (!LazyWriter.ScanActive) { \
01653
LazyWriter.ScanActive = TRUE; \
01654
ExReleaseSpinLockFromDpcLevel(&(SCM)->ActiveVacbSpinLock); \
01655
CcReleaseMasterLock((IRQ)); \
01656
KeSetTimer( &LazyWriter.ScanTimer, \
01657
CcFirstDelay, \
01658
&LazyWriter.ScanDpc ); \
01659
break; \
01660
} \
01661
} \
01662
} \
01663
} else { \
01664
(SCM)->ActiveVacb = (V); \
01665
(SCM)->ActivePage = (P); \
01666
(V) = NULL; \
01667
} \
01668
} \
01669
if (D) { \
01670
ExReleaseSpinLockFromDpcLevel(&(SCM)->ActiveVacbSpinLock); \
01671
CcReleaseMasterLock((IRQ)); \
01672
} else { \
01673
ExReleaseSpinLock(&(SCM)->ActiveVacbSpinLock, (IRQ)); \
01674
} \
01675
if ((V) != NULL) { \
01676
CcFreeActiveVacb( (SCM), (V), (P), (D)); \
01677
} \
01678
} while (FALSE); \
01679
}
01680
01681
01682
01683
01684
01685
01686
#else
01687
01688
#define SetActiveVacb(SCM,IRQ,V,P,D) { \
01689
ExAcquireFastLock(&(SCM)->ActiveVacbSpinLock, &(IRQ)); \
01690
do { \
01691
if ((SCM)->ActiveVacb == NULL) { \
01692
if (((SCM)->Flags & ACTIVE_PAGE_IS_DIRTY) != (D)) { \
01693
if (D) { \
01694
(SCM)->ActiveVacb = (V); \
01695
(SCM)->ActivePage = (P); \
01696
(V) = NULL; \
01697
SetFlag((SCM)->Flags, ACTIVE_PAGE_IS_DIRTY); \
01698
CcTotalDirtyPages += 1; \
01699
(SCM)->DirtyPages += 1; \
01700
if ((SCM)->DirtyPages == 1) { \
01701
PLIST_ENTRY Blink; \
01702
PLIST_ENTRY Entry; \
01703
PLIST_ENTRY Flink; \
01704
PLIST_ENTRY Head; \
01705
Entry = &(SCM)->SharedCacheMapLinks; \
01706
Blink = Entry->Blink; \
01707
Flink = Entry->Flink; \
01708
Blink->Flink = Flink; \
01709
Flink->Blink = Blink; \
01710
Head = &CcDirtySharedCacheMapList.SharedCacheMapLinks; \
01711
Blink = Head->Blink; \
01712
Entry->Flink = Head; \
01713
Entry->Blink = Blink; \
01714
Blink->Flink = Entry; \
01715
Head->Blink = Entry; \
01716
if (!LazyWriter.ScanActive) { \
01717
LazyWriter.ScanActive = TRUE; \
01718
ExReleaseFastLock(&(SCM)->ActiveVacbSpinLock, (IRQ)); \
01719
KeSetTimer( &LazyWriter.ScanTimer, \
01720
CcFirstDelay, \
01721
&LazyWriter.ScanDpc ); \
01722
break; \
01723
} \
01724
} \
01725
} \
01726
} else { \
01727
(SCM)->ActiveVacb = (V); \
01728
(SCM)->ActivePage = (P); \
01729
(V) = NULL; \
01730
} \
01731
} \
01732
ExReleaseFastLock(&(SCM)->ActiveVacbSpinLock, (IRQ)); \
01733
if ((V) != NULL) { \
01734
CcFreeActiveVacb( (SCM), (V), (P), (D)); \
01735
} \
01736
} while (FALSE); \
01737
}
01738
01739
#endif
01740
01741
VOID
01742
CcPostDeferredWrites (
01743 );
01744
01745 BOOLEAN
01746
CcPinFileData (
01747 IN
PFILE_OBJECT FileObject,
01748 IN PLARGE_INTEGER FileOffset,
01749 IN ULONG Length,
01750 IN BOOLEAN ReadOnly,
01751 IN BOOLEAN WriteOnly,
01752 IN ULONG Flags,
01753 OUT PBCB *Bcb,
01754 OUT PVOID *BaseAddress,
01755 OUT PLARGE_INTEGER BeyondLastByte
01756 );
01757
01758 typedef enum {
01759
UNPIN,
01760
UNREF,
01761
SET_CLEAN
01762 }
UNMAP_ACTIONS;
01763
01764
VOID
01765
FASTCALL
01766
CcUnpinFileData (
01767 IN OUT PBCB Bcb,
01768 IN BOOLEAN ReadOnly,
01769 IN UNMAP_ACTIONS UnmapAction
01770 );
01771
01772
VOID
01773
FASTCALL
01774
CcDeallocateBcb (
01775 IN PBCB Bcb
01776 );
01777
01778
VOID
01779
FASTCALL
01780
CcPerformReadAhead (
01781 IN
PFILE_OBJECT FileObject
01782 );
01783
01784
VOID
01785
CcSetDirtyInMask (
01786 IN PSHARED_CACHE_MAP SharedCacheMap,
01787 IN PLARGE_INTEGER FileOffset,
01788 IN ULONG Length
01789 );
01790
01791
VOID
01792
FASTCALL
01793
CcWriteBehind (
01794 IN PSHARED_CACHE_MAP SharedCacheMap,
01795 IN PIO_STATUS_BLOCK IoStatus
01796 );
01797
01798 #define ZERO_FIRST_PAGE 1
01799 #define ZERO_MIDDLE_PAGES 2
01800 #define ZERO_LAST_PAGE 4
01801
01802 BOOLEAN
01803
CcMapAndRead(
01804 IN PSHARED_CACHE_MAP SharedCacheMap,
01805 IN PLARGE_INTEGER FileOffset,
01806 IN ULONG Length,
01807 IN ULONG ZeroFlags,
01808 IN BOOLEAN Wait,
01809 IN PVOID BaseAddress
01810 );
01811
01812
VOID
01813
CcFreeActiveVacb (
01814 IN PSHARED_CACHE_MAP SharedCacheMap,
01815 IN PVACB ActiveVacb OPTIONAL,
01816 IN ULONG ActivePage,
01817 IN ULONG PageIsDirty
01818 );
01819
01820
VOID
01821
CcMapAndCopy(
01822 IN PSHARED_CACHE_MAP SharedCacheMap,
01823 IN PVOID UserBuffer,
01824 IN PLARGE_INTEGER FileOffset,
01825 IN ULONG Length,
01826 IN ULONG ZeroFlags,
01827 IN BOOLEAN WriteThrough
01828 );
01829
01830
VOID
01831
CcScanDpc (
01832 IN
PKDPC Dpc,
01833 IN PVOID DeferredContext,
01834 IN PVOID SystemArgument1,
01835 IN PVOID SystemArgument2
01836 );
01837
01838
VOID
01839
CcScheduleLazyWriteScan (
01840 );
01841
01842
VOID
01843
CcStartLazyWriter (
01844 IN PVOID NotUsed
01845 );
01846
01847 #define CcAllocateWorkQueueEntry() \
01848
(PWORK_QUEUE_ENTRY)ExAllocateFromPPNPagedLookasideList(LookasideTwilightList)
01849
01850 #define CcFreeWorkQueueEntry(_entry_) \
01851
ExFreeToPPNPagedLookasideList(LookasideTwilightList, (_entry_))
01852
01853
VOID
01854
FASTCALL
01855
CcPostWorkQueue (
01856 IN PWORK_QUEUE_ENTRY WorkQueueEntry,
01857 IN PLIST_ENTRY WorkQueue
01858 );
01859
01860
VOID
01861
CcWorkerThread (
01862 PVOID ExWorkQueueItem
01863 );
01864
01865
VOID
01866
FASTCALL
01867
CcDeleteSharedCacheMap (
01868 IN PSHARED_CACHE_MAP SharedCacheMap,
01869 IN KIRQL ListIrql,
01870 IN ULONG ReleaseFile
01871 );
01872
01873
01874
01875
01876
01877 LONG
01878
CcCopyReadExceptionFilter(
01879 IN PEXCEPTION_POINTERS ExceptionPointer,
01880 IN PNTSTATUS ExceptionCode
01881 );
01882
01883
01884
01885
01886
01887 LONG
01888
CcExceptionFilter (
01889 IN NTSTATUS ExceptionCode
01890 );
01891
01892
#ifdef CCDBG
01893
VOID
01894 CcDump (
01895 IN PVOID Ptr
01896 );
01897
#endif
01898
01899
01900
01901
01902
01903
VOID
01904
CcInitializeVacbs(
01905 );
01906
01907 PVOID
01908
CcGetVirtualAddressIfMapped (
01909 IN PSHARED_CACHE_MAP SharedCacheMap,
01910 IN LONGLONG FileOffset,
01911 OUT PVACB *Vacb,
01912 OUT PULONG ReceivedLength
01913 );
01914
01915 PVOID
01916
CcGetVirtualAddress (
01917 IN PSHARED_CACHE_MAP SharedCacheMap,
01918 IN LARGE_INTEGER FileOffset,
01919 OUT PVACB *Vacb,
01920 OUT PULONG ReceivedLength
01921 );
01922
01923
VOID
01924
FASTCALL
01925
CcFreeVirtualAddress (
01926 IN PVACB Vacb
01927 );
01928
01929
VOID
01930
CcReferenceFileOffset (
01931 IN PSHARED_CACHE_MAP SharedCacheMap,
01932 IN LARGE_INTEGER FileOffset
01933 );
01934
01935
VOID
01936
CcDereferenceFileOffset (
01937 IN PSHARED_CACHE_MAP SharedCacheMap,
01938 IN LARGE_INTEGER FileOffset
01939 );
01940
01941
VOID
01942
CcWaitOnActiveCount (
01943 IN PSHARED_CACHE_MAP SharedCacheMap
01944 );
01945
01946
VOID
01947
FASTCALL
01948
CcCreateVacbArray (
01949 IN PSHARED_CACHE_MAP SharedCacheMap,
01950 IN LARGE_INTEGER NewSectionSize
01951 );
01952
01953
VOID
01954
CcExtendVacbArray (
01955 IN PSHARED_CACHE_MAP SharedCacheMap,
01956 IN LARGE_INTEGER NewSectionSize
01957 );
01958
01959 BOOLEAN
01960
FASTCALL
01961
CcUnmapVacbArray (
01962 IN PSHARED_CACHE_MAP SharedCacheMap,
01963 IN PLARGE_INTEGER FileOffset OPTIONAL,
01964 IN ULONG Length,
01965 IN BOOLEAN UnmapBehind
01966 );
01967
01968
VOID
01969
CcAdjustVacbLevelLockCount (
01970 IN PSHARED_CACHE_MAP SharedCacheMap,
01971 IN LONGLONG FileOffset,
01972 IN LONG Adjustment
01973 );
01974
01975 PLIST_ENTRY
01976
CcGetBcbListHeadLargeOffset (
01977 IN PSHARED_CACHE_MAP SharedCacheMap,
01978 IN LONGLONG FileOffset,
01979 IN BOOLEAN FailToSuccessor
01980 );
01981
01982 ULONG
01983
CcPrefillVacbLevelZone (
01984 IN ULONG NumberNeeded,
01985 OUT PKIRQL OldIrql,
01986 IN ULONG NeedBcbListHeads
01987 );
01988
01989
VOID
01990
CcDrainVacbLevelZone (
01991 );
01992
01993
01994
01995
01996
01997 extern KSPIN_LOCK
CcMasterSpinLock;
01998 extern KSPIN_LOCK
CcBcbSpinLock;
01999 extern LIST_ENTRY
CcCleanSharedCacheMapList;
02000 extern SHARED_CACHE_MAP_LIST_CURSOR CcDirtySharedCacheMapList;
02001 extern SHARED_CACHE_MAP_LIST_CURSOR CcLazyWriterCursor;
02002 extern NPAGED_LOOKASIDE_LIST CcTwilightLookasideList;
02003 extern KSPIN_LOCK
CcWorkQueueSpinlock;
02004 extern ULONG
CcNumberWorkerThreads;
02005 extern ULONG
CcNumberActiveWorkerThreads;
02006 extern LIST_ENTRY
CcIdleWorkerThreadList;
02007 extern LIST_ENTRY
CcExpressWorkQueue;
02008 extern LIST_ENTRY
CcRegularWorkQueue;
02009 extern LIST_ENTRY
CcPostTickWorkQueue;
02010 extern BOOLEAN
CcQueueThrottle;
02011 extern ULONG
CcIdleDelayTick;
02012 extern LARGE_INTEGER
CcNoDelay;
02013 extern LARGE_INTEGER
CcFirstDelay;
02014 extern LARGE_INTEGER
CcIdleDelay;
02015 extern LARGE_INTEGER
CcCollisionDelay;
02016 extern LARGE_INTEGER
CcTargetCleanDelay;
02017 extern LAZY_WRITER LazyWriter;
02018 extern KSPIN_LOCK
CcVacbSpinLock;
02019 extern ULONG
CcNumberVacbs;
02020 extern PVACB CcVacbs;
02021 extern PVACB CcBeyondVacbs;
02022 extern LIST_ENTRY
CcVacbLru;
02023 extern KSPIN_LOCK
CcDeferredWriteSpinLock;
02024 extern LIST_ENTRY
CcDeferredWrites;
02025 extern ULONG
CcDirtyPageThreshold;
02026 extern ULONG
CcDirtyPageTarget;
02027 extern ULONG
CcDirtyPagesLastScan;
02028 extern ULONG
CcPagesYetToWrite;
02029 extern ULONG
CcPagesWrittenLastTime;
02030 extern ULONG
CcAvailablePagesThreshold;
02031 extern ULONG
CcTotalDirtyPages;
02032 extern ULONG
CcTune;
02033 extern LONG
CcAggressiveZeroCount;
02034 extern LONG
CcAggressiveZeroThreshold;
02035 extern ULONG
CcLazyWriteHotSpots;
02036 extern MM_SYSTEMSIZE CcCapturedSystemSize;
02037 extern ULONG
CcMaxVacbLevelsSeen;
02038 extern ULONG
CcVacbLevelEntries;
02039 extern PVACB *
CcVacbLevelFreeList;
02040 extern ULONG
CcVacbLevelWithBcbsEntries;
02041 extern PVACB *
CcVacbLevelWithBcbsFreeList;
02042
02043
02044
02045
02046
02047
02048 _inline
PVACB *
CcAllocateVacbLevel (
02049 IN BOOLEAN AllocatingBcbListHeads
02050 )
02051
02052 {
02053
PVACB *ReturnEntry;
02054
02055
if (AllocatingBcbListHeads) {
02056 ReturnEntry =
CcVacbLevelWithBcbsFreeList;
02057
CcVacbLevelWithBcbsFreeList = (
PVACB *)*ReturnEntry;
02058
CcVacbLevelWithBcbsEntries -= 1;
02059 }
else {
02060 ReturnEntry =
CcVacbLevelFreeList;
02061
CcVacbLevelFreeList = (
PVACB *)*ReturnEntry;
02062
CcVacbLevelEntries -= 1;
02063 }
02064 *ReturnEntry =
NULL;
02065
ASSERT(RtlCompareMemory(ReturnEntry, ReturnEntry + 1,
VACB_LEVEL_BLOCK_SIZE -
sizeof(
PVACB)) ==
02066 (
VACB_LEVEL_BLOCK_SIZE -
sizeof(
PVACB)));
02067
return ReturnEntry;
02068 }
02069
02070 _inline
VOID CcDeallocateVacbLevel (
02071 IN PVACB *Entry,
02072 IN BOOLEAN DeallocatingBcbListHeads
02073 )
02074
02075 {
02076
if (DeallocatingBcbListHeads) {
02077 *Entry = (
PVACB)
CcVacbLevelWithBcbsFreeList;
02078
CcVacbLevelWithBcbsFreeList = Entry;
02079
CcVacbLevelWithBcbsEntries += 1;
02080 }
else {
02081 *Entry = (
PVACB)
CcVacbLevelFreeList;
02082
CcVacbLevelFreeList = Entry;
02083
CcVacbLevelEntries += 1;
02084 }
02085 }
02086
02087
02088
02089
02090
02091
02092 _inline
02093
PVACB_LEVEL_REFERENCE
02094 VacbLevelReference (
02095 IN PSHARED_CACHE_MAP SharedCacheMap,
02096 IN PVACB *VacbArray,
02097 IN ULONG Level
02098 )
02099 {
02100
return (
PVACB_LEVEL_REFERENCE)
02101 ((PCHAR)VacbArray +
02102
VACB_LEVEL_BLOCK_SIZE +
02103 (Level != 0?
02104 0 : (
FlagOn( SharedCacheMap->Flags,
MODIFIED_WRITE_DISABLED )?
02105
VACB_LEVEL_BLOCK_SIZE : 0)));
02106 }
02107
02108 _inline
02109 ULONG
02110 IsVacbLevelReferenced (
02111 IN PSHARED_CACHE_MAP SharedCacheMap,
02112 IN PVACB *VacbArray,
02113 IN ULONG Level
02114 )
02115 {
02116
PVACB_LEVEL_REFERENCE VacbReference =
VacbLevelReference( SharedCacheMap, VacbArray, Level );
02117
02118
return VacbReference->
Reference | VacbReference->
SpecialReference;
02119 }
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154 #define try_return(S) { S; goto try_exit; }
02155
02156
#ifdef CCDBG
02157
02158
extern LONG CcDebugTraceLevel;
02159
extern LONG CcDebugTraceIndent;
02160
02161
#ifndef CCDBG_LOCK
02162
02163
#define DebugTrace(INDENT,LEVEL,X,Y) { \
02164
LONG _i; \
02165
if (((LEVEL) == 0) || (CcDebugTraceLevel & (LEVEL))) { \
02166
_i = (ULONG)PsGetCurrentThread(); \
02167
DbgPrint("%08lx:",_i); \
02168
if ((INDENT) < 0) { \
02169
CcDebugTraceIndent += (INDENT); \
02170
} \
02171
if (CcDebugTraceIndent < 0) { \
02172
CcDebugTraceIndent = 0; \
02173
} \
02174
for (_i=0; _i<CcDebugTraceIndent; _i+=1) { \
02175
DbgPrint(" "); \
02176
} \
02177
DbgPrint(X,Y); \
02178
if ((INDENT) > 0) { \
02179
CcDebugTraceIndent += (INDENT); \
02180
} \
02181
} \
02182
}
02183
02184
#define DebugTrace2(INDENT,LEVEL,X,Y,Z) { \
02185
LONG _i; \
02186
if (((LEVEL) == 0) || (CcDebugTraceLevel & (LEVEL))) { \
02187
_i = (ULONG)PsGetCurrentThread(); \
02188
DbgPrint("%08lx:",_i); \
02189
if ((INDENT) < 0) { \
02190
CcDebugTraceIndent += (INDENT); \
02191
} \
02192
if (CcDebugTraceIndent < 0) { \
02193
CcDebugTraceIndent = 0; \
02194
} \
02195
for (_i=0; _i<CcDebugTraceIndent; _i+=1) { \
02196
DbgPrint(" "); \
02197
} \
02198
DbgPrint(X,Y,Z); \
02199
if ((INDENT) > 0) { \
02200
CcDebugTraceIndent += (INDENT); \
02201
} \
02202
} \
02203
}
02204
02205
#define DebugDump(STR,LEVEL,PTR) { \
02206
LONG _i; \
02207
VOID CcDump(); \
02208
if (((LEVEL) == 0) || (CcDebugTraceLevel & (LEVEL))) { \
02209
_i = (ULONG)PsGetCurrentThread(); \
02210
DbgPrint("%08lx:",_i); \
02211
DbgPrint(STR); \
02212
if (PTR != NULL) {CcDump(PTR);} \
02213
DbgBreakPoint(); \
02214
} \
02215
}
02216
02217
#else // ndef CCDBG_LOCK
02218
02219
extern KSPIN_LOCK
CcDebugTraceLock;
02220
02221
#define DebugTrace(INDENT,LEVEL,X,Y) { \
02222
LONG _i; \
02223
KIRQL _oldIrql; \
02224
if (((LEVEL) == 0) || (CcDebugTraceLevel & (LEVEL))) { \
02225
_i = (ULONG)PsGetCurrentThread(); \
02226
ExAcquireSpinLock( &CcDebugTraceLock, &_oldIrql ); \
02227
DbgPrint("%08lx:",_i); \
02228
if ((INDENT) < 0) { \
02229
CcDebugTraceIndent += (INDENT); \
02230
} \
02231
if (CcDebugTraceIndent < 0) { \
02232
CcDebugTraceIndent = 0; \
02233
} \
02234
for (_i=0; _i<CcDebugTraceIndent; _i+=1) { \
02235
DbgPrint(" "); \
02236
} \
02237
DbgPrint(X,Y); \
02238
if ((INDENT) > 0) { \
02239
CcDebugTraceIndent += (INDENT); \
02240
} \
02241
ExReleaseSpinLock( &CcDebugTraceLock, _oldIrql ); \
02242
} \
02243
}
02244
02245
#define DebugTrace2(INDENT,LEVEL,X,Y,Z) { \
02246
LONG _i; \
02247
KIRQL _oldIrql; \
02248
if (((LEVEL) == 0) || (CcDebugTraceLevel & (LEVEL))) { \
02249
_i = (ULONG)PsGetCurrentThread(); \
02250
ExAcquireSpinLock( &CcDebugTraceLock, &_oldIrql ); \
02251
DbgPrint("%08lx:",_i); \
02252
if ((INDENT) < 0) { \
02253
CcDebugTraceIndent += (INDENT); \
02254
} \
02255
if (CcDebugTraceIndent < 0) { \
02256
CcDebugTraceIndent = 0; \
02257
} \
02258
for (_i=0; _i<CcDebugTraceIndent; _i+=1) { \
02259
DbgPrint(" "); \
02260
} \
02261
DbgPrint(X,Y,Z); \
02262
if ((INDENT) > 0) { \
02263
CcDebugTraceIndent += (INDENT); \
02264
} \
02265
ExReleaseSpinLock( &CcDebugTraceLock, _oldIrql ); \
02266
} \
02267
}
02268
02269
#define DebugDump(STR,LEVEL,PTR) { \
02270
LONG _i; \
02271
KIRQL _oldIrql; \
02272
VOID CcDump(); \
02273
if (((LEVEL) == 0) || (CcDebugTraceLevel & (LEVEL))) { \
02274
_i = (ULONG)PsGetCurrentThread(); \
02275
ExAcquireSpinLock( &CcDebugTraceLock, &_oldIrql ); \
02276
DbgPrint("%08lx:",_i); \
02277
DbgPrint(STR); \
02278
if (PTR != NULL) {CcDump(PTR);} \
02279
DbgBreakPoint(); \
02280
ExReleaseSpinLock( &CcDebugTraceLock, _oldIrql ); \
02281
} \
02282
}
02283
02284
#endif // else ndef CCDBG_LOCK
02285
02286
#else
02287
02288
#undef CCDBG_LOCK
02289
02290 #define DebugTrace(INDENT,LEVEL,X,Y) {NOTHING;}
02291
02292 #define DebugTrace2(INDENT,LEVEL,X,Y,Z) {NOTHING;}
02293
02294 #define DebugDump(STR,LEVEL,PTR) {NOTHING;}
02295
02296
#endif // CCDBG
02297
02298
02299
02300
02301
02302
#if DBG
02303
02304
extern ULONG CcBcbCount;
02305
extern LIST_ENTRY CcBcbList;
02306
02307
#endif
02308
02309
#endif // _CCh_