On Wed, Sep 05, 2012 at 01:11:06PM +0530, Bharata B Rao wrote: > On Thu, Aug 09, 2012 at 06:32:16PM +0530, Bharata B Rao wrote: > > +static void qemu_gluster_complete_aio(GlusterAIOCB *acb) > > +{ > > + int ret; > > + > > + if (acb->canceled) { > > + qemu_aio_release(acb); > > + return; > > + } > > + > > + if (acb->ret == acb->size) { > > + ret = 0; /* Success */ > > + } else if (acb->ret < 0) { > > + ret = acb->ret; /* Read/Write failed */ > > + } else { > > + ret = -EIO; /* Partial read/write - fail it */ > > + } > > + acb->common.cb(acb->common.opaque, ret); > > The .cb() here is bdrv_co_io_em_complete(). It does qemu_coroutine_enter(), > handles the return value and comes back here. > > But if the bdrv_read or bdrv_write or bdrv_flush was called from a > coroutine context (as against they themselves creating a new coroutine), > the above .cb() call above doesn't return to this point. Hence I won't > be able to release the acb and decrement the qemu_aio_count. > > What could be the issue here ? In general, how do I ensure that my > aio calls get completed correctly in such scenarios where bdrv_read etc > are called from coroutine context rather than from main thread context ?
One way to handle this is not to do completion from gluster thread but instead schedule a BH that does the completion. In fact I had this approach in the earlier versions, but resorted to directly calling completion from gluster thread as I didn't see the value of using a BH for completion. But I guess its indeed needed to support such scenarios (qcow2 image creation on gluster backend). Regards, Bharata.