当前位置: 首页 > news >正文

Ntfs!NtfsCheckpointVolume函数分析之Lfcb->RestartArea的变更和什么时候RestartArea写回文件的关系

Ntfs!NtfsCheckpointVolume函数分析之Lfcb->RestartArea的变更


第一部分:

VOID
NtfsCheckpointVolume (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN BOOLEAN OwnsCheckpoint,
IN BOOLEAN CleanVolume,
IN BOOLEAN FlushVolume,
IN ULONG LfsFlags,
IN LSN LastKnownLsn
)
{

    This routine is called periodically to perform a checkpoint on the volume
with respect to the log file.  The checkpoint dumps a bunch of log file
state information to the log file, and finally writes a summary of the
dumped information in its Restart Area.

    This checkpoint dumps the following:

        Open Attribute Table
(all of the attribute names for the Attribute Table)
Dirty Pages Table
Transaction Table

   此例程会定期调用,以根据日志文件对卷执行检查点操作。检查点会将大量日志文件状态信息转储到日志文件中,并最终在其重启区域中写入转储信息的摘要。


//
//  Finally, write our Restart Area to describe all of the above, and
//  give Lfs our new BaseLsn.
//

        LfsWriteRestartArea( Vcb->LogHandle,
sizeof( RESTART_AREA ),
&RestartArea,
LfsCleanShutdown,
&Vcb->LastRestartArea );

0: kd> kv
# ChildEBP RetAddr  Args to Child              
00 f78d6748 f71fe6bb e13417d8 08124479 00000000 Ntfs!LfsFlushLfcb+0x4c3 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\lfs\cachesup.c @ 970]
01 f78d679c f71796f4 013417d8 08124479 00000000 Ntfs!LfsFlushToLsnPriv+0x1c9 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\lfs\lbcbsup.c @ 163]
02 f78d67fc f71fdcd5 e13417d8 000000e0 00000001 Ntfs!LfsWriteLfsRestart+0x1fe (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\lfs\rstrtsup.c @ 179]
03 f78d6848 f71d9319 e12830e0 00000068 f78d6894 Ntfs!LfsWriteRestartArea+0x18d (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\lfs\restart.c @ 426]
04 f78d6ab4 f7192e4c 898118a0 895cf100 00000000 Ntfs!NtfsCheckpointVolume+0x13d1 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\ntfs\logsup.c @ 2529]
05 f78d6cec f717c5aa 898118a0 899c5488 898118a0 Ntfs!NtfsMountVolume+0x1268 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\ntfs\fsctrl.c @ 2418]
06 f78d6d04 f71484b0 898118a0 899c5488 8999d020 Ntfs!NtfsCommonFileSystemControl+0x8c (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\ntfs\fsctrl.c @ 837]
07 f78d6d80 80af2bb9 898118a0 00000000 8999d020 Ntfs!NtfsFspDispatch+0x1fe (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\fs\ntfs\fspdisp.c @ 336]
08 f78d6dac 80d391f0 898118a0 00000000 00000000 nt!ExpWorkerThread+0x10f (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ex\worker.c @ 1153]
09 f78d6ddc 80b00d52 80af2aaa 00000000 00000000 nt!PspSystemThreadStartup+0x2e (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ps\create.c @ 2213]
0a 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 [d:\srv03rtm\base\ntos\ke\i386\threadbg.asm @ 81]

第二部分:

