Checked log file blocks more recent than temporary ones
Under some circumstances, the temporary log file blocks are not the latest ones, so check whether there are more recent ones. Only done for log version 1.x, as log version 2.x follow a different logic.pull/2/head
parent
02747ea647
commit
f06672a02c
|
@ -3686,6 +3686,60 @@ static int walkback(CONTEXT *ctx, const struct BUFFER *buf, u32 blk,
|
|||
return (state == T_ERR ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the latest log block
|
||||
*
|
||||
* Usually, the latest block is either block 2 or 3 which act as
|
||||
* temporary block before being copied to target location.
|
||||
* However under some unknown condition the block are written
|
||||
* immediately to target location, and we have to scan for the
|
||||
* latest one.
|
||||
* Currently this is not checked for logfile version 2.x which
|
||||
* use a different layout of temporary blocks.
|
||||
*/
|
||||
|
||||
const struct BUFFER *find_latest_block(CONTEXT *ctx, u32 baseblk,
|
||||
const struct BUFFER *basebuf)
|
||||
{
|
||||
le64 offset;
|
||||
leLSN prevlsn;
|
||||
leLSN curlsn;
|
||||
u32 curblk;
|
||||
u32 prevblk;
|
||||
const struct BUFFER *prevbuf;
|
||||
const struct BUFFER *curbuf;
|
||||
|
||||
offset = basebuf->block.record.copy.file_offset;
|
||||
curblk = baseblk;
|
||||
do {
|
||||
if (curblk < BASEBLKS) {
|
||||
prevbuf = basebuf;
|
||||
prevlsn = basebuf->block.record.last_end_lsn;
|
||||
prevblk = baseblk;
|
||||
curblk = le64_to_cpu(offset) >> blockbits;
|
||||
} else {
|
||||
if (optv)
|
||||
printf("block %d is more recent than block %d\n",
|
||||
(int)curblk, (int)prevblk);
|
||||
prevbuf = curbuf;
|
||||
prevlsn = curlsn;
|
||||
prevblk = curblk;
|
||||
curblk++;
|
||||
if (curblk >= (logfilesz >> blockbits))
|
||||
curblk = (log_major < 2 ? BASEBLKS : BASEBLKS2);
|
||||
}
|
||||
curbuf = read_buffer(ctx, curblk);
|
||||
if (curbuf && (curbuf->block.record.magic == magic_RCRD)) {
|
||||
curlsn = curbuf->block.record.copy.last_lsn;
|
||||
}
|
||||
} while (curbuf
|
||||
&& (curbuf->block.record.magic == magic_RCRD)
|
||||
&& (le64_to_cpu(curlsn) > le64_to_cpu(prevlsn)));
|
||||
if (optv)
|
||||
printf("Block %d is the latest one\n",(int)prevblk);
|
||||
return (prevbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the sequencing of blocks (when version >= 2.0)
|
||||
*
|
||||
|
@ -3982,6 +4036,12 @@ static int walk(CONTEXT *ctx)
|
|||
&nextbuf->block.record);
|
||||
}
|
||||
}
|
||||
if (startbuf && opts) {
|
||||
buf = startbuf = find_latest_block(ctx,
|
||||
blk, startbuf);
|
||||
latest_lsn = le64_to_cpu(
|
||||
buf->block.record.last_end_lsn);
|
||||
}
|
||||
} else {
|
||||
buf = startbuf = read_buffer(ctx, blk);
|
||||
nextbuf = (const struct BUFFER*)NULL;
|
||||
|
@ -4043,7 +4103,7 @@ static void version(void)
|
|||
{
|
||||
printf("\n%s v%s (libntfs-3g) - Recover updates committed by Windows"
|
||||
" on an NTFS Volume.\n\n", "ntfsrecover", VERSION);
|
||||
printf("Copyright (c) 2012-2016 Jean-Pierre Andre\n");
|
||||
printf("Copyright (c) 2012-2017 Jean-Pierre Andre\n");
|
||||
printf("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue