On 10/9/24 4:58 PM, Denis V. Lunev wrote:
> 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 <[email protected]>
> CC: Andrey Drobyshev <[email protected]>
> CC: Vladimir Sementsov-Ogievskiy <[email protected]>
> CC: Kevin Wolf <[email protected]>
> ---
>  block/preallocate.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/block/preallocate.c b/block/preallocate.c
> index bfb638d8b1..1cf854966c 100644
> --- a/block/preallocate.c
> +++ b/block/preallocate.c
> @@ -581,6 +581,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),
> @@ -602,6 +613,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,
>  };

Reviewed-by: Andrey Drobyshev <[email protected]>

Reply via email to