4 # Checks assumptions on Cc* (Cache Manager) behaviour by reading TraceFS log
5 # Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; exactly version 2 of June 1991 is required
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 use Carp qw(cluck confess);
28 $Data::Dumper::Sortkeys=1;
29 my $ntfs_blocksize=0x200;
31 # $Object->{"by"}="CcSomeFunction";
32 # $Object->{"line_enter"}=123;
33 # $Object->{"line_leave"}=124;
34 # $Object->{"ProcessThread"}="0x12345678/0x12345678";
35 # $Object->{"data"}[dataline]{"FileObject"}="0x12345678";
36 # $Object->{"data"}[dataline]{"FileName"}="\filename" or undef() if NULL;
37 # $Object->{"data"}[dataline]{"Flags"}="0x40100";
38 # $Object->{"data"}[dataline]{"SectionObjectPointer"}="0x12345678";
39 # $Object->{"data"}[dataline]{"SharedCacheMap"}="0x12345678";
40 # $FileObject{$FileObject}{"FileObject"}="0x12345678";
41 # $FileObject{$FileObject}{"SectionObjectPointer"}="0x12345678";
42 # $SectionObjectPointer{$SectionObjectPointer}{"SectionObjectPointer"}="0x12345678";
43 # $SectionObjectPointer{$SectionObjectPointer}{"SharedCacheMap"}="0x12345678";
44 # $SharedCacheMap{$SharedCacheMap}{"SharedCacheMap"}="0x12345678";
45 # $SharedCacheMap{$SharedCacheMap}{"SectionObjectPointer"}="0x12345678";
46 # $SharedCacheMap{$SharedCacheMap}{"Allocation"}="0x12345";
47 # $SharedCacheMap{$SharedCacheMap}{"FileSize"}="0x12345";
48 # $SharedCacheMap{$SharedCacheMap}{"ref_count"}=1;
49 # $SharedCacheMap{$SharedCacheMap}{"map"}="0x12345678" (Bcb);
50 # $SharedCacheMap{$SharedCacheMap}{"pin"}{"0x1000"}="0x12345678" (Bcb) if !Bcb->{"OwnerPointer"};
51 # $SharedCacheMap{$SharedCacheMap}{"PinAccess"}=0 or 1;
52 # $SharedCacheMap{$SharedCacheMap}{"LogHandle"}="0x12345678" optional;
53 # $SharedCacheMap{$SharedCacheMap}{"AcquireForLazyWrite"}=0; # count
54 # $LogHandle{$LogHandle}{"LogHandle"}="0x12345678";
55 # $Bcb{$Bcb}{"Bcb"}="0x12345678";
56 # $Bcb{$Bcb}{"SharedCacheMap"}="0x12345678";
57 # $Bcb{$Bcb}{"type"}="pin" or "map";
58 # $Bcb{$Bcb}{"ref_count"}=1;
59 # $Bcb{$Bcb}{"FileOffset"}="0x1000" if {"type"} eq "pin";
60 # $Bcb{$Bcb}{"Buffer"}="0x12345678"; # PAGE_SIZE-aligned for "pin", FileOffset_0-aligned for "map"
61 # $Bcb{$Bcb}{"OwnerPointer"}="0x12345678" optional;
62 # $Bcb{$Bcb}{"Lsn"}="0x12345678" optional;
63 # $Bcb{$Bcb}{"dirty"}=1 optional;
64 # $MdlChain{$MdlChain}{"MdlChain"}="0x12345678";
65 # $MdlChain{$MdlChain}{"FileObject"}="0x12345678";
66 # $MdlChain{$MdlChain}{"FileOffset"}="0x5000";
67 # $MdlChain{$MdlChain}{"Length"}="0x9000";
71 my %SectionObjectPointer;
75 my %LastLeave; # $ProcessThread=>[$Object,$Object,...]
76 my $LastLeave; # ref copy of the last item for the current $ProcessThread
79 my $EnterLeave; # ref copy of the list for the current $ProcessThread
82 print Data::Dumper->Dump([\%FileObject,\%SectionObjectPointer,\%SharedCacheMap,\%Bcb],
83 [qw(%FileObject %SectionObjectPointer %SharedCacheMap %Bcb)]) if !$filter;
92 return sprintf("0x%X",$num);
99 my $FObject=$FileObject{$FileObject};
101 my($package,$filename,$line,$subroutine)=caller 0;
102 warn "Non-existent FileObject $FileObject by line $line";
107 sub delete_FObject($)
111 my $FileObject=$FObject->{"FileObject"};
112 delete $FileObject{$FileObject};
117 my($SectionObjectPointer)=@_;
119 my $SObject=$SectionObjectPointer{$SectionObjectPointer};
121 my($package,$filename,$line,$subroutine)=caller 0;
122 warn "Non-existent SectionObjectPointer $SectionObjectPointer by line $line"
127 sub SObject_from_FileObject($)
131 return if !(my $FObject=FObject $FileObject);
132 my $SObject=SObject $FObject->{"SectionObjectPointer"};
134 my($package,$filename,$line,$subroutine)=caller 0;
135 warn "by line $line";
140 sub delete_CObject($)
144 my $SharedCacheMap=$CObject->{"SharedCacheMap"};
145 do { warn "Trailing map $_ of SharedCacheMap $SharedCacheMap during its deletion" if $_; } for ($CObject->{"map"});
146 do { warn "Trailing pin $_ of SharedCacheMap $SharedCacheMap during its deletion" if $_; } for (values(%{$CObject->{"pin"}}));
147 if (my $LogHandle=$CObject->{"LogHandle"}) {
148 do { warn "INTERNAL: Missing LogHandle $LogHandle for SharedCacheMap $SharedCacheMap"; return; }
149 if !(my $LObject=$LogHandle{$LogHandle});
150 # Do not delete $LogHandle as it may be used by many SharedCacheMap-s
152 delete $SharedCacheMap{$SharedCacheMap};
157 my($SharedCacheMap)=@_;
159 my $CObject=$SharedCacheMap{$SharedCacheMap};
161 my($package,$filename,$line,$subroutine)=caller 0;
162 warn "Non-existent SharedCacheMap $SharedCacheMap by line $line";
167 sub CObject_from_FileObject($)
171 return if !(my $SObject=SObject_from_FileObject $FileObject);
172 return if !(my $CObject=CObject $SObject->{"SharedCacheMap"});
176 sub SharedCacheMap_valid($)
178 my($SharedCacheMap)=@_;
180 cluck if !defined $SharedCacheMap;
181 return 0 if "0x".("F"x8) eq $SharedCacheMap;
182 return 0 if !eval $SharedCacheMap;
190 if (!eval $data->{"SectionObjectPointer"}) {
191 return if $Object->{"by"} eq "IRP_MJ_CREATE"; # SectionObjectPointer is not yet initialized
192 warn "Existing FileObject ".$data->{"FileObject"}." but no SectionObjectPointer found"
193 if $FileObject{$data->{"FileObject"}} && eval($FileObject{$data->{"FileObject"}}{"SectionObjectPointer"});
196 my $SectionObjectPointer=$data->{"SectionObjectPointer"};
197 if (!SharedCacheMap_valid $data->{"SharedCacheMap"} && $SectionObjectPointer{$SectionObjectPointer}) {
198 return if !(my $SObject=SObject $SectionObjectPointer);
199 my $SharedCacheMap=$SObject->{"SharedCacheMap"};
200 return if !eval $SharedCacheMap;
201 my $CObject=CObject $SharedCacheMap;
202 warn "Existing SectionObjectPointer ".$data->{"SectionObjectPointer"}." but no SharedCacheMap found,"
203 ." ref_count of SharedCacheMap is ".$CObject->{"ref_count"}
204 if $CObject->{"ref_count"};
205 # if $SectionObjectPointer{$data->{"SectionObjectPointer"}};
206 # SharedCacheMap was droppped by async task as it had ref_count==0.
207 delete_CObject $CObject;
208 $SObject->{"SharedCacheMap"}=tohex(0);
209 # FileObject is still valid!
212 return if !$FileObject{$data->{"FileObject"}};
213 return if !(my $FObject=FObject $data->{"FileObject"});
214 return if !(my $SObject=SObject $FObject->{"SectionObjectPointer"});
215 my $SharedCacheMap=$SObject->{"SharedCacheMap"};
216 warn "FileObject ".$FObject->{"FileObject"}." SectionObjectPointer ".$SObject->{"SectionObjectPointer"}
217 ." expected SharedCacheMap $SharedCacheMap"
218 ." but found SharedCacheMap ".$data->{"SharedCacheMap"}
219 if $SharedCacheMap ne $data->{"SharedCacheMap"};
220 warn "INTERNAL: SharedCacheMap $SharedCacheMap of FileObject ".$FObject->{"FileObject"}." got destroyed"
221 if !$SharedCacheMap{$SharedCacheMap};
224 sub CcInitializeCacheMap($$$$$)
226 my($FileObject,$AllocationSize,$FileSize,$ValidDataLength,$PinAccess)=@_;
228 $ValidDataLength=$FileSize if $ValidDataLength==eval("0x".("F"x8));
229 $Object->{"ref_count"}=1;
230 $Object->{"AllocationSize"}=tohex($AllocationSize);
231 $Object->{"FileSize"}=tohex($FileSize);
232 $Object->{"ValidDataLength"}=tohex($ValidDataLength);
233 $Object->{"map"}=undef();
235 $Object->{"PinAccess"}=$PinAccess;
236 $Object->{"FileObject"}=$FileObject;
239 sub CcInitializeCacheMap_leave()
241 my $SharedCacheMap=$Object->{"data"}[1]{"SharedCacheMap"};
242 $Object->{"SharedCacheMap"}=$SharedCacheMap;
243 my $old=$SharedCacheMap{$SharedCacheMap};
244 if (!SharedCacheMap_valid $Object->{"data"}[0]{"SharedCacheMap"} && $old) {
245 # SharedCacheMap got deleted in the meantime
246 delete_CObject CObject $SharedCacheMap;
247 my $SObject=SObject $Object->{"data"}[0]{"SectionObjectPointer"};
248 $SObject->{"SharedCacheMap"}=tohex(0);
251 if (!$old != !SharedCacheMap_valid $Object->{"data"}[0]{"SharedCacheMap"}) {
252 warn "Expecting old SharedCacheMap validity ".(!!$old)
253 ." but found old SharedCacheMap ".$Object->{"data"}[0]{"SharedCacheMap"};
255 warn "New SharedCacheMap ".$Object->{"data"}[1]{"SharedCacheMap"}." is not valid"
256 if !SharedCacheMap_valid $Object->{"data"}[1]{"SharedCacheMap"};
257 if (SharedCacheMap_valid $Object->{"data"}[0]{"SharedCacheMap"}) {
258 warn "Existing SharedCacheMap changed"
259 ." from ".$Object->{"data"}[0]{"SharedCacheMap"}." to ".$Object->{"data"}[1]{"SharedCacheMap"}
260 if $Object->{"data"}[0]{"SharedCacheMap"} ne $Object->{"data"}[1]{"SharedCacheMap"};
263 for my $field (qw(AllocationSize FileSize PinAccess)) {
264 warn "SharedCacheMap $SharedCacheMap old instance $field ".$old->{$field}
265 ." != new instance $field ".$Object->{$field}
266 if $old->{$field} ne $Object->{$field};
268 do { warn "Existing map Bcb $_ during CcInitializeCacheMap()" if $_; } for ($old->{"map"});
269 do { warn "Existing pin Bcb $_ during CcInitializeCacheMap()" if $_; } for (values(%{$old->{"pin"}}));
270 $Object->{"ref_count"}+=$old->{"ref_count"};
272 $SharedCacheMap{$SharedCacheMap}=$Object;
274 warn "Changed SectionObjectPointer inside CcInitializeCacheMap()"
275 ." from ".$Object->{"data"}[0]{"SectionObjectPointer"}." to ".$Object->{"data"}[1]{"SectionObjectPointer"}
276 if $Object->{"data"}[0]{"SectionObjectPointer"} ne $Object->{"data"}[1]{"SectionObjectPointer"};
277 my $SectionObjectPointer=$Object->{"data"}[1]{"SectionObjectPointer"};
279 my $FileObject=$Object->{"FileObject"};
280 if (my $FObject=$FileObject{$FileObject}) {
281 if (my $SObject=$SectionObjectPointer{$FObject->{"SectionObjectPointer"}}) {
282 warn "Changed SectionObjectPointer of FileObject $FileObject"
283 ." from ".$FObject->{"SectionObjectPointer"}." to ".$SectionObjectPointer
284 if $FObject->{"SectionObjectPointer"} ne $SectionObjectPointer;
286 # Otherwise SectionObjectPointer could be deleted and rebuilt async in the meantime.
288 $FileObject{$FileObject}={
289 "FileObject"=>$FileObject,
290 "SectionObjectPointer"=>$SectionObjectPointer,
293 if (my $SObject=$SectionObjectPointer{$SectionObjectPointer}) {
294 warn "Changed SharedCacheMap of SectionObjectPointer $SectionObjectPointer"
295 ." from ".$SObject->{"SharedCacheMap"}." to ".$SharedCacheMap
296 if $SObject->{"SharedCacheMap"} ne $SharedCacheMap && eval($SObject->{"SharedCacheMap"});
298 $SectionObjectPointer{$SectionObjectPointer}={
299 "SectionObjectPointer"=>$SectionObjectPointer,
300 "SharedCacheMap"=>$SharedCacheMap,
303 CcSetFileSizes($FileObject,map({ eval($Object->{$_}); } qw(AllocationSize FileSize ValidDataLength)));
304 delete $Object->{$_} for (qw(FileObject ValidDataLength));
307 sub CcUninitializeCacheMap($$)
309 my($FileObject,$TruncateSize)=@_;
311 $Object->{"FileObject"}=$FileObject;
314 sub CcUninitializeCacheMap_leave($)
318 my $FileObject=$Object->{"FileObject"};
319 # 'r' means function success.
320 # r=0 either if no CcInitializeCacheMap() was called at all
321 # or if Cc was unable to detach SharedCacheMap and it remains valid
322 # (FIXME: Do we SharedCacheMap->ref_count-- on in such case?).
323 my $SectionObjectPointer=$FileObject{$FileObject}->{"SectionObjectPointer"} if $FileObject{$FileObject};
324 my $SharedCacheMap=$SectionObjectPointer{$SectionObjectPointer}->{"SharedCacheMap"}
325 if $SectionObjectPointer && $SectionObjectPointer{$SectionObjectPointer};
326 warn "Unexpected 'r' result $r for CcUninitializeCacheMap of FileObject $FileObject"
327 if !(eval($SharedCacheMap) && !SharedCacheMap_valid($Object->{"data"}[1]{"SharedCacheMap"})) != !$r;
328 if (!eval $SharedCacheMap) {
329 for my $SharedCacheMap ($Object->{"data"}[0]{"SharedCacheMap"},$Object->{"data"}[1]{"SharedCacheMap"}) {
330 warn "Not expecting valid SharedCacheMap $SharedCacheMap"
331 if SharedCacheMap_valid $SharedCacheMap;
335 for my $SharedCacheMap ($Object->{"data"}[0]{"SharedCacheMap"}) {
336 warn "Expecting valid SharedCacheMap $SharedCacheMap"
337 if !SharedCacheMap_valid $SharedCacheMap;
339 return if !(my $FObject=FObject $FileObject);
340 return if !(my $SObject=SObject $FObject->{"SectionObjectPointer"});
341 return if !(my $CObject=CObject $SObject->{"SharedCacheMap"});
342 if (--$CObject->{"ref_count"}) {
343 for my $SharedCacheMap ($Object->{"data"}[1]{"SharedCacheMap"}) {
344 warn "Expecting still valid SharedCacheMap $SharedCacheMap after CcUninitializeCacheMap()"
345 ." with ref_count=".$CObject->{"ref_count"}
346 if !SharedCacheMap_valid $SharedCacheMap;
350 if (!SharedCacheMap_valid $Object->{"data"}[1]{"SharedCacheMap"}) {
351 delete_CObject $CObject;
352 $SObject->{"SharedCacheMap"}=tohex(0);
353 # FileObject is still valid!
356 # FIXME: Do we SharedCacheMap->ref_count-- on in such case?
360 sub CcSetFileSizes($$$$)
362 my($FileObject,$AllocationSize,$FileSize,$ValidDataLength)=@_;
364 return if !(my $CObject=CObject_from_FileObject $FileObject);
365 my $SharedCacheMap=$CObject->{"SharedCacheMap"};
366 if ($AllocationSize!=eval($CObject->{"AllocationSize"})) {
367 do { warn "Existing map $_ of FileObject $FileObject SharedCacheMap $SharedCacheMap during CcSetAllocationSizes(),"
368 ." AllocationSize=".$CObject->{"AllocationSize"} if $_; }
369 for ($CObject->{"map"});
370 do { warn "Existing pin $_ of FileObject $FileObject SharedCacheMap $SharedCacheMap during CcSetAllocationSizes(),"
371 ." AllocationSize=".$CObject->{"AllocationSize"} if $_; }
372 for (values(%{$CObject->{"pin"}}));
374 # $ValidDataLength can be > $CObject->{"FileSize"};
375 warn "ValidDataLength ".tohex($ValidDataLength)." > FileSize ".tohex($FileSize)
376 if $ValidDataLength>$FileSize;
377 warn "0 != AllocationSize ".tohex($AllocationSize)." % ntfs_blocksize ".tohex($ntfs_blocksize)
378 if 0!=($AllocationSize%$ntfs_blocksize);
379 # $AllocationSize can be higher
380 warn "FileSize ".tohex($FileSize)." > AllocationSize ".tohex($AllocationSize)
381 if $FileSize>$AllocationSize;
382 $CObject->{"FileSize"}=tohex($FileSize);
383 $CObject->{"AllocationSize"}=tohex($AllocationSize);
386 sub IRP_MJ_CREATE_leave()
388 do { warn "Non-NULL SectionObjectPointer $_ not expected" if eval($_); } for ($Object->{"data"}[0]{"SectionObjectPointer"});
389 my $FileObject=$Object->{"data"}[0]{"FileObject"};
390 warn "Existing FileObject $FileObject not expected" if $FileObject{$FileObject};
391 my $SectionObjectPointer=$Object->{"data"}[1]{"SectionObjectPointer"};
392 # We want to track even FileObject without SectionObjectPointer yet.
393 # if ($SectionObjectPointer && $SectionObjectPointer{$SectionObjectPointer})
395 $FileObject{$FileObject}={
396 "FileObject"=>$FileObject,
397 "SectionObjectPointer"=>$SectionObjectPointer,
400 if (eval $SectionObjectPointer) {
401 my $SharedCacheMap=$Object->{"data"}[1]{"SharedCacheMap"};
402 if (my $SObject=$SectionObjectPointer{$SectionObjectPointer}) {
403 warn "Changed SharedCacheMap from stored ".$SObject->{"SharedCacheMap"}." to ".$SharedCacheMap
404 if $SObject->{"SharedCacheMap"} ne $SharedCacheMap && $Object->{"by"} ne "IRP_MJ_CREATE";
406 $SectionObjectPointer{$SectionObjectPointer}={
407 "SectionObjectPointer"=>$SectionObjectPointer,
408 "SharedCacheMap"=>$SharedCacheMap,
417 cluck if !defined $Bcb;
418 my $BObject=$Bcb{$Bcb};
419 warn "Non-existent Bcb $Bcb" if !$BObject;
423 sub delete_BObject($)
427 my $Bcb=$BObject->{"Bcb"};
428 warn "Deleting ref_count=".$BObject->{"ref_count"}." Bcb $Bcb" if $BObject->{"ref_count"};
429 # Do not: warn "Deleting dirty Bcb $Bcb" if $BObject->{"dirty"};
430 # as it is valid to allow sanity check below.
431 warn "Deleting dirty Bcb $Bcb" if $BObject->{"dirty"} && $BObject->{"ref_count"};
432 return if !(my $CObject=CObject $BObject->{"SharedCacheMap"});
433 if ($BObject->{"type"} eq "map") {
434 for my $pin (values(%{$CObject->{"pin"}})) {
435 next if !defined $pin;
436 warn "unpin map but CcPinMappedData pin $pin still exists"
437 if $Bcb{$pin}->{"by"} eq "CcPinMappedData";
440 for my $ref ($BObject->{"type"} eq "map" ? \$CObject->{"map"} : \$CObject->{"pin"}{$BObject->{"FileOffset"}}) {
441 warn "Final unpin but ".$BObject->{"type"}." Bcb $Bcb not registered"
442 ." in SharedCacheMap ".$CObject->{"SharedCacheMap"}." ref ".($$ref || "<undef>")
443 if !defined($BObject->{"OwnerPointer"}) && !($$ref && $$ref eq $Bcb)
444 && !($BObject->{"ref_count"}==0 && $BObject->{"dirty"});
445 if ($$ref && $$ref eq $Bcb) {
447 # Do not: delete $CObject->{"pin"}{$BObject->{"FileOffset"}} if $BObject->{"type"} eq "pin";
448 # as it would destroy $$ref slot in &Bcb_checkref '($$ref && $Bcb ne $$ref)' codepath.
458 cluck if !defined $MdlChain;
459 my $MObject=$MdlChain{$MdlChain};
460 warn "Non-existent MdlChain $MdlChain" if !$MObject;
464 sub Bcb_conflict($;@)
466 my($CObject,@Bcb_list)=@_;
470 "map"=>$CObject->{"map"},
471 map(("arg".($arg++)=>$_),@Bcb_list),
472 %{$CObject->{"pin"}},
475 my $BufferBase; # relativized to FileOffset 0
477 while (my($key,$val)=each(%check)) {
478 next if !defined $val;
479 warn "Conflicting Bcb $val of keys $key and ".$reversed{$val}." of SharedCacheMap ".$CObject->{"SharedCacheMap"}
481 # Buffer base should match even between 'map's and 'pin's
482 # as the data are always mapped only once.
483 if (my $BObject=BObject $val) {
484 my $Buffer=eval $BObject->{"Buffer"};
485 $Buffer-=eval($BObject->{"FileOffset"}) if exists $BObject->{"FileOffset"};
486 warn "Non-matching Bcb ".$BObject->{"type"}." $val Buffer base ".tohex($Buffer)
487 ." with Bcb ".$Bcb{$BufferBase_val}->{"type"}." $BufferBase_val BufferBase ".tohex($BufferBase)
488 if defined($BufferBase) && $Buffer!=$BufferBase;
490 $BufferBase_val=$val;
492 $reversed{$val}=$key;
496 # New $BObject will always be forced as the last stored reference.
499 my($BObject,$ref)=@_;
501 return if !(my $CObject=CObject $BObject->{"SharedCacheMap"});
502 my $type=$BObject->{"type"};
503 my $Bcb=$BObject->{"Bcb"};
504 if ($$ref && $Bcb ne $$ref) {
505 my $BObject2=$Bcb{$$ref};
506 warn "new $type Bcb $Bcb != old ".$BObject2->{"type"}." Bcb $$ref";
507 delete_BObject $BObject2;
508 warn "INTERNAL: Trailing ref to Bcb $$ref" if $$ref;
511 my $BObject2=$Bcb{$$ref};
512 warn "new $type $Bcb type ".$BObject->{"type"}." != old type $type $$ref type ".$BObject2->{"type"}
513 if $BObject->{"type"} ne $BObject2->{"type"};
514 warn "new $type $Bcb Buffer ".$BObject->{"Buffer"}." != old $type $$ref Buffer ".$BObject2->{"Buffer"}
515 if $BObject->{"Buffer"} ne $BObject2->{"Buffer"};
517 if ($$ref && $$ref eq $Bcb) {
518 $BObject->{"ref_count"}+=$Bcb{$$ref}->{"ref_count"};
521 $Bcb{$Bcb}=$BObject; # &Bcb_conflict needs this reference
522 Bcb_conflict $CObject,$Bcb;
528 my($SharedCacheMap,$FileOffset,$Length)=@_;
530 return if !(my $CObject=CObject $SharedCacheMap);
531 if (defined($FileOffset) && defined($Length)) {
532 warn "Mapping data (end ".tohex($FileOffset+$Length).") out of FileSize ".$CObject->{"FileSize"}
533 if $FileOffset+$Length>eval($CObject->{"FileSize"});
535 $Object->{"SharedCacheMap"}=$CObject->{"SharedCacheMap"};
536 if (defined $FileOffset) {
537 $Object->{"FileOffset"}=tohex($FileOffset);
539 $Object->{"type"}="map";
540 $Object->{"ref_count"}=1;
543 sub map_new_from_FileObject($;$$)
545 my($FileObject,$FileOffset,$Length)=@_;
547 return if !(my $CObject=CObject_from_FileObject $FileObject);
548 map_new $CObject->{"SharedCacheMap"},$FileOffset,$Length;
551 sub map_new_leave($;$)
555 $Object->{"Bcb"}=$Bcb;
556 return if !(my $CObject=CObject $Object->{"SharedCacheMap"});
558 if (defined $Buffer) {
559 $Object->{"Buffer"}=tohex(eval($Buffer)-(eval($Object->{"FileOffset"}) || 0));
561 delete $Object->{"FileOffset"};
563 my $ref=\$CObject->{"map"};
564 # There may exist some pin bcbs even if we are creating the new map bcb.
565 Bcb_checkref $Object,$ref;
570 my($FileObject,$FileOffset,$Length)=@_;
572 map_new_from_FileObject $FileObject,$FileOffset,$Length;
575 sub CcMapData_leave($$)
579 map_new_leave $Bcb,$Buffer;
584 my($FileObject,$FileOffset,$Length)=@_;
586 return if !(my $CObject=CObject_from_FileObject $FileObject);
587 warn "Pinning of non-PinAccess FileObject $FileObject" if !$CObject->{"PinAccess"};
588 warn "Mapping data (end ".tohex($FileOffset+$Length).") out of FileSize ".$CObject->{"FileSize"}
589 if $FileOffset+$Length>eval($CObject->{"FileSize"});
590 warn "Pinning Length ".tohex($Length)." > 0x1000" if $Length>0x1000;
591 warn "Pinning across file page (start=".tohex($FileOffset).",end-1=".tohex($FileOffset+$Length-1).")"
592 if ($FileOffset&~0xFFF)!=(($FileOffset+$Length-1)&~0xFFF);
593 $Object->{"SharedCacheMap"}=$CObject->{"SharedCacheMap"};
594 $Object->{"FileOffset"}=tohex($FileOffset);
595 $Object->{"type"}="pin";
596 $Object->{"ref_count"}=1;
599 sub pin_new_leave($$)
603 $Object->{"Bcb"}=$Bcb;
604 return if !(my $CObject=CObject $Object->{"SharedCacheMap"});
605 $Object->{"Buffer"}=tohex(eval($Buffer)-(eval($Object->{"FileOffset"})&0xFFF));
606 my $shift=eval($Object->{"FileOffset"})&0xFFF;
607 $Object->{"FileOffset"}=tohex(eval($Object->{"FileOffset"})-$shift);
608 $Object->{"Buffer"}=tohex(eval($Buffer)-$shift);
610 my $ref=\$CObject->{"pin"}{$Object->{"FileOffset"}};
611 # There may not exist map bcb even if we are creating the new pin bcb.
612 Bcb_checkref $Object,$ref;
617 my($FileObject,$FileOffset,$Length)=@_;
619 pin_new $FileObject,$FileOffset,$Length;
622 sub CcPinRead_leave($$)
626 pin_new_leave $Bcb,$Buffer;
629 sub CcPreparePinWrite($$$)
631 my($FileObject,$FileOffset,$Length)=@_;
633 pin_new $FileObject,$FileOffset,$Length;
636 sub CcPreparePinWrite_leave($$)
640 pin_new_leave $Bcb,$Buffer;
641 my $BObject=BObject $Bcb;
642 $BObject->{"dirty"}=1;
645 sub CcPinMappedData($$$)
647 my($FileObject,$FileOffset,$Length)=@_;
649 pin_new $FileObject,$FileOffset,$Length;
652 sub CcPinMappedData_leave($)
656 return if !(my $CObject=CObject $Object->{"SharedCacheMap"});
657 do { warn "CcPinMappedData() with Bcb $Bcb on non-CcMapData()ed SharedCacheMap ".$CObject->{"SharedCacheMap"}; return; }
658 if !(my $mapBcb=$CObject->{"map"});
659 return if !(my $BmapObject=BObject $mapBcb);
660 my $Buffer=tohex(eval($BmapObject->{"Buffer"})+eval($Object->{"FileOffset"}));
662 my $Bcb2=$CObject->{"pin"}{tohex(eval($Object->{"FileOffset"})&~0xFFF)};
663 my $BObject2=BObject $Bcb2 if $Bcb2;
665 pin_new_leave $Bcb,$Buffer;
668 sub CcSetDirtyPinnedData($$)
672 return if !(my $BObject=BObject $Bcb);
673 # Do not: warn "Lsn already set for Bcb $Bcb as ".$BObject->{"Lsn"}." while current Lsn=$Lsn" if $BObject->{"Lsn"};
674 # as it is permitted.
675 warn "Lsn goes backward for Bcb $Bcb old Lsn ".$BObject->{"Lsn"}." to a new Lsn=$Lsn"
676 if $BObject->{"Lsn"} && eval($BObject->{"Lsn"})>eval($Lsn);
677 $BObject->{"Lsn"}=$Lsn if $Lsn ne "0x".("F"x8);
678 $BObject->{"dirty"}=1;
679 return if !(my $CObject=CObject $BObject->{"SharedCacheMap"});
682 sub FlushToLsnRoutine($$)
684 my($LogHandle,$Lsn)=@_;
686 $Object->{"LogHandle"}=$LogHandle;
687 $Object->{"Lsn"}=$Lsn;
690 my $LogHandle_static;
691 sub CcSetLogHandleForFile($$$)
693 my($FileObject,$LogHandle,$FlushToLsnRoutine)=@_;
695 return if !(my $CObject=CObject_from_FileObject $FileObject);
696 warn "LogHandle ".$CObject->{"LogHandle"}." already exists for SharedCacheMap ".$CObject->{"SharedCacheMap"}
697 if $CObject->{"LogHandle"};
698 return if !eval $LogHandle; # $LogHandle may be "0x0"
699 # ntfs.sys uses single LogHandle for its whole session:
700 warn "Non-unique LogHandle $LogHandle while last LogHandle was $LogHandle_static"
701 if $LogHandle_static && $LogHandle ne $LogHandle_static;
702 $CObject->{"LogHandle"}=$LogHandle;
703 if (!$LogHandle{$LogHandle}) {
704 $LogHandle{$LogHandle}={
705 "LogHandle"=>$LogHandle,
710 sub IRP_MJ_WRITE_leave_page($$)
712 my($ByteOffset,$Lsn_check)=@_;
714 my $SharedCacheMap=$Object->{"data"}[0]{"SharedCacheMap"};
715 return if !(my $CObject=CObject $SharedCacheMap);
716 my $FlushToLsnRoutine=$LastLeave if $LastLeave->{"by"} eq "FlushToLsnRoutine";
717 # Do not: my $Bcb=$CObject->{"pin"}{$ByteOffset};
718 # as Bcbs with $BObject->{"OwnerPointer"} are no longer stored in $CObject->{"pin"}.
720 for my $Bcb (keys(%Bcb)) {
721 my $BObject=BObject $Bcb;
723 && $BObject->{"type"} eq "pin"
724 && $BObject->{"SharedCacheMap"} eq $SharedCacheMap
725 && $BObject->{"FileOffset"} eq $ByteOffset) {
731 warn "Non-Bcb IRP_MJ_WRITE ByteOffset=$ByteOffset as non-toplevel function"
732 ." (".join(",",map({ $_->{"line_enter"}.":".$_->{"by"}; } @$EnterLeave)).")";
733 # warn Dumper $CObject;
734 # Direct IRP_MJ_WRITE can be from callbacked 'FlushToLsnRoutine'.
735 # It can occur even from other callbacks ('DirtyPageRoutine' etc.)
736 # but it was not needed here yet.
737 } if @$EnterLeave && !(${$EnterLeave}[$#$EnterLeave]->{"by"} eq "FlushToLsnRoutine");
738 warn "Non-Bcb IRP_MJ_WRITE ByteOffset=$ByteOffset but FlushToLsnRoutine was preceding"
739 if $FlushToLsnRoutine;
742 warn "Ambiguous matching Bcbs ".join(",",@Bcbs)
743 ." to SharedCacheMap $SharedCacheMap WRITE ByteOffset $ByteOffset"
746 return if !(my $BObject=BObject $Bcb);
747 warn "IRP_MJ_WRITE on non-dirty Bcb $Bcb" if !$BObject->{"dirty"};
748 if ($FlushToLsnRoutine) {
751 "Bcb_Lsn",$BObject->{"Lsn"},
755 warn "Missing preceding FlushToLsnRoutine during IRP_MJ_WRITE of Bcb $Bcb with Lsn ".$BObject->{"Lsn"}
756 if $BObject->{"Lsn"};
758 warn "IRP_MJ_WRITE with FlushToLsnRoutine although not in AcquireForLazyWrite"
759 if $FlushToLsnRoutine && !($CObject->{"AcquireForLazyWrite"}>=1);
760 warn "IRP_MJ_WRITE not the toplevel function"
761 ." (".join(",",map({ $_->{"line_enter"}.":".$_->{"by"}; } @$EnterLeave)).")"
763 || (1==@$EnterLeave && ${$EnterLeave}[0]->{"by"} eq "CcFlushCache")
764 || (2==@$EnterLeave && ${$EnterLeave}[0]->{"by"} eq "IRP_MJ_FILE_SYSTEM_CONTROL"
765 && ${$EnterLeave}[1]->{"by"} eq "CcFlushCache"));
766 my $CcFlushCache=${$EnterLeave}[$#$EnterLeave];
767 if ($CcFlushCache && $CcFlushCache->{"by"} eq "CcFlushCache") {
768 $CcFlushCache->{"CcFlushCached"}++;
769 if ($CcFlushCache->{"FileOffset"} ne "0x".("F"x8) || $CcFlushCache->{"Length"} ne "0x0") {
770 warn "IRP_MJ_WRITE outside of range of active CcFlushCache()"
771 if eval($ByteOffset)< eval($CcFlushCache->{"FileOffset"})
772 || eval($ByteOffset)>=eval($CcFlushCache->{"FileOffset"})+eval($CcFlushCache->{"Length"});
775 # Keep $BObject->{"dirty"} there for &delete_BObject sanity checks.
776 delete_BObject $BObject if $BObject->{"dirty"} && !$BObject->{"ref_count"};
779 sub IRP_MJ_WRITE_leave()
781 do { warn "Length $_ not divisible by 0x1000" if eval($_)%0x1000; } for ($Object->{"WRITE"}{"Length"});
783 for my $reloffs (0..(eval($Object->{"WRITE"}{"Length"})/0x1000)-1) {
784 IRP_MJ_WRITE_leave_page tohex(eval($Object->{"WRITE"}{"ByteOffset"})+0x1000*$reloffs),\@Lsn_check;
787 if ($LastLeave->{"by"} eq "FlushToLsnRoutine" && (my $FlushToLsnRoutine=$LastLeave)) {
790 my $Lsn=eval $_->{"Bcb_Lsn"};
791 $Lsn_max=$Lsn if !defined($Lsn_max) || $Lsn_max<$Lsn;
793 warn "FlushToLsnRoutine of line_enter ".$FlushToLsnRoutine->{"line_enter"}
794 ." got Lsn ".$FlushToLsnRoutine->{"Lsn"}." although Bcbs have "
795 .join(",",map({ "(".$_->{"Bcb"}.":".$_->{"Bcb_Lsn"}.")"; } @Lsn_check))
796 if tohex($Lsn_max) ne $FlushToLsnRoutine->{"Lsn"};
800 sub CcFlushCache($$$$)
802 my($SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length)=@_;
804 $Object->{"CcFlushCached"}=0;
805 $Object->{"FileOffset"}=$FileOffset;
806 $Object->{"Length"}=$Length;
809 sub CcFlushCache_leave($$)
811 my($Status,$Information)=@_;
813 warn "CcFlushCache() not the toplevel function"
814 ." (".join(",",map({ $_->{"line_enter"}.":".$_->{"by"}; } @$EnterLeave)).")"
816 || (1==@$EnterLeave && ${$EnterLeave}[0]->{"by"} eq "IRP_MJ_FILE_SYSTEM_CONTROL"));
817 if ($Status ne "0x".("F"x8) || $Information ne "0x".("F"x8)) {
818 warn "Unexpected Status $Status" if eval $Status;
819 warn "Unexpected Information $Information while CcFlushCached=".$Object->{"CcFlushCached"}
820 if eval($Information)!=eval($Object->{"CcFlushCached"})*0x1000;
824 sub CcPrepareMdlWrite($$$)
826 my($FileObject,$FileOffset,$Length)=@_;
828 $Object->{"FileObject"}=$FileObject;
829 warn "FileOffset $FileOffset not divisible by 0x1000" if eval($FileOffset)%0x1000;
830 $Object->{"FileOffset"}=$FileOffset;
831 warn "Length $Length not divisible by 0x1000" if eval($Length)%0x1000;
832 $Object->{"Length"}=$Length;
835 sub CcPrepareMdlWrite_leave($$$)
837 my($MdlChain,$Status,$Information)=@_;
839 do { warn "Unexpected Status $Status"; return; } if eval $Status;
840 warn "Unexpected Information $Information" if $Information ne $Object->{"Length"};
841 warn "MdlChain $MdlChain already exists" if $MdlChain{$MdlChain};
842 $MdlChain{$MdlChain}=$Object;
845 sub CcMdlWriteComplete($$$)
847 my($FileObject,$FileOffset,$MdlChain)=@_;
849 return if !(my $MObject=MObject $MdlChain);
850 warn "CcMdlWriteComplete() parameter FileObject $FileObject"
851 ." not matching MdlChain $MdlChain FileObject ".$MObject->{"FileObject"}
852 if $FileObject ne $MObject->{"FileObject"};
853 warn "CcMdlWriteComplete() parameter FileOffset $FileOffset"
854 ." not matching MdlChain $MdlChain FileOffset ".$MObject->{"FileOffset"}
855 if $FileOffset ne $MObject->{"FileOffset"};
856 # Propose MdlChain to a simulated Bcb.
857 # We must split it by pages as pin can be just 0x1000 sized.
858 return if !(my $CObject=CObject_from_FileObject $MObject->{"FileObject"});
859 for my $reloffs (0..eval($MObject->{"Length"})/0x1000-1) {
860 my $BObject={ %$MObject };
861 $BObject->{"Bcb"}="MdlChain $MdlChain reloffs $reloffs";
862 $BObject->{"FileOffset"}=tohex(eval($MObject->{"FileOffset"})+$reloffs*0x1000);
863 $BObject->{"SharedCacheMap"}=$CObject->{"SharedCacheMap"};
864 $BObject->{"type"}="pin";
865 $BObject->{"ref_count"}=0;
866 $BObject->{"dirty"}=1;
867 warn "Bcb ".$BObject->{"Bcb"}." already exists" if $Bcb{$BObject->{"Bcb"}};
868 $Bcb{$BObject->{"Bcb"}}=$BObject;
870 delete $MdlChain{$MdlChain};
873 sub CcMdlWriteAbort($$)
875 my($FileObject,$MdlChain)=@_;
877 warn "CcMdlWriteAbort() not handled";
880 sub AcquireForLazyWrite_leave($)
884 warn "Unexpected 'r' $r" if $r ne "1";
885 warn "AcquireForLazyWrite() not the toplevel function" if @$EnterLeave;
886 return if !(my $CObject=CObject $Object->{"data"}[0]{"SharedCacheMap"});
887 $CObject->{"AcquireForLazyWrite"}++;
890 sub ReleaseFromLazyWrite_leave()
892 warn "ReleaseFromLazyWrite() not the toplevel function" if @$EnterLeave;
893 return if !(my $CObject=CObject $Object->{"data"}[0]{"SharedCacheMap"});
894 warn "Invalid 'AcquireForLazyWrite' value ".$CObject->{"AcquireForLazyWrite"}
895 if !($CObject->{"AcquireForLazyWrite"}>=1);
896 $CObject->{"AcquireForLazyWrite"}--;
903 return if !(my $BObject=BObject $Bcb);
904 map_new $BObject->{"SharedCacheMap"};
905 $Object->{"Buffer"}=tohex(eval($BObject->{"Buffer"})-eval($BObject->{"FileOffset"} || 0));
908 sub CcRemapBcb_leave($)
919 return if !(my $BObject=BObject $Bcb);
920 return if --$BObject->{"ref_count"};
921 if ($BObject->{"dirty"}) {
922 # last unpin of unreferenced dirty Bcb will no longer allow reincarnation
923 # of the same Bcb to the pin map of its SharedCacheMap.
924 return if !(my $CObject=CObject $BObject->{"SharedCacheMap"});
925 warn "unpin() of pin Bcb $Bcb but it is already not registered in SharedCacheMap ".$BObject->{"SharedCacheMap"}." pin map"
926 if (!$CObject->{"pin"}{$BObject->{"FileOffset"}} || $CObject->{"pin"}{$BObject->{"FileOffset"}} ne $Bcb)
927 && !$BObject->{"OwnerPointer"};
928 delete $CObject->{"pin"}{$BObject->{"FileOffset"}}
929 if $CObject->{"pin"}{$BObject->{"FileOffset"}} && ($CObject->{"pin"}{$BObject->{"FileOffset"}} eq $Bcb);
932 delete_BObject $BObject;
942 sub CcUnpinDataForThread($)
949 sub CcSetBcbOwnerPointer($$)
951 my($Bcb,$OwnerPointer)=@_;
953 return if !(my $BObject=BObject $Bcb);
954 warn "CcSetBcbOwnerPointer() on map Bcb $Bcb" if $BObject->{"type"} ne "pin";
955 return if !(my $CObject=CObject $BObject->{"SharedCacheMap"});
956 warn "Double CcSetBcbOwnerPointer() on Bcb $Bcb" if defined $BObject->{"OwnerPointer"};
957 my $val=$CObject->{"pin"}{$BObject->{"FileOffset"}};
958 warn "CcSetBcbOwnerPointer() on unregistered pin Bcb $Bcb" if !$val || $val ne $Bcb;
959 delete $CObject->{"pin"}{$BObject->{"FileOffset"}} if $val && $val eq $Bcb;
960 $BObject->{"OwnerPointer"}=$OwnerPointer;
963 sub IRP_MJ_CLOSE_leave()
965 my $FileObject=$Object->{"data"}[0]{"FileObject"};
966 # # IRP_MJ_CLOSE of FileObject w/o CcInitializeCacheMap()?
967 # return if !$FileObject{$FileObject};
968 return if !(my $FObject=FObject $FileObject);
969 if (eval(my $SectionObjectPointer=$FObject->{"SectionObjectPointer"})) {
970 return if !(my $SObject=SObject $SectionObjectPointer);
971 my $SharedCacheMap=$SObject->{"SharedCacheMap"};
972 if (eval $SharedCacheMap) {
973 return if !(my $CObject=CObject $SObject->{"SharedCacheMap"});
974 # SharedCacheMap may still exist for FCB although this FileObject gets destroyed now.
975 # warn "SectionObjectPointer $SectionObjectPointer still exists during IRP_MJ_CLOSE"
976 # ." while SharedCacheMap ".$CObject->{"SharedCacheMap"}." ref_count ".$CObject->{"ref_count"}
977 # if $SectionObjectPointer && $CObject->{"ref_count"};
980 delete_FObject $FObject;
985 my $hex='0x[\dA-F]+';
990 # We may get some foreign garbage without '\n' before our debug data line:
991 # Do not use '\bTraceFS' as there really can be precediny _any_ data.
992 s#^.*?TraceFS[(]($hex/$hex)[)]: ## or do { print "$_\n" if $filter; next; };
996 if (/^enter: (\w+)/) {
999 $Object->{"line_enter"}=$.;
1000 $Object->{"ProcessThread"}=$ProcessThread;
1001 push @{$EnterLeave{$ProcessThread}},$Object;
1003 elsif (/^leave: (\w+)/) {
1004 warn "Empty pop stack during 'leave' of $1" if !($Object=pop @{$EnterLeave{$ProcessThread}});
1005 warn "Non-matching popped 'by' ".$Object->{"by"}." ne current 'leave' $1"
1006 if $Object->{"by"} ne $1;
1007 $Object->{"line_leave"}=$.;
1008 push @{$LastLeave{$ProcessThread}},$Object;
1010 elsif (my($FileObject,$FileName,$Flags,$SectionObjectPointer,$SharedCacheMap)=
1011 /^FileObject=($hex): FileName=(?:NULL|'(.*)'),Flags=($hex),SectionObjectPointer=($hex),->SharedCacheMap=($hex)/) {
1012 my $aref=$EnterLeave{$ProcessThread};
1013 warn "Empty stack during 'data' line" if !($Object=${$aref}[$#$aref]);
1015 "FileObject"=>$FileObject,
1016 "FileName"=>$FileName,
1018 "SectionObjectPointer"=>$SectionObjectPointer,
1019 "SharedCacheMap"=>$SharedCacheMap,
1022 push @{$Object->{"data"}},$data;
1023 my $isinit={ map(($_=>1),qw(
1024 CcInitializeCacheMap
1025 CcUninitializeCacheMap
1027 )) }->{$Object->{"by"}};
1029 if 1==@{$Object->{"data"}} || !$isinit;
1031 # Prevent 'SharedCacheMap' 0->N change by CcInitializeCacheMap() called inside.
1032 for my $ref (@$aref[0..$#$aref-1]) {
1033 $ref->{"data"}[0]->{"SharedCacheMap"}=$SharedCacheMap;
1036 if (2<=@{$Object->{"data"}}) {
1037 my $data_prev=$Object->{"data"}[$#{$Object->{"data"}}-1];
1038 for my $field (qw(FileObject FileName Flags),($isinit ? () : qw(SharedCacheMap))) {
1039 next if !defined(my $prev=$data_prev->{$field});
1040 next if !defined(my $now=$data->{$field});
1041 my $by=$Object->{"by"};
1042 if ($field eq "Flags") {
1043 next if $by eq "IRP_MJ_CREATE" && $field eq "Flags";
1044 my $FO_CLEANUP_COMPLETE=0x4000;
1045 $now=tohex(eval($now)&~$FO_CLEANUP_COMPLETE) if $by eq "IRP_MJ_CLEANUP";
1046 my $FO_FILE_FAST_IO_READ=0x80000;
1047 $prev=tohex(eval($prev)&~$FO_FILE_FAST_IO_READ) if $by eq "IRP_MJ_CLEANUP";
1048 $now=tohex(eval($now)&~$FO_FILE_FAST_IO_READ) if $by eq "IRP_MJ_READ" && !(eval($prev)&$FO_FILE_FAST_IO_READ);
1049 my $FO_FILE_MODIFIED=0x1000;
1050 $now=tohex(eval($now)&~$FO_FILE_MODIFIED) if $by eq "IRP_MJ_WRITE" && !(eval($prev)&$FO_FILE_MODIFIED);
1051 my $FO_FILE_SIZE_CHANGED=0x2000;
1052 $prev=tohex(eval($prev)&~$FO_FILE_MODIFIED)
1053 if $by eq "IRP_MJ_SET_INFORMATION" && !(eval($now)&$FO_FILE_MODIFIED);
1054 $prev=tohex(eval($prev)&~$FO_FILE_SIZE_CHANGED)
1055 if $by eq "IRP_MJ_SET_INFORMATION" && !(eval($now)&$FO_FILE_SIZE_CHANGED);
1057 next if $by eq "IRP_MJ_CLOSE" && $field eq "FileName";
1058 $prev=~s#\\$## if $by eq "IRP_MJ_CREATE";
1059 $prev="\\" if $by eq "IRP_MJ_CREATE" && $prev eq "";
1060 $prev=~s#:.*## if $by eq "IRP_MJ_CREATE" && $prev ne $now;
1061 next if $field eq "SharedCacheMap" && !SharedCacheMap_valid $prev && !SharedCacheMap_valid $now;
1062 do { warn "Changed data field $field, prev=".$data_prev->{$field}.", now=".$data->{$field}." by $by";
1063 # print STDERR Dumper $data_prev,$data;
1069 elsif (my($ByteOffset,$Length)=
1070 /^WRITE: ByteOffset=($hex),Length=($hex)/) {
1071 my $aref=$EnterLeave{$ProcessThread};
1072 warn "Empty stack during 'data' line" if !($Object=${$aref}[$#$aref]);
1073 $Object->{"WRITE"}={
1074 "ByteOffset"=>$ByteOffset,
1080 $LastLeave=${$LastLeave{$ProcessThread}}[$#{$LastLeave{$ProcessThread}}-1];
1081 $EnterLeave=$EnterLeave{$ProcessThread};
1084 /^leave: IRP_MJ_\w+: r=($hex)/) {
1085 # Failed requests should make no consequences.
1089 if (my($FileObject,$AllocationSize,$FileSize,$ValidDataLength,$PinAccess)=
1090 /^enter: CcInitializeCacheMap: FileObject=($hex),FileSizes,->AllocationSize=($hex),->FileSize=($hex),->ValidDataLength=($hex),PinAccess=([01]),/) {
1091 CcInitializeCacheMap $FileObject,eval($AllocationSize),eval($FileSize),eval($ValidDataLength),eval($PinAccess);
1094 if (/^leave: CcInitializeCacheMap\b/) {
1095 CcInitializeCacheMap_leave;
1099 if (my($FileObject,$TruncateSize)=
1100 /^enter: CcUninitializeCacheMap: FileObject=($hex),TruncateSize=($hex),/) {
1101 CcUninitializeCacheMap $FileObject,eval($TruncateSize);
1105 /^leave: CcUninitializeCacheMap: r=([01])/) {
1106 CcUninitializeCacheMap_leave $r;
1110 if (my($FileObject,$AllocationSize,$FileSize,$ValidDataLength)=
1111 /^enter: CcSetFileSizes: FileObject=($hex),FileSizes,->AllocationSize=($hex),->FileSize=($hex),->ValidDataLength=($hex)/) {
1112 CcSetFileSizes $FileObject,eval($AllocationSize),eval($FileSize),eval($ValidDataLength);
1116 if (/^leave: IRP_MJ_CREATE\b/) {
1117 IRP_MJ_CREATE_leave;
1121 if (/^leave: IRP_MJ_CLOSE\b/) {
1126 if (my($FileObject,$FileOffset,$Length)=
1127 /^enter: CcMapData: FileObject=($hex),FileOffset=($hex),Length=($hex),Flags=0x1/) {
1128 CcMapData $FileObject,eval($FileOffset),eval($Length);
1131 if (my($Bcb,$Buffer)=
1132 /^leave: CcMapData: r=1,Bcb=($hex),Buffer=($hex)/) {
1133 CcMapData_leave $Bcb,$Buffer;
1137 if (my($FileObject,$FileOffset,$Length)=
1138 /^enter: CcPinRead: FileObject=($hex),FileOffset=($hex),Length=($hex),Flags=0x1/) {
1139 CcPinRead $FileObject,eval($FileOffset),eval($Length);
1142 if (my($Bcb,$Buffer)=
1143 /^leave: CcPinRead: r=1,Bcb=($hex),Buffer=($hex)/) {
1144 CcPinRead_leave $Bcb,$Buffer;
1148 if (my($FileObject,$FileOffset,$Length)=
1149 /^enter: CcPreparePinWrite: FileObject=($hex),FileOffset=($hex),Length=($hex),Zero=([01]),Flags=0x1/) {
1150 CcPreparePinWrite $FileObject,eval($FileOffset),eval($Length);
1153 if (my($Bcb,$Buffer)=
1154 /^leave: CcPreparePinWrite: r=1,Bcb=($hex),Buffer=($hex)/) {
1155 CcPreparePinWrite_leave $Bcb,$Buffer;
1159 if (my($FileObject,$FileOffset,$Length)=
1160 /^enter: CcPinMappedData: FileObject=($hex),FileOffset=($hex),Length=($hex),Flags=0x1/) {
1161 CcPinMappedData $FileObject,eval($FileOffset),eval($Length);
1165 /^leave: CcPinMappedData: r=1,Bcb=($hex)/) {
1166 CcPinMappedData_leave $Bcb;
1170 if (my($BcbVoid,$Lsn)=
1171 /^enter: CcSetDirtyPinnedData: BcbVoid=($hex),Lsn=($hex)/) {
1172 CcSetDirtyPinnedData $BcbVoid,$Lsn;
1176 if (my($LogHandle,$Lsn)=
1177 /^enter: FlushToLsnRoutine: LogHandle=($hex),Lsn=($hex)/) {
1178 FlushToLsnRoutine $LogHandle,$Lsn;
1182 if (/^leave: IRP_MJ_WRITE\b/) {
1187 if (my($SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length)=
1188 /^enter: CcFlushCache: SectionObjectPointer=($hex),->SharedCacheMap=($hex),FileOffset=($hex),Length=($hex)/) {
1189 CcFlushCache $SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length;
1193 if (my($Status,$Information)=
1194 /^leave: CcFlushCache: IoStatus->Status=($hex),IoStatus->Information=($hex)/) {
1195 CcFlushCache_leave $Status,$Information;
1200 /^leave: AcquireForLazyWrite: r=([01])/) {
1201 AcquireForLazyWrite_leave $r;
1204 if (/^leave: ReleaseFromLazyWrite\b/) {
1205 ReleaseFromLazyWrite_leave;
1208 if (my($FileObject,$LogHandle,$FlushToLsnRoutine)=
1209 /^enter: CcSetLogHandleForFile: FileObject=($hex),LogHandle=($hex),FlushToLsnRoutine=($hex)/) {
1210 CcSetLogHandleForFile $FileObject,$LogHandle,$FlushToLsnRoutine;
1214 if (my($FileObject,$FileOffset,$Length)=
1215 /^enter: CcPrepareMdlWrite: FileObject=($hex),FileOffset=($hex),Length=($hex)/) {
1216 CcPrepareMdlWrite $FileObject,$FileOffset,$Length;
1219 if (my($MdlChain,$Status,$Information)=
1220 /^leave: CcPrepareMdlWrite: MdlChain=($hex),IoStatus->Status=($hex),IoStatus->Information=($hex)/) {
1221 CcPrepareMdlWrite_leave $MdlChain,$Status,$Information;
1225 if (my($FileObject,$FileOffset,$MdlChain)=
1226 /^enter: CcMdlWriteComplete: FileObject=($hex),FileOffset=($hex),MdlChain=($hex)/) {
1227 CcMdlWriteComplete $FileObject,$FileOffset,$MdlChain;
1231 if (my($FileObject,$MdlChain)=
1232 /^enter: CcMdlWriteAbort: FileObject=($hex),MdlChain=($hex)/) {
1233 CcMdlWriteAbort $FileObject,$MdlChain;
1238 /^enter: CcRemapBcb: Bcb=($hex)/) {
1243 /^leave: CcRemapBcb: r=($hex)/) {
1244 CcRemapBcb_leave $r;
1249 /^enter: CcUnpinData: Bcb=($hex)/) {
1254 /^enter: CcUnpinDataForThread: Bcb=($hex)/) {
1255 CcUnpinDataForThread $Bcb;
1259 if (my($Bcb,$OwnerPointer)=
1260 /^enter: CcSetBcbOwnerPointer: Bcb=($hex),OwnerPointer=($hex)/) {
1261 CcSetBcbOwnerPointer $Bcb,$OwnerPointer;
1265 print "$_\n" if $filter;
1267 for my $FileObject (keys(%FileObject)) {
1268 warn "EXIT: still CcInitializeCacheMap FileObject $FileObject";
1269 next if !(my $FObject=FObject $FileObject);