RW permissions could not be lifted from the preallocation filter if
truncate operation has not been finished. In the other case this would
mean WRITE operation (image truncate) called after the return from
inactivate call. This is definitely a contract violation.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
CC: Kevin Wolf <kwolf@redhat.com>
---
block/preallocate.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/block/preallocate.c b/block/preallocate.c
index d215bc5d6d..1016c511cb 100644
--- a/block/preallocate.c
+++ b/block/preallocate.c
@@ -594,6 +594,17 @@ static void preallocate_child_perm(BlockDriverState *bs, BdrvChild *c,
}
}
+static int preallocate_check_perm(BlockDriverState *bs, uint64_t perm,
+ uint64_t shared, Error **errp)
+{
+ BDRVPreallocateState *s = bs->opaque;
+ if (!can_write_resize(perm) && s->data_end != -EINVAL) {
+ error_setg_errno(errp, EPERM, "Write access is required for truncate");
+ return -EPERM;
+ }
+ return 0;
+}
+
static BlockDriver bdrv_preallocate_filter = {
.format_name = "preallocate",
.instance_size = sizeof(BDRVPreallocateState),
@@ -615,6 +626,7 @@ static BlockDriver bdrv_preallocate_filter = {
.bdrv_set_perm = preallocate_set_perm,
.bdrv_child_perm = preallocate_child_perm,
+ .bdrv_check_perm = preallocate_check_perm,
.is_filter = true,
};
--
2.43.5