@@ -1202,17 +1202,14 @@ static bool __must_check is_valid_recovery_journal_block(const struct recovery_j
12021202 * @journal: The journal to use.
12031203 * @header: The unpacked block header to check.
12041204 * @sequence: The expected sequence number.
1205- * @type: The expected metadata type.
12061205 *
12071206 * Return: True if the block matches.
12081207 */
12091208static bool __must_check is_exact_recovery_journal_block (const struct recovery_journal * journal ,
12101209 const struct recovery_block_header * header ,
1211- sequence_number_t sequence ,
1212- enum vdo_metadata_type type )
1210+ sequence_number_t sequence )
12131211{
1214- return ((header -> metadata_type == type ) &&
1215- (header -> sequence_number == sequence ) &&
1212+ return ((header -> sequence_number == sequence ) &&
12161213 (is_valid_recovery_journal_block (journal , header , true)));
12171214}
12181215
@@ -1371,7 +1368,8 @@ static void extract_entries_from_block(struct repair_completion *repair,
13711368 get_recovery_journal_block_header (journal , repair -> journal_data ,
13721369 sequence );
13731370
1374- if (!is_exact_recovery_journal_block (journal , & header , sequence , format )) {
1371+ if (!is_exact_recovery_journal_block (journal , & header , sequence ) ||
1372+ (header .metadata_type != format )) {
13751373 /* This block is invalid, so skip it. */
13761374 return ;
13771375 }
@@ -1557,10 +1555,13 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
15571555 sequence_number_t i , head ;
15581556 bool found_entries = false;
15591557 struct recovery_journal * journal = repair -> completion .vdo -> recovery_journal ;
1558+ struct recovery_block_header header ;
1559+ enum vdo_metadata_type expected_format ;
15601560
15611561 head = min (repair -> block_map_head , repair -> slab_journal_head );
1562+ header = get_recovery_journal_block_header (journal , repair -> journal_data , head );
1563+ expected_format = header .metadata_type ;
15621564 for (i = head ; i <= repair -> highest_tail ; i ++ ) {
1563- struct recovery_block_header header ;
15641565 journal_entry_count_t block_entries ;
15651566 u8 j ;
15661567
@@ -1572,17 +1573,15 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
15721573 };
15731574
15741575 header = get_recovery_journal_block_header (journal , repair -> journal_data , i );
1575- if (header .metadata_type == VDO_METADATA_RECOVERY_JOURNAL ) {
1576- /* This is an old format block, so we need to upgrade */
1577- vdo_log_error_strerror (VDO_UNSUPPORTED_VERSION ,
1578- "Recovery journal is in the old format. Downgrade and complete recovery, then upgrade with a clean volume" );
1579- return VDO_UNSUPPORTED_VERSION ;
1580- }
1581-
1582- if (!is_exact_recovery_journal_block (journal , & header , i ,
1583- VDO_METADATA_RECOVERY_JOURNAL_2 )) {
1576+ if (!is_exact_recovery_journal_block (journal , & header , i )) {
15841577 /* A bad block header was found so this must be the end of the journal. */
15851578 break ;
1579+ } else if (header .metadata_type != expected_format ) {
1580+ /* There is a mix of old and new format blocks, so we need to rebuild. */
1581+ vdo_log_error_strerror (VDO_CORRUPT_JOURNAL ,
1582+ "Recovery journal is in an invalid format, a read-only rebuild is required." );
1583+ vdo_enter_read_only_mode (repair -> completion .vdo , VDO_CORRUPT_JOURNAL );
1584+ return VDO_CORRUPT_JOURNAL ;
15861585 }
15871586
15881587 block_entries = header .entry_count ;
@@ -1618,8 +1617,14 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
16181617 break ;
16191618 }
16201619
1621- if (!found_entries )
1620+ if (!found_entries ) {
16221621 return validate_heads (repair );
1622+ } else if (expected_format == VDO_METADATA_RECOVERY_JOURNAL ) {
1623+ /* All journal blocks have the old format, so we need to upgrade. */
1624+ vdo_log_error_strerror (VDO_UNSUPPORTED_VERSION ,
1625+ "Recovery journal is in the old format. Downgrade and complete recovery, then upgrade with a clean volume" );
1626+ return VDO_UNSUPPORTED_VERSION ;
1627+ }
16231628
16241629 /* Set the tail to the last valid tail block, if there is one. */
16251630 if (repair -> tail_recovery_point .sector_count == 0 )
0 commit comments