From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51168) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VLyvQ-0004hO-U2 for qemu-devel@nongnu.org; Tue, 17 Sep 2013 13:19:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VLyvK-0003OY-Dw for qemu-devel@nongnu.org; Tue, 17 Sep 2013 13:18:56 -0400 Received: from [2a03:4000:1::4e2f:c7ac:d] (port=35059 helo=v220110690675601.yourvserver.net) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VLyvK-0003Nz-35 for qemu-devel@nongnu.org; Tue, 17 Sep 2013 13:18:50 -0400 Message-ID: <52388EF5.4030108@weilnetz.de> Date: Tue, 17 Sep 2013 19:18:45 +0200 From: Stefan Weil MIME-Version: 1.0 References: <1378984634-765-1-git-send-email-pbonzini@redhat.com> <1378984634-765-9-git-send-email-pbonzini@redhat.com> In-Reply-To: <1378984634-765-9-git-send-email-pbonzini@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PULL 08/11] iscsi: add .bdrv_get_block_status List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: Peter Lieven , qemu-devel@nongnu.org, Anthony Liguori Am 12.09.2013 13:17, schrieb Paolo Bonzini: > From: Peter Lieven > > this patch adds a coroutine for .bdrv_co_block_status as well as > a generic framework that can be used to build coroutines in block/iscsi= . > > Signed-off-by: Peter Lieven > Signed-off-by: Paolo Bonzini > --- > block/iscsi.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++ > 1 file changed, 136 insertions(+) > > diff --git a/block/iscsi.c b/block/iscsi.c > index bfd659a..c377d21 100644 > --- a/block/iscsi.c > +++ b/block/iscsi.c > @@ -58,6 +58,15 @@ typedef struct IscsiLun { > struct scsi_inquiry_block_limits bl; > } IscsiLun; > =20 > +typedef struct IscsiTask { > + int status; > + int complete; > + int retries; > + int do_retry; > + struct scsi_task *task; > + Coroutine *co; > +} IscsiTask; > + > typedef struct IscsiAIOCB { > BlockDriverAIOCB common; > QEMUIOVector *qiov; > @@ -111,6 +120,41 @@ iscsi_schedule_bh(IscsiAIOCB *acb) > qemu_bh_schedule(acb->bh); > } > =20 > +static void > +iscsi_co_generic_cb(struct iscsi_context *iscsi, int status, > + void *command_data, void *opaque) > +{ > + struct IscsiTask *iTask =3D opaque; > + struct scsi_task *task =3D command_data; > + > + iTask->complete =3D 1; > + iTask->status =3D status; > + iTask->do_retry =3D 0; > + iTask->task =3D task; > + > + if (iTask->retries-- > 0 && status =3D=3D SCSI_STATUS_CHECK_CONDIT= ION > + && task->sense.key =3D=3D SCSI_SENSE_UNIT_ATTENTION) { > + iTask->do_retry =3D 1; > + goto out; > + } > + > + if (status !=3D SCSI_STATUS_GOOD) { > + error_report("iSCSI: Failure. %s", iscsi_get_error(iscsi)); > + } > + > +out: > + if (iTask->co) { > + qemu_coroutine_enter(iTask->co, NULL); > + } > +} > + > +static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTa= sk *iTask) > +{ > + *iTask =3D (struct IscsiTask) { > + .co =3D qemu_coroutine_self(), > + .retries =3D ISCSI_CMD_RETRIES, > + }; > +} > =20 > static void > iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *com= mand_data, > @@ -848,6 +892,96 @@ iscsi_getlength(BlockDriverState *bs) > return len; > } > =20 > +static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState= *bs, > + int64_t sector_num, > + int nb_sectors, int = *pnum) > +{ > + IscsiLun *iscsilun =3D bs->opaque; > + struct scsi_get_lba_status *lbas =3D NULL; > + struct scsi_lba_status_descriptor *lbasd =3D NULL; > + struct IscsiTask iTask; > + int64_t ret; > + > + iscsi_co_init_iscsitask(iscsilun, &iTask); > + > + if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { > + ret =3D -EINVAL; > + goto out; > + } > + > + /* default to all sectors allocated */ > + ret =3D BDRV_BLOCK_DATA; > + ret |=3D (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALI= D; > + *pnum =3D nb_sectors; > + > + /* LUN does not support logical block provisioning */ > + if (iscsilun->lbpme =3D=3D 0) { > + goto out; > + } > + > +retry: > + if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun, > + sector_qemu2lun(sector_num, iscsilun= ), > + 8 + 16, iscsi_co_generic_cb, > + &iTask) =3D=3D NULL) { > + ret =3D -EIO; > + goto out; > + } > + > + while (!iTask.complete) { > + iscsi_set_events(iscsilun); > + qemu_coroutine_yield(); > + } > + > + if (iTask.do_retry) { > + if (iTask.task !=3D NULL) { > + scsi_free_scsi_task(iTask.task); > + iTask.task =3D NULL; > + } > + goto retry; > + } > + > + if (iTask.status !=3D SCSI_STATUS_GOOD) { > + /* in case the get_lba_status_callout fails (i.e. > + * because the device is busy or the cmd is not > + * supported) we pretend all blocks are allocated > + * for backwards compatiblity */ > + goto out; > + } > + > + lbas =3D scsi_datain_unmarshall(iTask.task); > + if (lbas =3D=3D NULL) { > + ret =3D -EIO; > + goto out; > + } > + > + lbasd =3D &lbas->descriptors[0]; > + > + if (sector_qemu2lun(sector_num, iscsilun) !=3D lbasd->lba) { > + ret =3D -EIO; > + goto out; > + } > + > + *pnum =3D sector_lun2qemu(lbasd->num_blocks, iscsilun); > + if (*pnum > nb_sectors) { > + *pnum =3D nb_sectors; > + } > + > + if (lbasd->provisioning =3D=3D SCSI_PROVISIONING_TYPE_DEALLOCATED = || > + lbasd->provisioning =3D=3D SCSI_PROVISIONING_TYPE_ANCHORED) { > + ret &=3D ~BDRV_BLOCK_DATA; > + if (iscsilun->lbprz) { > + ret |=3D BDRV_BLOCK_ZERO; > + } > + } > + > +out: > + if (iTask.task !=3D NULL) { > + scsi_free_scsi_task(iTask.task); > + } > + return ret; > +} > + > static int parse_chap(struct iscsi_context *iscsi, const char *target) > { > QemuOptsList *list; > @@ -1398,6 +1532,8 @@ static BlockDriver bdrv_iscsi =3D { > .bdrv_getlength =3D iscsi_getlength, > .bdrv_truncate =3D iscsi_truncate, > =20 > + .bdrv_co_get_block_status =3D iscsi_co_get_block_status, > + > .bdrv_aio_readv =3D iscsi_aio_readv, > .bdrv_aio_writev =3D iscsi_aio_writev, > .bdrv_aio_flush =3D iscsi_aio_flush, Latest QEMU git is broken on Debian wheezy: block/iscsi.c: In function =E2=80=98iscsi_co_get_block_status=E2=80=99: block/iscsi.c:842:5: error: implicit declaration of function =E2=80=98iscsi_get_lba_status_task=E2=80=99 [-Werror=3Dimplicit-function-= declaration] block/iscsi.c:842:5: error: nested extern declaration of =E2=80=98iscsi_get_lba_status_task=E2=80=99 [-Werror=3Dnested-externs] block/iscsi.c:845:43: error: comparison between pointer and integer [-Werror] block/iscsi.c:877:18: error: dereferencing pointer to incomplete type block/iscsi.c:879:55: error: dereferencing pointer to incomplete type block/iscsi.c:884:34: error: dereferencing pointer to incomplete type block/iscsi.c:889:14: error: dereferencing pointer to incomplete type block/iscsi.c:889:32: error: =E2=80=98SCSI_PROVISIONING_TYPE_DEALLOCATED=E2= =80=99 undeclared (first use in this function) block/iscsi.c:889:32: note: each undeclared identifier is reported only once for each function it appears in block/iscsi.c:890:14: error: dereferencing pointer to incomplete type block/iscsi.c:890:32: error: =E2=80=98SCSI_PROVISIONING_TYPE_ANCHORED=E2=80= =99 undeclared (first use in this function) cc1: all warnings being treated as errors Debian includes libiscsi-dev 1.4.0 without a libiscsi.pk, so it uses a compile test which thinks that libiscsi is good enough. Did the latest changes raise the requirements for libscsi? Regards, Stefan