VOID
LfsWriteLfsRestart (
IN PLFCB Lfcb,
IN ULONG ThisRestartSize,
IN BOOLEAN WaitForIo
)
{


LfsAllocateRestartArea( &NewRestart, ThisRestartSize );

        //
//  We allocate a Lbcb structure and update the values to
//  reflect this restart area.
//

        LfsAllocateLbcb( Lfcb, &NewLbcb );
SetFlag( NewLbcb->LbcbFlags, LBCB_RESTART_LBCB );        //关键代码

参考开始:
LfsFindFirstIo( Lfcb,
TargetLsn,
RestartLsn,
FirstLbcb,
&NextLbcb,
&FileOffset,
&ContainsLastEntry,
&LfsRestart,
&UseTailCopy,
&IoBlocks );


//
//  Check if this is a restart block or if we are passing through the log
//  file for the first time or if this Lbcb is still in the active queue.
//  If not, then group as many of the Lbcb's as can be part of a single Io.
//

    if (LfsLbcbIsRestart( FirstLbcb )) {

        *LfsRestart = TRUE;

#define LfsLbcbIsRestart(LBCB)                                  \
(FlagOn( (LBCB)->LbcbFlags, LBCB_RESTART_LBCB ))

参考结束:


(ULONG)NewLbcb->Length = ThisRestartSize;

        NewLbcb->PageHeader = (PVOID) Lfcb->RestartArea;

        //
//  Copy the existing restart area into the new area.
//

        RtlCopyMemory( NewRestart, Lfcb->RestartArea, ThisRestartSize );
Lfcb->RestartArea = NewRestart;

        //
//  Add this Lbcb to the end of the workque and flush to that point.
//

        InsertTailList( &Lfcb->LbcbWorkque, &NewLbcb->WorkqueLinks );


参考开始:
0: kd> t
Ntfs!LfsWriteLfsRestart:
f71794f6 6a2c            push    2Ch
0: kd> kc
#
00 Ntfs!LfsWriteLfsRestart
01 Ntfs!LfsWriteRestartArea
02 Ntfs!NtfsCheckpointVolume
03 Ntfs!NtfsMountVolume
04 Ntfs!NtfsCommonFileSystemControl
05 Ntfs!NtfsFspDispatch
06 nt!ExpWorkerThread
07 nt!PspSystemThreadStartup
08 nt!KiThreadStartup
0: kd> dv
Lfcb = 0xe13417d8


[+0x0a0] RestartArea      : 0xe139d008

参考结束:

    [+0x0a0] RestartArea      : 0xe1364f20 [Type: _LFS_RESTART_AREA *]

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 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

0: kd> dd 0xe139d008
e139d008  08124478 00000000 ffff0001 00000000
e139d018  00000028 004000e0 04000000 00000000
e139d028  00000068 00400030 85e12261 00000000
e139d038  00000000 00000000 00000000 00000000
e139d048  08124465 00000000 08124478 00000000
e139d058  ffffffff 00000000 00000000 00000008
e139d068  0054004e 00530046 00000000 00000000
e139d078  00000000 00000000 00000000 00000000
0: kd> dd 0xe1364f20
e1364f20  08124478 00000000 ffff0001 00000000
e1364f30  00000028 004000e0 04000000 00000000
e1364f40  00000068 00400030 85e12261 00000000
e1364f50  00000000 00000000 00000000 00000000
e1364f60  08124465 00000000 08124478 00000000
e1364f70  ffffffff 00000000 00000000 00000008
e1364f80  0054004e 00530046 00000000 00000000
e1364f90  00000000 00000000 00000000 00000000

第三部分:0x89897000页面写回文件

        //
//  Remember the first Lbcb in the list.
//

        FirstLbcb = CONTAINING_RECORD( Lfcb->LbcbWorkque.Flink,
LBCB,
WorkqueLinks );


//
//  Write the page header into the page and mark the page dirty.
//

                RtlCopyMemory( Add2Ptr( RestartPage, Lfcb->RestartDataOffset, PVOID ),
FirstLbcb->PageHeader,
(ULONG)FirstLbcb->Length );

           //
//  Remember the range we are flushing and find the second half of a page
//  if necessary.
//

            Lfcb->UserWriteData->FileOffset = FileOffset;
Lfcb->UserWriteData->Length = Length;

0: kd> dv FileOffset
FileOffset = 0x1000


Status = IoSynchronousPageWrite( Lfcb->FileObject,
Lfcb->LogHeadPartialMdl,
(PLARGE_INTEGER)&FileOffset,
&Event,
&Iosb );

0: kd> dx -r1 ((Ntfs!_LFCB *)0xe13417d8)
((Ntfs!_LFCB *)0xe13417d8)                 : 0xe13417d8 [Type: _LFCB *]

    [+0x14c] LogHeadMdl       : 0x899c57a8 [Type: _MDL *]
[+0x150] LogHeadPartialMdl : 0x895ccb00 [Type: _MDL *]
[+0x154] LogHeadBuffer    : 0x89896000 [Type: void *]

0: kd> dx -r1 ((Ntfs!_MDL *)0x895ccb00)
((Ntfs!_MDL *)0x895ccb00)                 : 0x895ccb00 [Type: _MDL *]
[+0x000] Next             : 0x0 [Type: _MDL *]
[+0x004] Size             : 32 [Type: short]
[+0x006] MdlFlags         : 28 [Type: short]
[+0x008] Process          : 0x0 [Type: _EPROCESS *]
[+0x00c] MappedSystemVa   : 0x89897000 [Type: void *]
[+0x010] StartVa          : 0x89897000 [Type: void *]
[+0x014] ByteCount        : 0x1000 [Type: unsigned long]
[+0x018] ByteOffset       : 0x0 [Type: unsigned long]

http://www.dtcms.com/a/273890.html

相关文章:

  • 两台电脑通过网线直连形成局域网,共享一台wifi网络实现上网
  • Cesium实战:交互式多边形绘制与编辑功能完全指南(最终修复版)
  • Unity3d程序运行显示debugger信息
  • c/c++拷贝函数
  • 【Qt 学习之路】Qt Android开发环境搭建:Ubuntu的Vmware虚拟机中的踩坑实录
  • Arcgis连接HGDB报错
  • python的类型注解讲解
  • c++设计模式:抽象工厂模式
  • 【unity游戏开发——优化篇】Unity6.2新功能介绍——Mesh LOD的使用
  • Redis数据类型之list
  • Vue3的组件通信方式
  • (1-7-2)Mysql 数据表的相关操作
  • ollama大模型spring单机集成
  • 输入输出练习
  • C++入门基础篇(二)
  • 【C语言网络编程】HTTP 客户端请求(域名解析过程)
  • P9755 [CSP-S 2023] 种树
  • 浮点测试初探
  • Genus:设计信息结构以及导航方式(路径种类)
  • Java中的泛型继承
  • 【C语言进阶】带你由浅入深了解指针【第四期】:数组指针的应用、介绍函数指针
  • 【Spring Boot】Spring Boot 4.0 的颠覆性AI特性全景解析,结合智能编码实战案例、底层架构革新及Prompt工程手册
  • mysql的LIMIT 用法
  • 1 APP-OneNET 生成token密钥
  • Ubuntu2404修改国内镜像
  • 我的第一个开源项目|Geex:道阻且长的开源之路
  • docker的学习
  • React中Redux基础和路由介绍
  • 将手工建模模型(fbx、obj)转换为3dtiles的免费工具!
  • threejs案例开发-中国3D国旗动画