COW: Extend checking allocated bits to beyond one sector
cow_co_is_allocated() only checks one sector's worth of allocated bits before returning. This is allowed but (slightly) inefficient, so extend it to check all of the file's metadata sectors. Signed-off-by: Charlie Shepherd <charlie@ctshepherd.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> [kwolf: silenced compiler warning (-Wmaybe-uninitialized for changed)] Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									14b98fdaf3
								
							
						
					
					
						commit
						091b1108ca
					
				
							
								
								
									
										36
									
								
								block/cow.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								block/cow.c
									
									
									
									
									
								
							@ -152,18 +152,34 @@ static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs,
 | 
			
		||||
{
 | 
			
		||||
    int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8;
 | 
			
		||||
    uint64_t offset = (bitnum / 8) & -BDRV_SECTOR_SIZE;
 | 
			
		||||
    uint8_t bitmap[BDRV_SECTOR_SIZE];
 | 
			
		||||
    int ret;
 | 
			
		||||
    int changed;
 | 
			
		||||
    bool first = true;
 | 
			
		||||
    int changed = 0, same = 0;
 | 
			
		||||
 | 
			
		||||
    ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    do {
 | 
			
		||||
        int ret;
 | 
			
		||||
        uint8_t bitmap[BDRV_SECTOR_SIZE];
 | 
			
		||||
 | 
			
		||||
    bitnum &= BITS_PER_BITMAP_SECTOR - 1;
 | 
			
		||||
    changed = cow_test_bit(bitnum, bitmap);
 | 
			
		||||
    *num_same = cow_find_streak(bitmap, changed, bitnum, nb_sectors);
 | 
			
		||||
        bitnum &= BITS_PER_BITMAP_SECTOR - 1;
 | 
			
		||||
        int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum);
 | 
			
		||||
 | 
			
		||||
        ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (first) {
 | 
			
		||||
            changed = cow_test_bit(bitnum, bitmap);
 | 
			
		||||
            first = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        same += cow_find_streak(bitmap, changed, bitnum, nb_sectors);
 | 
			
		||||
 | 
			
		||||
        bitnum += sector_bits;
 | 
			
		||||
        nb_sectors -= sector_bits;
 | 
			
		||||
        offset += BDRV_SECTOR_SIZE;
 | 
			
		||||
    } while (nb_sectors);
 | 
			
		||||
 | 
			
		||||
    *num_same = same;
 | 
			
		||||
    return changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user