[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(+)
diff --git a/block/io.c b/block/io.c
index 361eeb8..bee6c71 100644
--- a/block/io.c
+++ b/block/io.c
@@ -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) -
--
2.9.3