Ntfs!NtfsCheckpointVolume函数中的Ntfs!LfsFlushLfcb函数对Lfcb->LogHeadBuffer进行了赋值--重要
第一部分:
//
//
// If we can do the Io, call down to flush the Lfcb.
//
if (Flush) {
LfsFlushLfcb( Lfcb, Lsn, RestartLsn );
break;
}
第二部分:
if (LfsRestart) {
PLFS_RESTART_PAGE_HEADER RestartPage;
ASSERT( !UseTailCopy && IoBlocks == 1);
//
// Build the partial mdl to describe this lfs restart page from the permanently
// mapped piece of the log
//
RestartPage = Add2Ptr( Lfcb->LogHeadBuffer, FileOffset, PLFS_RESTART_PAGE_HEADER );
IoBuildPartialMdl( Lfcb->LogHeadMdl, Lfcb->LogHeadPartialMdl, RestartPage, (ULONG)Lfcb->LogPageSize );
第三部分:
0: kd> t
Ntfs!LfsFlushToLsnPriv+0x1c4:
f71fe6b6 e817d2f5ff call Ntfs!LfsFlushLfcb (f715b8d2)
0: kd> t
Ntfs!LfsFlushLfcb:
f715b8d2 689c000000 push 9Ch
0: kd> kc
#
00 Ntfs!LfsFlushLfcb
01 Ntfs!LfsFlushToLsnPriv
02 Ntfs!LfsWriteLfsRestart
03 Ntfs!LfsWriteRestartArea
04 Ntfs!NtfsCheckpointVolume
05 Ntfs!NtfsMountVolume
06 Ntfs!NtfsCommonFileSystemControl
07 Ntfs!NtfsFspDispatch
08 nt!ExpWorkerThread
09 nt!PspSystemThreadStartup
0a nt!KiThreadStartup
0: kd> dv
Lfcb = 0xe13417d8
TargetLsn = {135414905}
RestartLsn = 0x01 ''
FirstLbcb = 0x8999d020
if (TargetLsn.QuadPart > Lfcb->RestartArea->CurrentLsn.QuadPart) {
ThisLbcb = CONTAINING_RECORD( Lfcb->LbcbWorkque.Blink,
LBCB,
WorkqueLinks );
TargetLsn.QuadPart = ThisLbcb->LastLsn.QuadPart;
RestartLsn = (BOOLEAN) LfsLbcbIsRestart( ThisLbcb );
}
第四部分:
0: kd> dx -r1 ((Ntfs!_LFCB *)0xe13417d8)
((Ntfs!_LFCB *)0xe13417d8) : 0xe13417d8 [Type: _LFCB *]
[+0x000] NodeTypeCode : 2051 [Type: short]
[+0x002] NodeByteSize : 352 [Type: short]
[+0x070] SeqNumber : 8 [Type: __int64]
[+0x078] SeqNumberForWrap : 9 [Type: __int64]
[+0x080] SeqNumberBits : 0x28 [Type: unsigned long]
[+0x084] FileDataBits : 0x18 [Type: unsigned long]
[+0x088] LbcbWorkque [Type: _LIST_ENTRY]
0: kd> dx -r1 (*((Ntfs!_LIST_ENTRY *)0xe1341860))
(*((Ntfs!_LIST_ENTRY *)0xe1341860)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0xe135ed2c [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xe127bc34 [Type: _LIST_ENTRY *]
//
// Remember the first Lbcb in the list.
//
FirstLbcb = CONTAINING_RECORD( Lfcb->LbcbWorkque.Flink,
LBCB,
WorkqueLinks );
0: kd> dt _lbcb 0xe127bc34-4
Ntfs!_LBCB
+0x000 NodeTypeCode : 0n2050
+0x002 NodeByteSize : 0n96
+0x004 WorkqueLinks : _LIST_ENTRY [ 0xe1341860 - 0xe1350cec ]
+0x00c ActiveLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 FileOffset : 0n4096
+0x020 Length : 0n224
+0x028 SeqNumber : 0n0
+0x030 BufferOffset : 0n0
+0x038 PageHeader : 0xe139d008 Void
+0x03c LogPageBcb : (null)
+0x040 LastLsn : _LARGE_INTEGER 0x8124479
+0x048 LastEndLsn : _LARGE_INTEGER 0x8124479
+0x050 Flags : 0
+0x054 LbcbFlags : 0x20
+0x058 ResourceThread : 0
第五部分:
#define LfsLbcbIsRestart(LBCB) \
(FlagOn( (LBCB)->LbcbFlags, LBCB_RESTART_LBCB ))
#define LBCB_LOG_WRAPPED (0x00000001)
#define LBCB_ON_ACTIVE_QUEUE (0x00000002)
#define LBCB_NOT_EMPTY (0x00000004)
#define LBCB_FLUSH_COPY (0x00000008)
#define LBCB_RESTART_LBCB (0x00000020)
RestartLsn = (BOOLEAN) LfsLbcbIsRestart( ThisLbcb ); TRUE
0: kd> p
Ntfs!LfsFlushLfcb+0xaa:
f715b97c 83e020 and eax,20h
0: kd> r
eax=00000020
0: kd> dv FirstLbcb
FirstLbcb = 0xe135ed28
0: kd> dx -r1 (*((Ntfs!_LIST_ENTRY *)0xe1341860))
(*((Ntfs!_LIST_ENTRY *)0xe1341860)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0xe135ed2c [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xe127bc34 [Type: _LIST_ENTRY *]
0: kd> dt lbcb 0xe135ed2c-4
Ntfs!LBCB
+0x000 NodeTypeCode : 0n2050
+0x002 NodeByteSize : 0n96
+0x004 WorkqueLinks : _LIST_ENTRY [ 0xe1277b54 - 0xe1341860 ]
+0x00c ActiveLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 FileOffset : 0n4096
+0x020 Length : 0n4048
+0x028 SeqNumber : 0n0
+0x030 BufferOffset : 0n0
+0x038 PageHeader : 0xe1363008 Void
+0x03c LogPageBcb : (null)
+0x040 LastLsn : _LARGE_INTEGER 0x8124466
+0x048 LastEndLsn : _LARGE_INTEGER 0x8124466
+0x050 Flags : 0
+0x054 LbcbFlags : 0x20
+0x058 ResourceThread : 0
第六部分:
LfsFindFirstIo( Lfcb,
TargetLsn,
RestartLsn,
FirstLbcb,
&NextLbcb,
&FileOffset,
&ContainsLastEntry,
&LfsRestart,
&UseTailCopy,
&IoBlocks );
0: kd> p
Ntfs!LfsFlushLfcb+0x11a:
f715b9ec e883380a00 call Ntfs!LfsFindFirstIo (f71ff274)
0: kd> t
Ntfs!LfsFindFirstIo:
f71ff274 55 push ebp
0: kd> kc
#
00 Ntfs!LfsFindFirstIo
01 Ntfs!LfsFlushLfcb
02 Ntfs!LfsFlushToLsnPriv
03 Ntfs!LfsWriteLfsRestart
04 Ntfs!LfsWriteRestartArea
05 Ntfs!NtfsCheckpointVolume
06 Ntfs!NtfsMountVolume
07 Ntfs!NtfsCommonFileSystemControl
08 Ntfs!NtfsFspDispatch
09 nt!ExpWorkerThread
0a nt!PspSystemThreadStartup
0b nt!KiThreadStartup
0: kd> dv
Lfcb = 0xe13417d8
TargetLsn = {135414905}
RestartLsn = 0x20 ' '
FirstLbcb = 0xe135ed28
NextLbcb = 0xf78d66cc
FileOffset = 0xf78d6724
ContainsLastEntry = 0xf78d672c ""
//
// Local support routine.
//
VOID
LfsFindFirstIo (
IN PLFCB Lfcb,
IN LSN TargetLsn,
IN BOOLEAN RestartLsn,
IN PLBCB FirstLbcb,
OUT PLBCB *NextLbcb,
OUT PLONGLONG FileOffset,
OUT PBOOLEAN ContainsLastEntry,
OUT PBOOLEAN LfsRestart,
OUT PBOOLEAN UseTailCopy,
OUT PULONG IoBlocks
)
} else {
*ContainsLastEntry = FALSE;
}
0: kd> dv ContainsLastEntry
ContainsLastEntry = 0xf78d672c ""
0: kd> dx -r1 ((Ntfs!unsigned char *)0xf78d672c)
((Ntfs!unsigned char *)0xf78d672c) : 0xf78d672c : 0x0 [Type: unsigned char *]
0x0 [Type: unsigned char]
第七部分:
if (LfsLbcbIsRestart( FirstLbcb )) {
*LfsRestart = TRUE; //关键代码
0: kd> dv LfsRestart
LfsRestart = 0xf78d672e "???"
0: kd> dx -r1 ((Ntfs!unsigned char *)0xf78d672e)
((Ntfs!unsigned char *)0xf78d672e) : 0xf78d672e : 0x1 [Type: unsigned char *]
0x1 [Type: unsigned char]
第八部分:
//
// If we haven't found the Lbcb to restart from we will just use the
// next Lbcb after the last one found.
//
if ((*NextLbcb == NULL) && (FirstLbcb->WorkqueLinks.Flink != &Lfcb->LbcbWorkque)) {
*NextLbcb = CONTAINING_RECORD( FirstLbcb->WorkqueLinks.Flink,
LBCB,
WorkqueLinks );
}
0: kd> dx -r1 ((Ntfs!_LBCB *)0xe135ed28)
((Ntfs!_LBCB *)0xe135ed28) : 0xe135ed28 [Type: _LBCB *]
[+0x000] NodeTypeCode : 2050 [Type: short]
[+0x002] NodeByteSize : 96 [Type: short]
[+0x004] WorkqueLinks [Type: _LIST_ENTRY]
[+0x00c] ActiveLinks [Type: _LIST_ENTRY]
[+0x018] FileOffset : 4096 [Type: __int64]
[+0x020] Length : 4048 [Type: __int64]
[+0x028] SeqNumber : 0 [Type: __int64]
[+0x030] BufferOffset : 0 [Type: __int64]
[+0x038] PageHeader : 0xe1363008 [Type: void *]
[+0x03c] LogPageBcb : 0x0 [Type: void *]
[+0x040] LastLsn : {135414886} [Type: _LARGE_INTEGER]
[+0x048] LastEndLsn : {135414886} [Type: _LARGE_INTEGER]
[+0x050] Flags : 0x0 [Type: unsigned long]
[+0x054] LbcbFlags : 0x20 [Type: unsigned long]
[+0x058] ResourceThread : 0x0 [Type: unsigned long]
0: kd> dx -r1 (*((Ntfs!_LIST_ENTRY *)0xe135ed2c))
(*((Ntfs!_LIST_ENTRY *)0xe135ed2c)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0xe1277b54 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xe1341860 [Type: _LIST_ENTRY *]
0: kd> dt _lbcb 0xe1277b54-4
Ntfs!_LBCB
+0x000 NodeTypeCode : 0n2050
+0x002 NodeByteSize : 0n96
+0x004 WorkqueLinks : _LIST_ENTRY [ 0xe1350cec - 0xe135ed2c ]
+0x00c ActiveLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 FileOffset : 0n0
+0x020 Length : 0n4048
+0x028 SeqNumber : 0n0
+0x030 BufferOffset : 0n0
+0x038 PageHeader : 0xe138c008 Void
+0x03c LogPageBcb : (null)
+0x040 LastLsn : _LARGE_INTEGER 0x8124467
+0x048 LastEndLsn : _LARGE_INTEGER 0x8124467
+0x050 Flags : 0
+0x054 LbcbFlags : 0x20
+0x058 ResourceThread : 0
第九部分:
VOID
LfsFindFirstIo (
IN PLFCB Lfcb,
IN LSN TargetLsn,
IN BOOLEAN RestartLsn,
IN PLBCB FirstLbcb,
OUT PLBCB *NextLbcb,
OUT PLONGLONG FileOffset,
OUT PBOOLEAN ContainsLastEntry,
OUT PBOOLEAN LfsRestart,
OUT PBOOLEAN UseTailCopy,
OUT PULONG IoBlocks
)
dv
IoBlocks = 1
Length = IoBlocks * (ULONG) Lfcb->LogPageSize;
0: kd> dv Length
Length = 0x1000
} else {
TargetLbcb = FirstLbcb;
}
0: kd> dv TargetLbcb
TargetLbcb = 0xe135ed28
第十部分:
if (LfsRestart) {
PLFS_RESTART_PAGE_HEADER RestartPage;
ASSERT( !UseTailCopy && IoBlocks == 1);
//
// Build the partial mdl to describe this lfs restart page from the permanently
// mapped piece of the log
//
RestartPage = Add2Ptr( Lfcb->LogHeadBuffer, FileOffset, PLFS_RESTART_PAGE_HEADER );
IoBuildPartialMdl( Lfcb->LogHeadMdl, Lfcb->LogHeadPartialMdl, RestartPage, (ULONG)Lfcb->LogPageSize );
RestartPage->ChkDskLsn = LfsLi0;
RestartPage->MultiSectorHeader.UpdateSequenceArrayOffset
= Lfcb->RestartUsaOffset;
RestartPage->MultiSectorHeader.UpdateSequenceArraySize
= Lfcb->UsaArraySize;
//
// Maintain the illusion that all systems have log page == system page
// on disk so we can migrate disks between different platforms
//
RestartPage->SystemPageSize = (ULONG)Lfcb->LogPageSize;
RestartPage->LogPageSize = (ULONG)Lfcb->LogPageSize;
RestartPage->RestartOffset = (USHORT) Lfcb->RestartDataOffset;
RestartPage->MajorVersion = Lfcb->MajorVersion;
RestartPage->MinorVersion = Lfcb->MinorVersion;
0: kd> dv FileOffset
FileOffset = 0n4096
0: kd> dd 0x89897000
89897000 00000000 00000000 00000000 50554f4c
89897010 89862000 00000000 00000000 00000000
89897020 00000000 00000000 00000000 00000000
89897030 00000000 00000000 00000000 00000000
89897040 00000000 00000000 00000000 00000000
89897050 00000000 00000000 00000000 00000000
89897060 00000000 00000000 00000000 00000000
89897070 00000000 00000000 00000000 00000000
0: kd> dd 0x89896000
89896000 898d9000 8955c000 0000001a 50554f4c
89896010 89862000 898d9010 00000000 00000000
89896020 00000120 89934c40 89934c40 00000000
89896030 00000000 00000000 00000000 89934c9e
89896040 00000000 00000000 00000000 00000000
89896050 00000000 f7407364 8963c834 8963c808
89896060 000a0008 00000000 89896068 89896068
89896070 00000000 00000000 00000000 00000000
0: kd> dd 0x89897000
89897000 52545352 0009001e 00000000 00000000
89897010 00001000 00001000 00010030 00000001
89897020 00000000 00000000 00000000 00000000
89897030 00000000 00000000 00000000 00000000
89897040 00000000 00000000 00000000 00000000
89897050 00000000 00000000 00000000 00000000
89897060 00000000 00000000 00000000 00000000
89897070 00000000 00000000 00000000 00000000
0: kd> dt LFS_RESTART_PAGE_HEADER 0x89897000
Ntfs!LFS_RESTART_PAGE_HEADER
+0x000 MultiSectorHeader : _MULTI_SECTOR_HEADER
+0x008 ChkDskLsn : _LARGE_INTEGER 0x0
+0x010 SystemPageSize : 0x1000
+0x014 LogPageSize : 0x1000
+0x018 RestartOffset : 0x30
+0x01a MinorVersion : 0n1
+0x01c MajorVersion : 0n1
+0x01e UpdateSequenceArray : [1] 0
0: kd> dt LFS_RESTART_PAGE_HEADER 0x89897000 -r
Ntfs!LFS_RESTART_PAGE_HEADER
+0x000 MultiSectorHeader : _MULTI_SECTOR_HEADER
+0x000 Signature : [4] "RSTR"
+0x004 UpdateSequenceArrayOffset : 0x1e
+0x006 UpdateSequenceArraySize : 9
+0x008 ChkDskLsn : _LARGE_INTEGER 0x0
+0x000 LowPart : 0
+0x004 HighPart : 0n0
+0x000 u : __unnamed
+0x000 LowPart : 0
+0x004 HighPart : 0n0
+0x000 QuadPart : 0n0
+0x010 SystemPageSize : 0x1000
+0x014 LogPageSize : 0x1000
+0x018 RestartOffset : 0x30
+0x01a MinorVersion : 0n1
+0x01c MajorVersion : 0n1
+0x01e UpdateSequenceArray : [1] 0
[+0x04c] RestartDataOffset : 0x30 [Type: unsigned long]
#define Add2Ptr(P,I) ((PVOID)((PUCHAR)(P) + (I)))
0: kd> dt LFS_RESTART_PAGE_HEADER -v
Ntfs!LFS_RESTART_PAGE_HEADER
struct _LFS_RESTART_PAGE_HEADER, 8 elements, 0x20 bytes
+0x000 MultiSectorHeader : struct _MULTI_SECTOR_HEADER, 3 elements, 0x8 bytes
+0x008 ChkDskLsn : union _LARGE_INTEGER, 4 elements, 0x8 bytes
+0x010 SystemPageSize : Uint4B
+0x014 LogPageSize : Uint4B
+0x018 RestartOffset : Uint2B
+0x01a MinorVersion : Int2B
+0x01c MajorVersion : Int2B
+0x01e UpdateSequenceArray : [1] Uint2B
0: kd> dd 0xe1363008
e1363008 08124465 00000000 ffff0001 00000000
e1363018 00000028 004000e0 04000000 00000000
e1363028 00000068 00400030 85e12261 00000000
e1363038 00000000 00000000 00000000 00000000
e1363048 08124452 00000000 08124465 00000000
e1363058 ffffffff 00000000 00000000 00000008
e1363068 0054004e 00530046 00000000 00000000
e1363078 00000000 00000000 00000000 00000000
0: kd> dd 89897000
89897000 52545352 0009001e 00000000 00000000
89897010 00001000 00001000 00010030 00000001
89897020 00000000 00000000 00000000 00000000
89897030 00000000 00000000 00000000 00000000
89897040 00000000 00000000 00000000 00000000
89897050 00000000 00000000 00000000 00000000
89897060 00000000 00000000 00000000 00000000
89897070 00000000 00000000 00000000 00000000
0: kd> p
Ntfs!LfsFlushLfcb+0x23f:
f715bb11 c1e902 shr ecx,2
0: kd> p
Ntfs!LfsFlushLfcb+0x242:
f715bb14 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0: kd> r
eax=e135ed28 ebx=e13417d8 ecx=000003f4 edx=00000fd0 esi=e1363008 edi=89897030
0: kd> ?4*3f4
Evaluate expression: 4048 = 00000fd0
0: kd> dd 89897000
89897000 52545352 0009001e 00000000 00000000
89897010 00001000 00001000 00010030 00000001
89897020 00000000 00000000 00000000 00000000
89897030 08124465 00000000 ffff0001 00000000
89897040 00000028 004000e0 04000000 00000000
89897050 00000068 00400030 85e12261 00000000
89897060 00000000 00000000 00000000 00000000
89897070 08124452 00000000 08124465 00000000
0: kd> dd 89897000
89897000 52545352 0009001e 00000000 00000000
89897010 00001000 00001000 00010030 00000001
89897020 00000000 00000000 00000000 00000000
89897030 08124465 00000000 ffff0001 00000000
89897040 00000028 004000e0 04000000 00000000
89897050 00000068 00400030 85e12261 00000000
89897060 00000000 00000000 00000000 00000000
89897070 08124452 00000000 08124465 00000000
0: kd> dd 89897000+80*1
89897080 ffffffff 00000000 00000000 00000008
89897090 0054004e 00530046 00000000 00000000
898970a0 00000000 00000000 00000000 00000000
898970b0 00000000 00000000 00000000 00000000
898970c0 00000000 00000000 00000000 00000000
898970d0 00000000 00000000 00000000 00000000
898970e0 00000000 00000000 00000000 00000000
898970f0 00000000 00000000 00000000 00000000
0: kd> dt lfs_restart_area 89897030
Ntfs!LFS_RESTART_AREA
+0x000 CurrentLsn : _LARGE_INTEGER 0x8124465
+0x008 LogClients : 1
+0x00a ClientFreeList : 0xffff
+0x00c ClientInUseList : 0
+0x00e Flags : 0
+0x010 SeqNumberBits : 0x28
+0x014 RestartAreaLength : 0xe0
+0x016 ClientArrayOffset : 0x40
+0x018 FileSize : 0n67108864
+0x020 LastLsnDataLength : 0x68
+0x024 RecordHeaderLength : 0x30
+0x026 LogPageDataOffset : 0x40
+0x028 RestartOpenLogCount : 0x85e12261
+0x02c LastFailedFlushStatus : 0
+0x030 LastFailedFlushOffset : 0n0
+0x038 LastFailedFlushLsn : _LARGE_INTEGER 0x0
+0x040 LogClientArray : [1] _LFS_CLIENT_RECORD
0: kd> dx -id 0,0,899a2278 -r1 (*((Ntfs!_LFS_CLIENT_RECORD (*)[1])0x89897070))
(*((Ntfs!_LFS_CLIENT_RECORD (*)[1])0x89897070)) [Type: _LFS_CLIENT_RECORD [1]]
[0] [Type: _LFS_CLIENT_RECORD]
0: kd> dx -id 0,0,899a2278 -r1 (*((Ntfs!_LFS_CLIENT_RECORD *)0x89897070))
(*((Ntfs!_LFS_CLIENT_RECORD *)0x89897070)) [Type: _LFS_CLIENT_RECORD]
[+0x000] OldestLsn : {135414866} [Type: _LARGE_INTEGER]
[+0x008] ClientRestartLsn : {135414885} [Type: _LARGE_INTEGER]
[+0x010] PrevClient : 0xffff [Type: unsigned short]
[+0x012] NextClient : 0xffff [Type: unsigned short]
[+0x014] SeqNumber : 0x0 [Type: unsigned short]
[+0x016] AlignWord : 0x0 [Type: unsigned short]
[+0x018] AlignDWord : 0x0 [Type: unsigned long]
[+0x01c] ClientNameLength : 0x8 [Type: unsigned long]
[+0x020] ClientName [Type: unsigned short [64]]
0: kd> dx -id 0,0,899a2278 -r1 (*((Ntfs!unsigned short (*)[64])0x89897090))
(*((Ntfs!unsigned short (*)[64])0x89897090)) [Type: unsigned short [64]]
[0] : 0x4e [Type: unsigned short]
[1] : 0x54 [Type: unsigned short]
[2] : 0x46 [Type: unsigned short]
[3] : 0x53 [Type: unsigned short]