@@ -1202,17 +1202,14 @@ static bool __must_check is_valid_recovery_journal_block(const struct recovery_j
1202
1202
* @journal: The journal to use.
1203
1203
* @header: The unpacked block header to check.
1204
1204
* @sequence: The expected sequence number.
1205
- * @type: The expected metadata type.
1206
1205
*
1207
1206
* Return: True if the block matches.
1208
1207
*/
1209
1208
static bool __must_check is_exact_recovery_journal_block (const struct recovery_journal * journal ,
1210
1209
const struct recovery_block_header * header ,
1211
- sequence_number_t sequence ,
1212
- enum vdo_metadata_type type )
1210
+ sequence_number_t sequence )
1213
1211
{
1214
- return ((header -> metadata_type == type ) &&
1215
- (header -> sequence_number == sequence ) &&
1212
+ return ((header -> sequence_number == sequence ) &&
1216
1213
(is_valid_recovery_journal_block (journal , header , true)));
1217
1214
}
1218
1215
@@ -1371,7 +1368,8 @@ static void extract_entries_from_block(struct repair_completion *repair,
1371
1368
get_recovery_journal_block_header (journal , repair -> journal_data ,
1372
1369
sequence );
1373
1370
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 )) {
1375
1373
/* This block is invalid, so skip it. */
1376
1374
return ;
1377
1375
}
@@ -1557,10 +1555,13 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
1557
1555
sequence_number_t i , head ;
1558
1556
bool found_entries = false;
1559
1557
struct recovery_journal * journal = repair -> completion .vdo -> recovery_journal ;
1558
+ struct recovery_block_header header ;
1559
+ enum vdo_metadata_type expected_format ;
1560
1560
1561
1561
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 ;
1562
1564
for (i = head ; i <= repair -> highest_tail ; i ++ ) {
1563
- struct recovery_block_header header ;
1564
1565
journal_entry_count_t block_entries ;
1565
1566
u8 j ;
1566
1567
@@ -1572,17 +1573,15 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
1572
1573
};
1573
1574
1574
1575
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 )) {
1584
1577
/* A bad block header was found so this must be the end of the journal. */
1585
1578
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 ;
1586
1585
}
1587
1586
1588
1587
block_entries = header .entry_count ;
@@ -1618,8 +1617,14 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
1618
1617
break ;
1619
1618
}
1620
1619
1621
- if (!found_entries )
1620
+ if (!found_entries ) {
1622
1621
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
+ }
1623
1628
1624
1629
/* Set the tail to the last valid tail block, if there is one. */
1625
1630
if (repair -> tail_recovery_point .sector_count == 0 )
0 commit comments