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?
signature.asc
Description: PGP signature