Commit e88ae226 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

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: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
parent 1a381811
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -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);
}

/*
+7 −4
Original line number Diff line number Diff line
@@ -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 {