block: Fix bdrv_is_allocated() for short backing files
bdrv_is_allocated() shouldn't return true for sectors that are unallocated, but after the end of a short backing file, even though such sectors are (correctly) marked as containing zeros. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
		
							
								
								
									
										10
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								block.c
									
									
									
									
									
								
							| @@ -3864,7 +3864,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, | ||||
|  | ||||
|     if (!bs->drv->bdrv_co_get_block_status) { | ||||
|         *pnum = nb_sectors; | ||||
|         ret = BDRV_BLOCK_DATA; | ||||
|         ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED; | ||||
|         if (bs->drv->protocol_name) { | ||||
|             ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE); | ||||
|         } | ||||
| @@ -3883,6 +3883,10 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, | ||||
|                                      *pnum, pnum); | ||||
|     } | ||||
|  | ||||
|     if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) { | ||||
|         ret |= BDRV_BLOCK_ALLOCATED; | ||||
|     } | ||||
|  | ||||
|     if (!(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO)) { | ||||
|         if (bdrv_unallocated_blocks_are_zero(bs)) { | ||||
|             ret |= BDRV_BLOCK_ZERO; | ||||
| @@ -3959,9 +3963,7 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, | ||||
|     if (ret < 0) { | ||||
|         return ret; | ||||
|     } | ||||
|     return | ||||
|         (ret & BDRV_BLOCK_DATA) || | ||||
|         ((ret & BDRV_BLOCK_ZERO) && !bdrv_has_zero_init(bs)); | ||||
|     return (ret & BDRV_BLOCK_ALLOCATED); | ||||
| } | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -120,6 +120,8 @@ typedef enum { | ||||
| /* BDRV_BLOCK_DATA: data is read from bs->file or another file | ||||
|  * BDRV_BLOCK_ZERO: sectors read as zero | ||||
|  * BDRV_BLOCK_OFFSET_VALID: sector stored in bs->file as raw data | ||||
|  * BDRV_BLOCK_ALLOCATED: the content of the block is determined by this | ||||
|  *                       layer (as opposed to the backing file) | ||||
|  * BDRV_BLOCK_RAW: used internally to indicate that the request | ||||
|  *                 was answered by the raw driver and that one | ||||
|  *                 should look in bs->file directly. | ||||
| @@ -141,10 +143,11 @@ typedef enum { | ||||
|  *  f    t        f       not allocated or unknown offset, read as zero | ||||
|  *  f    f        f       not allocated or unknown offset, read from backing_hd | ||||
|  */ | ||||
| #define BDRV_BLOCK_DATA         1 | ||||
| #define BDRV_BLOCK_ZERO         2 | ||||
| #define BDRV_BLOCK_OFFSET_VALID 4 | ||||
| #define BDRV_BLOCK_RAW          8 | ||||
| #define BDRV_BLOCK_DATA         0x01 | ||||
| #define BDRV_BLOCK_ZERO         0x02 | ||||
| #define BDRV_BLOCK_OFFSET_VALID 0x04 | ||||
| #define BDRV_BLOCK_RAW          0x08 | ||||
| #define BDRV_BLOCK_ALLOCATED    0x10 | ||||
| #define BDRV_BLOCK_OFFSET_MASK  BDRV_SECTOR_MASK | ||||
|  | ||||
| typedef enum { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user