@@ -1588,7 +1588,8 @@ enum {
1588
1588
};
1589
1589
1590
1590
/*
1591
- * Fix L2 entry by making it QCOW2_CLUSTER_ZERO_PLAIN.
1591
+ * Fix L2 entry by making it QCOW2_CLUSTER_ZERO_PLAIN (or making all its present
1592
+ * subclusters QCOW2_SUBCLUSTER_ZERO_PLAIN).
1592
1593
*
1593
1594
* This function decrements res->corruptions on success, so the caller is
1594
1595
* responsible to increment res->corruptions prior to the call.
@@ -1605,9 +1606,20 @@ static int fix_l2_entry_by_zero(BlockDriverState *bs, BdrvCheckResult *res,
1605
1606
int idx = l2_index * (l2_entry_size (s ) / sizeof (uint64_t ));
1606
1607
uint64_t l2e_offset = l2_offset + (uint64_t )l2_index * l2_entry_size (s );
1607
1608
int ign = active ? QCOW2_OL_ACTIVE_L2 : QCOW2_OL_INACTIVE_L2 ;
1608
- uint64_t l2_entry = has_subclusters (s ) ? 0 : QCOW_OFLAG_ZERO ;
1609
1609
1610
- set_l2_entry (s , l2_table , l2_index , l2_entry );
1610
+ if (has_subclusters (s )) {
1611
+ uint64_t l2_bitmap = get_l2_bitmap (s , l2_table , l2_index );
1612
+
1613
+ /* Allocated subclusters become zero */
1614
+ l2_bitmap |= l2_bitmap << 32 ;
1615
+ l2_bitmap &= QCOW_L2_BITMAP_ALL_ZEROES ;
1616
+
1617
+ set_l2_bitmap (s , l2_table , l2_index , l2_bitmap );
1618
+ set_l2_entry (s , l2_table , l2_index , 0 );
1619
+ } else {
1620
+ set_l2_entry (s , l2_table , l2_index , QCOW_OFLAG_ZERO );
1621
+ }
1622
+
1611
1623
ret = qcow2_pre_write_overlap_check (bs , ign , l2e_offset , l2_entry_size (s ),
1612
1624
false);
1613
1625
if (metadata_overlap ) {
0 commit comments