From 1703eb1c27a6010ff33d5add2d76aadc9b2777bd Mon Sep 17 00:00:00 2001 From: Hanna Czenczek Date: Mon, 27 Feb 2023 11:47:24 +0100 Subject: [PATCH] block/fuse: Let PUNCH_HOLE write zeroes fallocate(2) says about PUNCH_HOLE: "After a successful call, subsequent reads from this range will return zeros." As it is, PUNCH_HOLE is implemented as a call to blk_pdiscard(), which does not guarantee this. We must call blk_pwrite_zeroes() instead. The difference to ZERO_RANGE is that we pass the `BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK` flags to the call -- the storage is supposed to be unmapped, and a slow fallback by actually writing zeroes as data is not allowed. Closes: https://gitlab.com/qemu-project/qemu/-/issues/1507 Signed-off-by: Hanna Czenczek Message-Id: <20230227104725.33511-2-hreitz@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/export/fuse.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index e5fc4af165..06fa41079e 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -673,7 +673,16 @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_t inode, int mode, do { int size = MIN(length, BDRV_REQUEST_MAX_BYTES); - ret = blk_pdiscard(exp->common.blk, offset, size); + ret = blk_pwrite_zeroes(exp->common.blk, offset, size, + BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK); + if (ret == -ENOTSUP) { + /* + * fallocate() specifies to return EOPNOTSUPP for unsupported + * operations + */ + ret = -EOPNOTSUPP; + } + offset += size; length -= size; } while (ret == 0 && length > 0); -- 2.11.0