diff options
-rw-r--r-- | block/file-posix.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/block/file-posix.c b/block/file-posix.c index e09e15bbf8..d018429672 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2488,6 +2488,8 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, off_t data = 0, hole = 0; int ret; + assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment)); + ret = fd_open(bs); if (ret < 0) { return ret; @@ -2513,6 +2515,20 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, /* On a data extent, compute bytes to the end of the extent, * possibly including a partial sector at EOF. */ *pnum = MIN(bytes, hole - offset); + + /* + * We are not allowed to return partial sectors, though, so + * round up if necessary. + */ + if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) { + int64_t file_length = raw_getlength(bs); + if (file_length > 0) { + /* Ignore errors, this is just a safeguard */ + assert(hole == file_length); + } + *pnum = ROUND_UP(*pnum, bs->bl.request_alignment); + } + ret = BDRV_BLOCK_DATA; } else { /* On a hole, compute bytes to the beginning of the next extent. */ |