On Tue, Aug 9, 2011 at 4:46 PM, Ram Pai <linuxram@xxxxxxxxxx> wrote: > On Tue, Aug 09, 2011 at 12:17:50PM +0800, Zhi Yong Wu wrote: >> The patch introduce one block queue for QEMU block layer. >> >> Signed-off-by: Zhi Yong Wu <wuzhy@xxxxxxxxxxxxxxxxxx> >> --- >> block/blk-queue.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++ >> block/blk-queue.h | 73 +++++++++++++++++++++++++++ >> 2 files changed, 214 insertions(+), 0 deletions(-) >> create mode 100644 block/blk-queue.c >> create mode 100644 block/blk-queue.h >> >> diff --git a/block/blk-queue.c b/block/blk-queue.c >> new file mode 100644 >> index 0000000..f36f3e2 >> --- /dev/null >> +++ b/block/blk-queue.c >> @@ -0,0 +1,141 @@ >> +/* >> + * QEMU System Emulator queue definition for block layer >> + * >> + * Copyright (c) 2011 Zhi Yong Wu <zwu.kernel@xxxxxxxxx> >> + * >> + * Permission is hereby granted, free of charge, to any person obtaining a copy >> + * of this software and associated documentation files (the "Software"), to deal >> + * in the Software without restriction, including without limitation the rights >> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell >> + * copies of the Software, and to permit persons to whom the Software is >> + * furnished to do so, subject to the following conditions: >> + * >> + * The above copyright notice and this permission notice shall be included in >> + * all copies or substantial portions of the Software. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER >> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, >> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN >> + * THE SOFTWARE. >> + */ >> + >> +#include "block_int.h" >> +#include "qemu-queue.h" >> +#include "block/blk-queue.h" >> + >> +/* The APIs for block request queue on qemu block layer. >> + */ >> + >> +static void qemu_block_queue_cancel(BlockDriverAIOCB *acb) >> +{ >> + qemu_aio_release(acb); >> +} >> + >> +static AIOPool block_queue_pool = { >> + .aiocb_size = sizeof(struct BlockDriverAIOCB), >> + .cancel = qemu_block_queue_cancel, >> +}; >> + >> +static void qemu_block_queue_callback(void *opaque, int ret) >> +{ >> + BlockDriverAIOCB *acb = opaque; >> + >> + qemu_aio_release(acb); >> +} >> + >> +BlockQueue *qemu_new_block_queue(void) >> +{ >> + BlockQueue *queue; >> + >> + queue = qemu_mallocz(sizeof(BlockQueue)); >> + >> + QTAILQ_INIT(&queue->requests); >> + >> + return queue; >> +} >> + >> +void qemu_del_block_queue(BlockQueue *queue) >> +{ >> + BlockIORequest *request, *next; >> + >> + QTAILQ_FOREACH_SAFE(request, &queue->requests, entry, next) { >> + QTAILQ_REMOVE(&queue->requests, request, entry); >> + qemu_free(request); >> + } >> + >> + qemu_free(queue); >> +} >> + >> +BlockDriverAIOCB *qemu_block_queue_enqueue(BlockQueue *queue, >> + BlockDriverState *bs, >> + BlockRequestHandler *handler, >> + int64_t sector_num, >> + QEMUIOVector *qiov, >> + int nb_sectors, >> + BlockDriverCompletionFunc *cb, >> + void *opaque) >> +{ >> + BlockIORequest *request; >> + BlockDriverAIOCB *acb; >> + >> + request = qemu_malloc(sizeof(BlockIORequest)); >> + request->bs = bs; >> + request->handler = handler; >> + request->sector_num = sector_num; >> + request->qiov = qiov; >> + request->nb_sectors = nb_sectors; >> + request->cb = cb; >> + request->opaque = opaque; >> + >> + QTAILQ_INSERT_TAIL(&queue->requests, request, entry); >> + >> + acb = qemu_aio_get(&block_queue_pool, bs, >> + qemu_block_queue_callback, opaque); >> + >> + request->acb = acb; >> + >> + return acb; >> +} >> + >> +int qemu_block_queue_handler(BlockIORequest *request) >> +{ >> + int ret; >> + BlockDriverAIOCB *res; >> + >> + /* indicate this req is from block queue */ >> + request->bs->req_from_queue = true; >> + >> + res = request->handler(request->bs, request->sector_num, >> + request->qiov, request->nb_sectors, >> + request->cb, request->opaque); > > > should'nt you return with a failure here if res == NULL? > Otherwise qemu_block_queue_callback() gets called which > will release the acb. Thanks, Pai. When req handler fails, acb should not be released. A condition determination should be done before callback function is invoked. It should be like as below: res = request->handler(request->bs, request->sector_num, request->qiov, request->nb_sectors, request->cb, request->opaque); ret = (res == NULL) ? 0 : 1; if ( ret && request->acb) { qemu_block_queue_callback(request->acb, 0); } > > >> + >> + if (request->acb) { >> + qemu_block_queue_callback(request->acb, 0); >> + } >> + >> + ret = (res == NULL) ? 0 : 1; >> + >> + return ret; >> +} > > > RP > > -- Regards, Zhi Yong Wu -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html