NTFS: More $LogFile handling fixes: when chkdsk has been run, it can leave the

restart pages in the journal without multi sector transfer protection
      fixups (i.e. the update sequence array is empty and in fact does not
      exist).

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
This commit is contained in:
Anton Altaparmakov
2005-09-26 10:48:54 +01:00
parent 838bf9675a
commit 5a8c0cc32b
3 changed files with 35 additions and 15 deletions

View File

@@ -51,7 +51,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
RESTART_PAGE_HEADER *rp, s64 pos)
{
u32 logfile_system_page_size, logfile_log_page_size;
u16 usa_count, usa_ofs, usa_end, ra_ofs;
u16 ra_ofs, usa_count, usa_ofs, usa_end = 0;
BOOL have_usa = TRUE;
ntfs_debug("Entering.");
/*
@@ -86,6 +87,14 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
(int)sle16_to_cpu(rp->minor_ver));
return FALSE;
}
/*
* If chkdsk has been run the restart page may not be protected by an
* update sequence array.
*/
if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) {
have_usa = FALSE;
goto skip_usa_checks;
}
/* Verify the size of the update sequence array. */
usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS);
if (usa_count != le16_to_cpu(rp->usa_count)) {
@@ -102,6 +111,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
"inconsistent update sequence array offset.");
return FALSE;
}
skip_usa_checks:
/*
* Verify the position of the restart area. It must be:
* - aligned to 8-byte boundary,
@@ -109,7 +119,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
* - within the system page size.
*/
ra_ofs = le16_to_cpu(rp->restart_area_offset);
if (ra_ofs & 7 || ra_ofs < usa_end ||
if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end :
ra_ofs < sizeof(RESTART_PAGE_HEADER)) ||
ra_ofs > logfile_system_page_size) {
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
"inconsistent restart area offset.");
@@ -402,8 +413,12 @@ static int ntfs_check_and_load_restart_page(struct inode *vi,
idx++;
} while (to_read > 0);
}
/* Perform the multi sector transfer deprotection on the buffer. */
if (post_read_mst_fixup((NTFS_RECORD*)trp,
/*
* Perform the multi sector transfer deprotection on the buffer if the
* restart page is protected.
*/
if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count))
&& post_read_mst_fixup((NTFS_RECORD*)trp,
le32_to_cpu(rp->system_page_size))) {
/*
* A multi sector tranfer error was detected. We only need to
@@ -615,11 +630,16 @@ is_empty:
* Otherwise just throw it away.
*/
if (rstr2_lsn > rstr1_lsn) {
ntfs_debug("Using second restart page as it is more "
"recent.");
ntfs_free(rstr1_ph);
rstr1_ph = rstr2_ph;
/* rstr1_lsn = rstr2_lsn; */
} else
} else {
ntfs_debug("Using first restart page as it is more "
"recent.");
ntfs_free(rstr2_ph);
}
rstr2_ph = NULL;
}
/* All consistency checks passed. */