On Fri, Jul 05, 2024 at 06:56:09PM +0800, Changqi Lu wrote: > Add persistent reservation in/out operations in the > SCSI device layer. By introducing the persistent > reservation in/out api, this enables the SCSI 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 operations 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> > --- > hw/scsi/scsi-disk.c | 368 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 368 insertions(+) > > diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c > index 4bd7af9d0c..f0c3ce774f 100644 > --- a/hw/scsi/scsi-disk.c > +++ b/hw/scsi/scsi-disk.c > @@ -32,6 +32,7 @@ > #include "migration/vmstate.h" > #include "hw/scsi/emulation.h" > #include "scsi/constants.h" > +#include "scsi/utils.h" > #include "sysemu/block-backend.h" > #include "sysemu/blockdev.h" > #include "hw/block/block.h" > @@ -42,6 +43,7 @@ > #include "qemu/cutils.h" > #include "trace.h" > #include "qom/object.h" > +#include "block/block_int.h" > > #ifdef __linux > #include <scsi/sg.h> > @@ -1474,6 +1476,362 @@ static void scsi_disk_emulate_read_data(SCSIRequest > *req) > scsi_req_complete(&r->req, GOOD); > } > > +typedef struct SCSIPrReadKeys { > + uint32_t generation; > + uint32_t num_keys; > + uint64_t *keys; > + SCSIDiskReq *req; > +} SCSIPrReadKeys; > + > +typedef struct SCSIPrReadReservation { > + uint32_t generation; > + uint64_t key; > + BlockPrType type; > + SCSIDiskReq *req; > +} SCSIPrReadReservation; > + > +static void scsi_pr_read_keys_complete(void *opaque, int ret) > +{ > + int num_keys; > + uint8_t *buf; > + SCSIPrReadKeys *blk_keys = (SCSIPrReadKeys *)opaque; > + SCSIDiskReq *r = blk_keys->req; > + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); > + > + assert(blk_get_aio_context(s->qdev.conf.blk) == > + qemu_get_current_aio_context()); > + > + assert(r->req.aiocb != NULL); > + r->req.aiocb = NULL; > + > + if (scsi_disk_req_check_error(r, ret, true)) { > + goto done; > + } > + > + buf = scsi_req_get_buf(&r->req); > + num_keys = MIN(blk_keys->num_keys, ret);
The behavior of scsi_disk_req_check_error() above is strange for pr_read_keys operations. When --drive ...,rerror=ignore and ret < 0 this line is reached and we don't want a negative num_keys value. It would be safer to use (ret > 0 ? ret : 0) instead of the raw value of ret. Stefan
signature.asc
Description: PGP signature