> 
> Notably absent: qapi/block-core.json. Without changing this, the option can't 
> be
> available in -blockdev, which is the primary option to configure block device
> backends.
> 
> This patch seems to contain multiple logical changes that should be split into
> separate patches:
> 
> * Adding a flags parameter to .bdrv_co_pdiscard
> 
> * Support for the new feature in the core block layer (should be done
>   with -blockdev)
> 
> * Convenience magic for -drive (BDRV_O_SECDISCARD). It's not clear that
>   this should be done at all because the option is really specific to
>   one single block driver (file-posix). I think in your patch, all
>   other block drivers silently ignore the option, which is not what we
>   want.
Sorry for the absent for -blockdev. Will try add that.
Also I will try to split the patches.
And for the BDRV_O_SECDISCARD, it is specific for file-posix.c(host_device). 
Maybe
I need to add the option only for file-posix.c.

> 
> > diff --git a/block.c b/block.c
> > index 580cb77a70..4f05e96d12 100644
> > --- a/block.c
> > +++ b/block.c
> > @@ -1128,6 +1128,32 @@ int bdrv_parse_discard_flags(const char *mode,
> int *flags)
> >      return 0;
> >  }
> >
> > +/**
> > + * Set open flags for a given secdiscard mode
> > + *
> > + * Return 0 on success, -1 if the secdiscard mode was invalid.
> > + */
> > +int bdrv_parse_secdiscard_flags(const char *mode, int *flags, Error
> > +**errp) {
> > +    *flags &= ~BDRV_O_SECDISCARD;
> > +
> > +    if (!strcmp(mode, "off")) {
> > +        /* do nothing */
> > +    } else if (!strcmp(mode, "on")) {
> > +        if (!(*flags & BDRV_O_UNMAP)) {
> > +            error_setg(errp, "cannot enable secdiscard when discard is "
> > +                             "disabled!");
> > +            return -1;
> > +        }
> 
> This check has nothing to do with parsing the option, it's validating its 
> value.
> 
> You don't even need a new function to parse it, because there is already
> qemu_opt_get_bool(). Duplicating it means only that you're inconsistent with
> other boolean options, which alternatively accept "yes"/"no", "true"/"false",
> "y/n".
Sure. Will use qemu_opt_get_bool() instead.

> 
> > +
> > +        *flags |= BDRV_O_SECDISCARD;
> > +    } else {
> > +        return -1;
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> >  /**
> >   * Set open flags for a given cache mode
> >   *
> > @@ -1695,6 +1721,11 @@ QemuOptsList bdrv_runtime_opts = {
> >              .type = QEMU_OPT_STRING,
> >              .help = "discard operation (ignore/off, unmap/on)",
> >          },
> > +        {
> > +            .name = BDRV_OPT_SECDISCARD,
> > +            .type = QEMU_OPT_STRING,
> > +            .help = "secure discard operation (off, on)",
> > +        },
> >          {
> >              .name = BDRV_OPT_FORCE_SHARE,
> >              .type = QEMU_OPT_BOOL,
> > @@ -1735,6 +1766,7 @@ static int bdrv_open_common(BlockDriverState *bs,
> BlockBackend *file,
> >      const char *driver_name = NULL;
> >      const char *node_name = NULL;
> >      const char *discard;
> > +    const char *secdiscard;
> >      QemuOpts *opts;
> >      BlockDriver *drv;
> >      Error *local_err = NULL;
> > @@ -1829,6 +1861,16 @@ static int bdrv_open_common(BlockDriverState
> *bs, BlockBackend *file,
> >          }
> >      }
> >
> > +
> > +    secdiscard = qemu_opt_get(opts, BDRV_OPT_SECDISCARD);
> > +    if (secdiscard != NULL) {
> > +        if (bdrv_parse_secdiscard_flags(secdiscard, &bs->open_flags,
> > +                                        errp) != 0) {
> > +            ret = -EINVAL;
> > +            goto fail_opts;
> > +        }
> > +    }
> > +
> >      bs->detect_zeroes =
> >          bdrv_parse_detect_zeroes(opts, bs->open_flags, &local_err);
> >      if (local_err) {
> > @@ -3685,6 +3727,10 @@ static BlockDriverState *bdrv_open_inherit(const
> char *filename,
> >                                 &flags, options, flags, options);
> >      }
> >
> > +    if (g_strcmp0(qdict_get_try_str(options, BDRV_OPT_SECDISCARD), "on")) {
> > +            flags |= BDRV_O_SECDISCARD;
> 
> Indentation is off.
Will fix it.

> 
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -160,6 +160,7 @@ typedef struct BDRVRawState {
> >      bool is_xfs:1;
> >  #endif
> >      bool has_discard:1;
> > +    bool has_secdiscard:1;
> >      bool has_write_zeroes:1;
> >      bool discard_zeroes:1;
> >      bool use_linux_aio:1;
> 
> has_secdiscard is only set to false in raw_open_common() and never changed or
> used.
Will remove it.

> 
> > @@ -727,6 +728,7 @@ static int raw_open_common(BlockDriverState *bs,
> > QDict *options,  #endif /* !defined(CONFIG_LINUX_IO_URING) */
> >
> >      s->has_discard = true;
> > +    s->has_secdiscard = false;
> >      s->has_write_zeroes = true;
> >      if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd))
> {
> >          s->needs_alignment = true;
> > @@ -765,6 +767,7 @@ static int raw_open_common(BlockDriverState *bs,
> QDict *options,
> >              s->discard_zeroes = true;
> >          }
> >  #endif
> > +
> >  #ifdef __linux__
> >          /* On Linux 3.10, BLKDISCARD leaves stale data in the page cache.  
> > Do
> >           * not rely on the contents of discarded blocks unless using 
> > O_DIRECT.
> 
> Unrelated hunk.
Will fix it.

> 
> > @@ -1859,6 +1862,35 @@ static int handle_aiocb_discard(void *opaque)
> >      return ret;
> >  }
> >
> > +static int handle_aiocb_secdiscard(void *opaque) {
> > +    RawPosixAIOData *aiocb = opaque;
> > +    int ret = -ENOTSUP;
> > +    BlockDriverState *bs = aiocb->bs;
> > +
> > +    if (!(bs->open_flags & BDRV_O_SECDISCARD)) {
> > +        return -ENOTSUP;
> > +    }
> > +
> > +    if (aiocb->aio_type & QEMU_AIO_BLKDEV) { #ifdef BLKSECDISCARD
> > +        do {
> > +            uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
> > +            if (ioctl(aiocb->aio_fildes, BLKSECDISCARD, range) == 0) {
> > +                return 0;
> > +            }
> > +        } while (errno == EINTR);
> > +
> > +        ret = translate_err(-errno);
> > +#endif
> > +    }
> > +
> > +    if (ret == -ENOTSUP) {
> > +        bs->open_flags &= ~BDRV_O_SECDISCARD;
> 
> I'd rather avoid changing bs->open_flags. This is user input and I would 
> preserve
> it in its original state.
> 
> We already know when opening the image whether it is a block device. Why do
> we even open the image instead of erroring out there?
OK. I will try to find another way to record whether backend driver would 
support
SECDISCARD.

Best Regard
Yadong



Reply via email to