block: Add BDRV_BLOCK_EOF to bdrv_get_block_status()

Just as the block layer already sets BDRV_BLOCK_ALLOCATED as a
shortcut for subsequent operations, there are also some optimizations
that are made easier if we can quickly tell that *pnum will advance
us to the end of a file, via a new BDRV_BLOCK_EOF which gets set
by the block layer.

This just plumbs up the new bit; subsequent patches will make use
of it.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170505021500.19315-2-eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
This commit is contained in:
Eric Blake 2017-05-04 21:14:59 -05:00 committed by Fam Zheng
parent 36f87b4513
commit fb0d8654ff
2 changed files with 13 additions and 4 deletions

View File

@ -1711,15 +1711,16 @@ typedef struct BdrvCoGetBlockStatusData {
* Drivers not implementing the functionality are assumed to not support * Drivers not implementing the functionality are assumed to not support
* backing files, hence all their sectors are reported as allocated. * backing files, hence all their sectors are reported as allocated.
* *
* If 'sector_num' is beyond the end of the disk image the return value is 0 * If 'sector_num' is beyond the end of the disk image the return value is
* and 'pnum' is set to 0. * BDRV_BLOCK_EOF and 'pnum' is set to 0.
* *
* 'pnum' is set to the number of sectors (including and immediately following * 'pnum' is set to the number of sectors (including and immediately following
* the specified sector) that are known to be in the same * the specified sector) that are known to be in the same
* allocated/unallocated state. * allocated/unallocated state.
* *
* 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
* beyond the end of the disk image it will be clamped. * beyond the end of the disk image it will be clamped; if 'pnum' is set to
* the end of the image, then the returned value will include BDRV_BLOCK_EOF.
* *
* If returned value is positive and BDRV_BLOCK_OFFSET_VALID bit is set, 'file' * If returned value is positive and BDRV_BLOCK_OFFSET_VALID bit is set, 'file'
* points to the BDS which the sector range is allocated in. * points to the BDS which the sector range is allocated in.
@ -1740,7 +1741,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
if (sector_num >= total_sectors) { if (sector_num >= total_sectors) {
*pnum = 0; *pnum = 0;
return 0; return BDRV_BLOCK_EOF;
} }
n = total_sectors - sector_num; n = total_sectors - sector_num;
@ -1751,6 +1752,9 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
if (!bs->drv->bdrv_co_get_block_status) { if (!bs->drv->bdrv_co_get_block_status) {
*pnum = nb_sectors; *pnum = nb_sectors;
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED; ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
if (sector_num + nb_sectors == total_sectors) {
ret |= BDRV_BLOCK_EOF;
}
if (bs->drv->protocol_name) { if (bs->drv->protocol_name) {
ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE); ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
} }
@ -1814,6 +1818,9 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
out: out:
bdrv_dec_in_flight(bs); bdrv_dec_in_flight(bs);
if (ret >= 0 && sector_num + *pnum == total_sectors) {
ret |= BDRV_BLOCK_EOF;
}
return ret; return ret;
} }

View File

@ -129,6 +129,7 @@ typedef struct HDGeometry {
* BDRV_BLOCK_OFFSET_VALID: an associated offset exists for accessing raw data * BDRV_BLOCK_OFFSET_VALID: an associated offset exists for accessing raw data
* BDRV_BLOCK_ALLOCATED: the content of the block is determined by this * BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
* layer (short for DATA || ZERO), set by block layer * layer (short for DATA || ZERO), set by block layer
* BDRV_BLOCK_EOF: the returned pnum covers through end of file for this layer
* *
* Internal flag: * Internal flag:
* BDRV_BLOCK_RAW: used internally to indicate that the request was * BDRV_BLOCK_RAW: used internally to indicate that the request was
@ -157,6 +158,7 @@ typedef struct HDGeometry {
#define BDRV_BLOCK_OFFSET_VALID 0x04 #define BDRV_BLOCK_OFFSET_VALID 0x04
#define BDRV_BLOCK_RAW 0x08 #define BDRV_BLOCK_RAW 0x08
#define BDRV_BLOCK_ALLOCATED 0x10 #define BDRV_BLOCK_ALLOCATED 0x10
#define BDRV_BLOCK_EOF 0x20
#define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK #define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK
typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue; typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;