Commit 4333bb71 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Stefan Hajnoczi
Browse files

block: define get_block_status return value



Define the return value of get_block_status.  Bits 0, 1, 2 and 9-62
are valid; bit 63 (the sign bit) is reserved for errors.  Bits 3-8
are left for future extensions.

The return code is compatible with the old is_allocated API: if a driver
only returns 0 or 1 (aka BDRV_BLOCK_DATA) like is_allocated used to,
clients of is_allocated will not have any change in behavior.  Still,
we will return more precise information in the next patches and the
new definition of bdrv_is_allocated is already prepared for this.

Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent b6b8a333
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -3093,7 +3093,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,

    if (!bs->drv->bdrv_co_get_block_status) {
        *pnum = nb_sectors;
        return 1;
        return BDRV_BLOCK_DATA;
    }

    return bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum);
@@ -3143,7 +3143,13 @@ int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num,
int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,
                                   int nb_sectors, int *pnum)
{
    return bdrv_get_block_status(bs, sector_num, nb_sectors, pnum);
    int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum);
    if (ret < 0) {
        return ret;
    }
    return
        (ret & BDRV_BLOCK_DATA) ||
        ((ret & BDRV_BLOCK_ZERO) && !bdrv_has_zero_init(bs));
}

/*
+26 −0
Original line number Diff line number Diff line
@@ -81,6 +81,32 @@ typedef struct BlockDevOps {
#define BDRV_SECTOR_SIZE   (1ULL << BDRV_SECTOR_BITS)
#define BDRV_SECTOR_MASK   ~(BDRV_SECTOR_SIZE - 1)

/* 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
 *
 * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 represent the offset in
 * bs->file where sector data can be read from as raw data.
 *
 * DATA == 0 && ZERO == 0 means that data is read from backing_hd if present.
 *
 * DATA ZERO OFFSET_VALID
 *  t    t        t       sectors read as zero, bs->file is zero at offset
 *  t    f        t       sectors read as valid from bs->file at offset
 *  f    t        t       sectors preallocated, read as zero, bs->file not
 *                        necessarily zero at offset
 *  f    f        t       sectors preallocated but read from backing_hd,
 *                        bs->file contains garbage at offset
 *  t    t        f       sectors preallocated, read as zero, unknown offset
 *  t    f        f       sectors read from unknown file or offset
 *  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_OFFSET_MASK  BDRV_SECTOR_MASK

typedef enum {
    BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
} BlockErrorAction;