mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 18:14:24 +08:00
Subdivided the replay functions in playlog
Partially unnested play_redos() and play_undos()
This commit is contained in:
parent
fe3e16243a
commit
22b59548d9
@ -4234,38 +4234,25 @@ static int distribute_redos(ntfs_volume *vol,
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Play the redo actions from earliest to latest
|
||||
*
|
||||
* Currently we can only redo the last undone transaction,
|
||||
* otherwise the attribute table would be out of phase.
|
||||
*/
|
||||
|
||||
int play_redos(ntfs_volume *vol, const struct ACTION_RECORD *firstaction)
|
||||
int play_one_redo(ntfs_volume *vol, const struct ACTION_RECORD *action)
|
||||
{
|
||||
const struct ACTION_RECORD *action;
|
||||
MFT_RECORD *entry;
|
||||
INDEX_BLOCK *indx;
|
||||
char *buffer;
|
||||
s64 this_lsn;
|
||||
s64 data_lsn;
|
||||
u32 xsize;
|
||||
u16 rop;
|
||||
u16 uop;
|
||||
int err;
|
||||
BOOL warn;
|
||||
BOOL executed;
|
||||
enum ACTION_KIND kind;
|
||||
u16 rop;
|
||||
u16 uop;
|
||||
|
||||
err = 0;
|
||||
action = firstaction;
|
||||
while (action && !err) {
|
||||
this_lsn = le64_to_cpu(action->record.this_lsn);
|
||||
/* Only committed actions should be redone */
|
||||
if ((!optc || within_lcn_range(&action->record))
|
||||
&& (action->flags & ACTION_TO_REDO)) {
|
||||
rop = le16_to_cpu(action->record.redo_operation);
|
||||
uop = le16_to_cpu(action->record.undo_operation);
|
||||
this_lsn = le64_to_cpu(action->record.this_lsn);
|
||||
if (optv)
|
||||
printf("Redo action %d %s (%s) 0x%llx\n",
|
||||
action->num,
|
||||
@ -4364,17 +4351,14 @@ printf("** %s (action %d) not acting on MFT\n",actionname(rop),(int)action->num)
|
||||
* have a stale lsn (consequence
|
||||
* of ntfs-3g resetting the log)
|
||||
*/
|
||||
executed = ((s64)(data_lsn
|
||||
- this_lsn) >= 0)
|
||||
&& (((s64)(data_lsn
|
||||
- latest_lsn)) <= 0)
|
||||
executed = ((s64)(data_lsn - this_lsn) >= 0)
|
||||
&& (((s64)(data_lsn - latest_lsn)) <= 0)
|
||||
&& !exception(action->num);
|
||||
} else {
|
||||
if (!warn) {
|
||||
/* Old record not needed */
|
||||
if (!buffer)
|
||||
buffer =
|
||||
(char*)malloc(mftrecsz);
|
||||
buffer = (char*)calloc(1, mftrecsz);
|
||||
if (buffer)
|
||||
executed = FALSE;
|
||||
else
|
||||
@ -4409,17 +4393,14 @@ printf("** %s (action %d) not acting on INDX\n",actionname(rop),(int)action->num
|
||||
* have a stale lsn (consequence
|
||||
* of ntfs-3g resetting the log)
|
||||
*/
|
||||
executed = ((s64)(data_lsn
|
||||
- this_lsn) >= 0)
|
||||
&& (((s64)(data_lsn
|
||||
- latest_lsn)) <= 0)
|
||||
executed = ((s64)(data_lsn - this_lsn) >= 0)
|
||||
&& (((s64)(data_lsn - latest_lsn)) <= 0)
|
||||
&& ! exception(action->num);
|
||||
} else {
|
||||
if (!warn) {
|
||||
/* Old record not needed */
|
||||
if (!buffer)
|
||||
buffer =
|
||||
(char*)malloc(xsize);
|
||||
buffer = (char*)calloc(1, xsize);
|
||||
if (buffer)
|
||||
executed = FALSE;
|
||||
else
|
||||
@ -4435,8 +4416,7 @@ printf("** %s (action %d) not acting on INDX\n",actionname(rop),(int)action->num
|
||||
break;
|
||||
case ON_RAW :
|
||||
if (action->record.attribute_flags
|
||||
& (const_cpu_to_le16(
|
||||
ACTS_ON_INDX | ACTS_ON_MFT))) {
|
||||
& (const_cpu_to_le16(ACTS_ON_INDX | ACTS_ON_MFT))) {
|
||||
printf("** Error : action %s on MFT"
|
||||
" or INDX\n",
|
||||
actionname(rop));
|
||||
@ -4463,7 +4443,29 @@ printf("** %s (action %d) not acting on INDX\n",actionname(rop),(int)action->num
|
||||
}
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Play the redo actions from earliest to latest
|
||||
*
|
||||
* Currently we can only redo the last undone transaction,
|
||||
* otherwise the attribute table would be out of phase.
|
||||
*/
|
||||
|
||||
int play_redos(ntfs_volume *vol, const struct ACTION_RECORD *firstaction)
|
||||
{
|
||||
const struct ACTION_RECORD *action;
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
action = firstaction;
|
||||
while (action && !err) {
|
||||
/* Only committed actions should be redone */
|
||||
if ((!optc || within_lcn_range(&action->record))
|
||||
&& (action->flags & ACTION_TO_REDO))
|
||||
err = play_one_redo(vol, action);
|
||||
if (!err)
|
||||
action = action->next;
|
||||
}
|
||||
@ -4616,19 +4618,8 @@ static int distribute_undos(ntfs_volume *vol, const struct ACTION_RECORD *action
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Play the undo actions from latest to earliest
|
||||
*
|
||||
* For structured record, a check is made on the lsn to only
|
||||
* try to undo the actions which were executed. This implies
|
||||
* identifying actions on a structured record.
|
||||
*
|
||||
* Returns 0 if successful
|
||||
*/
|
||||
|
||||
int play_undos(ntfs_volume *vol, const struct ACTION_RECORD *lastaction)
|
||||
int play_one_undo(ntfs_volume *vol, const struct ACTION_RECORD *action)
|
||||
{
|
||||
const struct ACTION_RECORD *action;
|
||||
MFT_RECORD *entry;
|
||||
INDEX_BLOCK *indx;
|
||||
char *buffer;
|
||||
@ -4640,9 +4631,6 @@ int play_undos(ntfs_volume *vol, const struct ACTION_RECORD *lastaction)
|
||||
enum ACTION_KIND kind;
|
||||
|
||||
err = 0;
|
||||
action = lastaction;
|
||||
while (action && !err) {
|
||||
if (!optc || within_lcn_range(&action->record)) {
|
||||
rop = le16_to_cpu(action->record.redo_operation);
|
||||
uop = le16_to_cpu(action->record.undo_operation);
|
||||
if (optv)
|
||||
@ -4724,8 +4712,7 @@ int play_undos(ntfs_volume *vol, const struct ACTION_RECORD *lastaction)
|
||||
if (!(action->record.attribute_flags & const_cpu_to_le16(ACTS_ON_MFT)))
|
||||
printf("** %s (action %d) not acting on MFT\n",actionname(rop),(int)action->num);
|
||||
*/
|
||||
buffer = read_protected(vol, &action->record,
|
||||
mftrecsz, TRUE);
|
||||
buffer = read_protected(vol, &action->record, mftrecsz, TRUE);
|
||||
entry = (MFT_RECORD*)buffer;
|
||||
if (entry) {
|
||||
if (entry->magic == magic_FILE) {
|
||||
@ -4741,16 +4728,15 @@ printf("record lsn 0x%llx is %s than action %d lsn 0x%llx\n",
|
||||
(int)action->num,
|
||||
(long long)le64_to_cpu(action->record.this_lsn));
|
||||
} else {
|
||||
printf("** %s (action %d) not"
|
||||
" acting on MFT\n",
|
||||
actionname(rop),
|
||||
(int)action->num);
|
||||
printf("** %s (action %d) not acting on MFT\n",
|
||||
actionname(rop), (int)action->num);
|
||||
err = 1;
|
||||
}
|
||||
} else {
|
||||
/* Undoing a record create which was not done ? */
|
||||
// TODO make sure this is about a newly allocated record (with bad fixup)
|
||||
// TODO check this is inputting a full record (record lth == data lth)
|
||||
buffer = (char*)malloc(mftrecsz);
|
||||
buffer = (char*)calloc(1, mftrecsz);
|
||||
}
|
||||
break;
|
||||
case ON_INDX :
|
||||
@ -4760,8 +4746,7 @@ if (!(action->record.attribute_flags & const_cpu_to_le16(ACTS_ON_INDX)))
|
||||
printf("** %s (action %d) not acting on INDX\n",actionname(rop),(int)action->num);
|
||||
*/
|
||||
xsize = vol->indx_record_size;
|
||||
buffer = read_protected(vol, &action->record,
|
||||
xsize, TRUE);
|
||||
buffer = read_protected(vol, &action->record, xsize, TRUE);
|
||||
indx = (INDEX_BLOCK*)buffer;
|
||||
if (indx) {
|
||||
if (indx->magic == magic_INDX) {
|
||||
@ -4777,27 +4762,24 @@ printf("index lsn 0x%llx is %s than action %d lsn 0x%llx\n",
|
||||
(int)action->num,
|
||||
(long long)le64_to_cpu(action->record.this_lsn));
|
||||
} else {
|
||||
printf("** %s (action %d) not"
|
||||
" acting on INDX\n",
|
||||
actionname(rop),
|
||||
(int)action->num);
|
||||
printf("** %s (action %d) not acting on INDX\n",
|
||||
actionname(rop), (int)action->num);
|
||||
err = 1;
|
||||
}
|
||||
} else {
|
||||
/* Undoing a record create which was not done ? */
|
||||
// TODO make sure this is about a newly allocated record (with bad fixup)
|
||||
// TODO check this is inputting a full record (record lth == data lth)
|
||||
// recreate an INDX record if this is the first entry
|
||||
buffer = (char*)malloc(xsize);
|
||||
buffer = (char*)calloc(1, xsize);
|
||||
err = create_indx(vol, action, buffer);
|
||||
executed = TRUE;
|
||||
}
|
||||
break;
|
||||
case ON_RAW :
|
||||
if (action->record.attribute_flags
|
||||
& (const_cpu_to_le16(
|
||||
ACTS_ON_INDX | ACTS_ON_MFT))) {
|
||||
printf("** Error : action %s on MFT"
|
||||
" or INDX\n",
|
||||
& (const_cpu_to_le16(ACTS_ON_INDX | ACTS_ON_MFT))) {
|
||||
printf("** Error : action %s on MFT or INDX\n",
|
||||
actionname(rop));
|
||||
err = 1;
|
||||
} else {
|
||||
@ -4818,7 +4800,30 @@ printf("index lsn 0x%llx is %s than action %d lsn 0x%llx\n",
|
||||
}
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Play the undo actions from latest to earliest
|
||||
*
|
||||
* For structured record, a check is made on the lsn to only
|
||||
* try to undo the actions which were executed. This implies
|
||||
* identifying actions on a structured record.
|
||||
*
|
||||
* Returns 0 if successful
|
||||
*/
|
||||
|
||||
int play_undos(ntfs_volume *vol, const struct ACTION_RECORD *lastaction)
|
||||
{
|
||||
const struct ACTION_RECORD *action;
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
action = lastaction;
|
||||
while (action && !err) {
|
||||
if (!optc || within_lcn_range(&action->record))
|
||||
err = play_one_undo(vol, action);
|
||||
if (!err)
|
||||
action = action->prev;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user