On Oct 11 20:12, Changqi Lu wrote:
> Add reservation acquire, reservation register,
> reservation release and reservation report commands
> in the nvme device layer.
> 
> By introducing these commands, this enables the nvme
> device to perform reservation-related tasks, including
> querying keys, querying reservation status, registering
> reservation keys, initiating and releasing reservations,
> as well as clearing and preempting reservations held by
> other keys.
> 
> These commands are crucial for management and control of
> shared storage resources in a persistent manner.
> Signed-off-by: Changqi Lu <luchangqi....@bytedance.com>
> Signed-off-by: zhenwei pi <pizhen...@bytedance.com>
> Acked-by: Klaus Jensen <k.jen...@samsung.com>
> ---
>  hw/nvme/ctrl.c       | 347 +++++++++++++++++++++++++++++++++++++++++++
>  hw/nvme/ns.c         |   6 +
>  hw/nvme/nvme.h       |   9 ++
>  include/block/nvme.h |  58 ++++++++
>  4 files changed, 420 insertions(+)
> 
> diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
> index ad212de723..4821a7ff3b 100644
> --- a/hw/nvme/ctrl.c
> +++ b/hw/nvme/ctrl.c
> +static uint16_t nvme_resv_report(NvmeCtrl *n, NvmeRequest *req)
> +{
> +    int num_keys;
> +    uint32_t cdw10 = le32_to_cpu(req->cmd.cdw10);
> +    uint32_t cdw11 = le32_to_cpu(req->cmd.cdw11);
> +    size_t buflen = (cdw10 + 1) * sizeof(uint32_t);
> +    bool eds = cdw11 & 0x1;
> +    NvmeNamespace *ns = req->ns;
> +    NvmeResvKeys *keys_info;
> +
> +    if (!nvme_support_pr(ns)) {
> +        return NVME_INVALID_OPCODE;
> +    }
> +
> +    if (eds) {
> +        if (buflen < sizeof(NvmeReservationStatusExt)) {
> +            return NVME_INVALID_FIELD;
> +        }
> +
> +        num_keys = (buflen - sizeof(NvmeReservationStatusExt)) /
> +                   sizeof(struct NvmeRegisteredCtrlExt);
> +    } else {
> +        if (buflen < sizeof(NvmeReservationStatusHeader)) {
> +            return NVME_INVALID_FIELD;
> +        }
> +
> +        num_keys = (buflen - sizeof(NvmeReservationStatusHeader)) /
> +                   sizeof(struct NvmeRegisteredCtrl);
> +    }
> +
> +    keys_info = g_new0(NvmeResvKeys, 1);
> +    /* num_keys is the maximum number of keys that can be transmitted */
> +    keys_info->num_keys = MAX(num_keys, 0);
> +    keys_info->keys = g_malloc(sizeof(uint64_t) * num_keys);
> +    keys_info->req = req;
> +
> +    req->aiocb = blk_aio_pr_read_keys(ns->blkconf.blk, 
> &keys_info->generation,
> +                                      keys_info->num_keys, keys_info->keys,
> +                                      nvme_resv_read_keys_cb, keys_info);
> +
> +    return NVME_NO_COMPLETE;
> +}

This wasn't exactly what I meant when I mentioned that we could get rid
of the MAX_KEYS. I was thinking you would do the transfer in chunks.
With the above, I think there is a risk of DoS (we can end up allocating
A LOT of memory here).

I kinda want this to get into 9.2, so I suggest that you revert this
change to the MAX_KEYS approach you had in v13.

With that sorted out, consider this R-b'ed.

Stefan, I think it makes most sense this is PR'ed by block layer
maintainers. Or, it can be split so you can take the reviewed block
layer parts and I can PR the nvme one. What do you think?

Attachment: signature.asc
Description: PGP signature

Reply via email to