diff options
Diffstat (limited to 'fs/ntfs/logfile.c')
| -rw-r--r-- | fs/ntfs/logfile.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c index 0173e95500d9..0fd70295cca6 100644 --- a/fs/ntfs/logfile.c +++ b/fs/ntfs/logfile.c | |||
| @@ -51,7 +51,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
| 51 | RESTART_PAGE_HEADER *rp, s64 pos) | 51 | RESTART_PAGE_HEADER *rp, s64 pos) |
| 52 | { | 52 | { |
| 53 | u32 logfile_system_page_size, logfile_log_page_size; | 53 | u32 logfile_system_page_size, logfile_log_page_size; |
| 54 | u16 usa_count, usa_ofs, usa_end, ra_ofs; | 54 | u16 ra_ofs, usa_count, usa_ofs, usa_end = 0; |
| 55 | BOOL have_usa = TRUE; | ||
| 55 | 56 | ||
| 56 | ntfs_debug("Entering."); | 57 | ntfs_debug("Entering."); |
| 57 | /* | 58 | /* |
| @@ -86,6 +87,14 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
| 86 | (int)sle16_to_cpu(rp->minor_ver)); | 87 | (int)sle16_to_cpu(rp->minor_ver)); |
| 87 | return FALSE; | 88 | return FALSE; |
| 88 | } | 89 | } |
| 90 | /* | ||
| 91 | * If chkdsk has been run the restart page may not be protected by an | ||
| 92 | * update sequence array. | ||
| 93 | */ | ||
| 94 | if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) { | ||
| 95 | have_usa = FALSE; | ||
| 96 | goto skip_usa_checks; | ||
| 97 | } | ||
| 89 | /* Verify the size of the update sequence array. */ | 98 | /* Verify the size of the update sequence array. */ |
| 90 | usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS); | 99 | usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS); |
| 91 | if (usa_count != le16_to_cpu(rp->usa_count)) { | 100 | if (usa_count != le16_to_cpu(rp->usa_count)) { |
| @@ -102,6 +111,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
| 102 | "inconsistent update sequence array offset."); | 111 | "inconsistent update sequence array offset."); |
| 103 | return FALSE; | 112 | return FALSE; |
| 104 | } | 113 | } |
| 114 | skip_usa_checks: | ||
| 105 | /* | 115 | /* |
| 106 | * Verify the position of the restart area. It must be: | 116 | * Verify the position of the restart area. It must be: |
| 107 | * - aligned to 8-byte boundary, | 117 | * - aligned to 8-byte boundary, |
| @@ -109,7 +119,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
| 109 | * - within the system page size. | 119 | * - within the system page size. |
| 110 | */ | 120 | */ |
| 111 | ra_ofs = le16_to_cpu(rp->restart_area_offset); | 121 | ra_ofs = le16_to_cpu(rp->restart_area_offset); |
| 112 | if (ra_ofs & 7 || ra_ofs < usa_end || | 122 | if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end : |
| 123 | ra_ofs < sizeof(RESTART_PAGE_HEADER)) || | ||
| 113 | ra_ofs > logfile_system_page_size) { | 124 | ra_ofs > logfile_system_page_size) { |
| 114 | ntfs_error(vi->i_sb, "$LogFile restart page specifies " | 125 | ntfs_error(vi->i_sb, "$LogFile restart page specifies " |
| 115 | "inconsistent restart area offset."); | 126 | "inconsistent restart area offset."); |
| @@ -402,8 +413,12 @@ static int ntfs_check_and_load_restart_page(struct inode *vi, | |||
| 402 | idx++; | 413 | idx++; |
| 403 | } while (to_read > 0); | 414 | } while (to_read > 0); |
| 404 | } | 415 | } |
| 405 | /* Perform the multi sector transfer deprotection on the buffer. */ | 416 | /* |
| 406 | if (post_read_mst_fixup((NTFS_RECORD*)trp, | 417 | * Perform the multi sector transfer deprotection on the buffer if the |
| 418 | * restart page is protected. | ||
| 419 | */ | ||
| 420 | if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count)) | ||
| 421 | && post_read_mst_fixup((NTFS_RECORD*)trp, | ||
| 407 | le32_to_cpu(rp->system_page_size))) { | 422 | le32_to_cpu(rp->system_page_size))) { |
| 408 | /* | 423 | /* |
| 409 | * A multi sector tranfer error was detected. We only need to | 424 | * A multi sector tranfer error was detected. We only need to |
| @@ -615,11 +630,16 @@ is_empty: | |||
| 615 | * Otherwise just throw it away. | 630 | * Otherwise just throw it away. |
| 616 | */ | 631 | */ |
| 617 | if (rstr2_lsn > rstr1_lsn) { | 632 | if (rstr2_lsn > rstr1_lsn) { |
| 633 | ntfs_debug("Using second restart page as it is more " | ||
| 634 | "recent."); | ||
| 618 | ntfs_free(rstr1_ph); | 635 | ntfs_free(rstr1_ph); |
| 619 | rstr1_ph = rstr2_ph; | 636 | rstr1_ph = rstr2_ph; |
| 620 | /* rstr1_lsn = rstr2_lsn; */ | 637 | /* rstr1_lsn = rstr2_lsn; */ |
| 621 | } else | 638 | } else { |
| 639 | ntfs_debug("Using first restart page as it is more " | ||
| 640 | "recent."); | ||
| 622 | ntfs_free(rstr2_ph); | 641 | ntfs_free(rstr2_ph); |
| 642 | } | ||
| 623 | rstr2_ph = NULL; | 643 | rstr2_ph = NULL; |
| 624 | } | 644 | } |
| 625 | /* All consistency checks passed. */ | 645 | /* All consistency checks passed. */ |
