|
@@ -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. */
|