@ -1177,11 +1177,11 @@ void qcow2_free_any_cluster(BlockDriverState *bs, uint64_t l2_entry,
switch ( ctype ) {
switch ( ctype ) {
case QCOW2_CLUSTER_COMPRESSED :
case QCOW2_CLUSTER_COMPRESSED :
{
{
int64_t offset = ( l2_entry & s - > cluster_offset_mask )
uint64_t coffset ;
& QCOW2_COMPRESSED_SECTOR_MASK ;
int csize ;
int size = QCOW2_COMPRESSED_SECTOR_SIZE *
( ( ( l2_entry > > s - > csize_shift ) & s - > csize_mask ) + 1 ) ;
qcow2_parse_compressed_l2_entry ( bs , l2_entry , & coffset , & csize ) ;
qcow2_free_clusters ( bs , offset , size , type ) ;
qcow2_free_clusters ( bs , c offset, c size, type ) ;
}
}
break ;
break ;
case QCOW2_CLUSTER_NORMAL :
case QCOW2_CLUSTER_NORMAL :
@ -1247,7 +1247,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
bool l1_allocated = false ;
bool l1_allocated = false ;
int64_t old_entry , old_l2_offset ;
int64_t old_entry , old_l2_offset ;
unsigned slice , slice_size2 , n_slices ;
unsigned slice , slice_size2 , n_slices ;
int i , j , l1_modified = 0 , nb_csectors ;
int i , j , l1_modified = 0 ;
int ret ;
int ret ;
assert ( addend > = - 1 & & addend < = 1 ) ;
assert ( addend > = - 1 & & addend < = 1 ) ;
@ -1318,14 +1318,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
switch ( qcow2_get_cluster_type ( bs , entry ) ) {
switch ( qcow2_get_cluster_type ( bs , entry ) ) {
case QCOW2_CLUSTER_COMPRESSED :
case QCOW2_CLUSTER_COMPRESSED :
nb_csectors = ( ( entry > > s - > csize_shift ) &
s - > csize_mask ) + 1 ;
if ( addend ! = 0 ) {
if ( addend ! = 0 ) {
uint64_t coffset = ( entry & s - > cluster_offset_mask )
uint64_t coffset ;
& QCOW2_COMPRESSED_SECTOR_MASK ;
int csize ;
qcow2_parse_compressed_l2_entry ( bs , entry ,
& coffset , & csize ) ;
ret = update_refcount (
ret = update_refcount (
bs , coffset ,
bs , coffset , csize ,
nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE ,
abs ( addend ) , addend < 0 ,
abs ( addend ) , addend < 0 ,
QCOW2_DISCARD_SNAPSHOT ) ;
QCOW2_DISCARD_SNAPSHOT ) ;
if ( ret < 0 ) {
if ( ret < 0 ) {
@ -1603,7 +1603,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
BDRVQcow2State * s = bs - > opaque ;
BDRVQcow2State * s = bs - > opaque ;
uint64_t l2_entry ;
uint64_t l2_entry ;
uint64_t next_contiguous_offset = 0 ;
uint64_t next_contiguous_offset = 0 ;
int i , nb_csectors , ret ;
int i , ret ;
size_t l2_size_bytes = s - > l2_size * l2_entry_size ( s ) ;
size_t l2_size_bytes = s - > l2_size * l2_entry_size ( s ) ;
g_autofree uint64_t * l2_table = g_malloc ( l2_size_bytes ) ;
g_autofree uint64_t * l2_table = g_malloc ( l2_size_bytes ) ;
@ -1617,6 +1617,8 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
/* Do the actual checks */
/* Do the actual checks */
for ( i = 0 ; i < s - > l2_size ; i + + ) {
for ( i = 0 ; i < s - > l2_size ; i + + ) {
uint64_t coffset ;
int csize ;
l2_entry = get_l2_entry ( s , l2_table , i ) ;
l2_entry = get_l2_entry ( s , l2_table , i ) ;
switch ( qcow2_get_cluster_type ( bs , l2_entry ) ) {
switch ( qcow2_get_cluster_type ( bs , l2_entry ) ) {
@ -1638,13 +1640,9 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
}
}
/* Mark cluster as used */
/* Mark cluster as used */
nb_csectors = ( ( l2_entry > > s - > csize_shift ) &
qcow2_parse_compressed_l2_entry ( bs , l2_entry , & coffset , & csize ) ;
s - > csize_mask ) + 1 ;
l2_entry & = s - > cluster_offset_mask ;
ret = qcow2_inc_refcounts_imrt (
ret = qcow2_inc_refcounts_imrt (
bs , res , refcount_table , refcount_table_size ,
bs , res , refcount_table , refcount_table_size , coffset , csize ) ;
l2_entry & QCOW2_COMPRESSED_SECTOR_MASK ,
nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE ) ;
if ( ret < 0 ) {
if ( ret < 0 ) {
return ret ;
return ret ;
}
}