mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 10:04:00 +08:00
Defined an option to kill the Windows cache and play the log file
The new ntfsrecover option --kill-fast-restart can be used to delete the Windows fast-restart indication before playing the log. This can lead to data loss, but is needed before mounting a partition improperly unmounted from Windows when remounting on Windows is inconvenient.
This commit is contained in:
parent
ab4bdea00f
commit
4278fbb7f6
@ -86,6 +86,13 @@ generated during several sessions.
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Show some help information.
|
||||
.TP
|
||||
\fB\-k\fR, \fB\-\-kill\-fast\-restart\fR
|
||||
When Windows has been interrupted with fast restart mode activated,
|
||||
part of pending changes are kept in the Windows cache and only the same
|
||||
Windows version can recover them. This option can be used to apply the
|
||||
changes recorded in the log file and drop the ones in the Windows cache.
|
||||
This is dangerous and may cause loss of data.
|
||||
.TP
|
||||
\fB\-n\fR, \fB\-\-no-action\fR
|
||||
Do not apply any modification, useful when using the options -p, -s or -u.
|
||||
.TP
|
||||
|
@ -146,6 +146,7 @@ BOOL optd; /* device argument present*/
|
||||
BOOL opth; /* show help */
|
||||
BOOL opti; /* show invalid (stale) records */
|
||||
BOOL optf; /* show full log */
|
||||
BOOL optk; /* kill fast restart */
|
||||
BOOL optn; /* do not apply modifications */
|
||||
BOOL optp; /* count of transaction sets to play */
|
||||
BOOL optr; /* show a range of blocks */
|
||||
@ -2894,6 +2895,7 @@ static const struct BUFFER *read_restart(CONTEXT *ctx)
|
||||
{
|
||||
const struct BUFFER *buf;
|
||||
BOOL bad;
|
||||
int major, minor;
|
||||
|
||||
bad = FALSE;
|
||||
if (ctx->vol) {
|
||||
@ -2943,13 +2945,22 @@ static const struct BUFFER *read_restart(CONTEXT *ctx)
|
||||
}
|
||||
if (!bad && !ctx->vol)
|
||||
dorest(ctx, 0, &buf->block.restart, TRUE);
|
||||
if ((buf->block.restart.major_ver != const_cpu_to_le16(1))
|
||||
|| (buf->block.restart.minor_ver != const_cpu_to_le16(1))) {
|
||||
printf("** Unsupported $LogFile version %d.%d\n",
|
||||
le16_to_cpu(buf->block.restart.major_ver),
|
||||
le16_to_cpu(buf->block.restart.minor_ver));
|
||||
bad = TRUE;
|
||||
}
|
||||
major = le16_to_cpu(buf->block.restart.major_ver);
|
||||
minor = le16_to_cpu(buf->block.restart.minor_ver);
|
||||
if ((major == 2) && (minor == 0)) {
|
||||
if (!optk) {
|
||||
printf("** Fast restart mode detected,"
|
||||
" data could be lost\n");
|
||||
printf(" Use option --kill-fast-restart"
|
||||
" to bypass\n");
|
||||
bad = TRUE;
|
||||
}
|
||||
} else
|
||||
if ((major != 1) || (minor != 1)) {
|
||||
printf("** Unsupported $LogFile version %d.%d\n",
|
||||
major, minor);
|
||||
bad = TRUE;
|
||||
}
|
||||
if (bad) {
|
||||
buf = (const struct BUFFER*)NULL;
|
||||
}
|
||||
@ -2974,6 +2985,9 @@ static int reset_logfile(CONTEXT *ctx __attribute__((unused)))
|
||||
restart.client_in_use_list = LOGFILE_NO_CLIENT;
|
||||
restart.flags |= RESTART_VOLUME_IS_CLEAN;
|
||||
client.oldest_lsn = cpu_to_sle64(restart_lsn);
|
||||
/* Set $LogFile version to 1.1 so that volume can be mounted */
|
||||
log_header.major_ver = const_cpu_to_le16(1);
|
||||
log_header.minor_ver = const_cpu_to_le16(1);
|
||||
memcpy(buffer, &log_header,
|
||||
sizeof(RESTART_PAGE_HEADER));
|
||||
off = le16_to_cpu(log_header.restart_area_offset);
|
||||
@ -3257,7 +3271,7 @@ static BOOL open_volume(CONTEXT *ctx, const char *device_name)
|
||||
/* Not a log file, assume an ntfs device, mount it */
|
||||
ctx->file = (FILE*)NULL;
|
||||
ctx->vol = ntfs_mount(device_name,
|
||||
((optp || optu || opts) && !optn
|
||||
((optk || optp || optu || opts) && !optn
|
||||
? NTFS_MNT_FORENSIC : NTFS_MNT_RDONLY));
|
||||
if (ctx->vol) {
|
||||
ok = getvolumedata(ctx, boot.buf);
|
||||
@ -3876,6 +3890,7 @@ static void usage(void)
|
||||
fprintf(stderr," -i : show invalid (stale) records\n");
|
||||
fprintf(stderr," -f : show the full log forward\n");
|
||||
fprintf(stderr," -h : show this help information\n");
|
||||
fprintf(stderr," -k : kill fast restart data\n");
|
||||
fprintf(stderr," -n : do not apply any modification\n");
|
||||
fprintf(stderr," -p : undo the latest count transaction sets and play one\n");
|
||||
fprintf(stderr," -r : show a range of log blocks forward\n");
|
||||
@ -3897,12 +3912,13 @@ static BOOL getoptions(int argc, char *argv[])
|
||||
u32 xval;
|
||||
char *endptr;
|
||||
BOOL err;
|
||||
static const char *sopt = "-bc:hifnp:r:stu:vVx:";
|
||||
static const char *sopt = "-bc:hifknp:r:stu:vVx:";
|
||||
static const struct option lopt[] = {
|
||||
{ "backward", no_argument, NULL, 'b' },
|
||||
{ "clusters", required_argument, NULL, 'c' },
|
||||
{ "forward", no_argument, NULL, 'f' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "kill-fast-restart", no_argument, NULL, 'k' },
|
||||
{ "no-action", no_argument, NULL, 'n' },
|
||||
{ "play", required_argument, NULL, 'p' },
|
||||
{ "range", required_argument, NULL, 'r' },
|
||||
@ -3922,6 +3938,7 @@ static BOOL getoptions(int argc, char *argv[])
|
||||
optf = FALSE;
|
||||
opth = FALSE;
|
||||
opti = FALSE;
|
||||
optk = FALSE;
|
||||
optn = FALSE;
|
||||
optp = FALSE;
|
||||
optr = FALSE;
|
||||
@ -3964,6 +3981,9 @@ static BOOL getoptions(int argc, char *argv[])
|
||||
case 'h':
|
||||
opth = TRUE;
|
||||
break;
|
||||
case 'k':
|
||||
optk = TRUE;
|
||||
break;
|
||||
case 'n':
|
||||
optn = TRUE;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user