On Wed, Aug 27, 2014 at 10:49:10AM +0800, Fam Zheng wrote: > +/* Async version of aio cancel. The caller is not blocked if the acb > implements > + * cancel_async, otherwise fall back to bdrv_aio_cancel. In both cases, > acb->cb > + * is guarenteed to be called, before or after function returns. */ > +void bdrv_aio_cancel_async(BlockDriverAIOCB *acb) > +{ > + if (acb->aiocb_info->cancel_async) { > + acb->aiocb_info->cancel_async(acb); > + } else { > + /* Mask the cb and cancel, we'll call it manually once the > synchronous > + * cancel is done. */ > + BlockDriverCompletionFunc *cb = acb->cb; > + void *opaque = acb->opaque; > + acb->cb = bdrv_aio_cancel_cb_nop; > + acb->opaque = NULL; > + qemu_aio_ref(acb); > + acb->aiocb_info->cancel(acb); > + cb(opaque, -ECANCELED); > + qemu_aio_release(acb); > + } > +}
It is not totally obvious why we hijack the callback. If you respin, please rephrase the comment along the lines of: /* bdrv_aio_cancel() does not guarantee to invoke cb() so mask it during * bdrv_aio_cancel() and always invoke it ourselves. */ Stefan
pgpJG2mr9sgMa.pgp
Description: PGP signature