@@ -1769,6 +1769,14 @@ static int64_t coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
bs->bl.request_alignment) - aligned_offset;
ret = bs->drv->bdrv_co_block_status(bs, aligned_offset, aligned_bytes,
&n, file);
+
+ /* total_size is always sector-aligned, by sometimes exceeding actual
+ * file size. Expand n if it lands mid-sector due to end-of-file. */
+ if (ret >= 0 && QEMU_ALIGN_UP(n + aligned_offset,
+ BDRV_SECTOR_SIZE) == total_size) {
+ n = total_size - aligned_offset;
+ }
+
/* Clamp pnum and ret to original request */
if (aligned_offset != offset && ret >= 0) {
int sectors = DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) -
[adjust a paragraph of the original commit message] ... Note that we have an inherent limitation in the BDRV_BLOCK_* return values: BDRV_BLOCK_OFFSET_VALID can only return the start of a sector, even if we later relax the interface to query for the status starting at an intermediate byte; document the obvious interpretation that valid offsets are always sector-relative. Furthermore, note that many callers are expecting sector-aligned answers, especially since bdrv_getlength() is sector-aligned even when it exceeds the actual file size; so we intentionally lie and state that any partial sector at the end of a file has the same status for the entire sector, rather than a literal interpretation of a hole starting at a mid-sector location due to end-of-file. ... Signed-off-by: Eric Blake <eblake@redhat.com> --- This was sufficient to avoid failure of qemu-iotests 109 after patch 13/31 adjusts file-posix.c to clamp EOF numbers to mid-sector locations. block/io.c | 8 ++++++++ 1 file changed, 8 insertions(+)