From: Jens Axboe Date: Tue, 28 Oct 2014 15:03:11 +0000 (-0600) Subject: engines/rbd: use rbd_aio_is_complete() and add TRIM support X-Git-Tag: fio-2.1.14~29 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=dbf388d2f6a76b37176edc2b1b500f1bb2557ca8 engines/rbd: use rbd_aio_is_complete() and add TRIM support Using fri->io_complete is potentially racy, since we have no locking around checking and waiting. Use the API provided function to check for completion instead. Add support for TRIM through rbd_aio_discard(). Cleanup the queue interface and completion creation. Signed-off-by: Jens Axboe --- diff --git a/engines/rbd.c b/engines/rbd.c index e4155da2..828fdf8c 100644 --- a/engines/rbd.c +++ b/engines/rbd.c @@ -12,7 +12,6 @@ struct fio_rbd_iou { struct io_u *io_u; rbd_completion_t completion; - int io_complete; int io_seen; }; @@ -100,7 +99,7 @@ static int _fio_rbd_connect(struct thread_data *td) struct rbd_options *o = td->eo; int r; - r = rados_create(&(rbd_data->cluster), o->client_name); + r = rados_create(&rbd_data->cluster, o->client_name); if (r < 0) { log_err("rados_create failed.\n"); goto failed_early; @@ -119,13 +118,13 @@ static int _fio_rbd_connect(struct thread_data *td) } r = rados_ioctx_create(rbd_data->cluster, o->pool_name, - &(rbd_data->io_ctx)); + &rbd_data->io_ctx); if (r < 0) { log_err("rados_ioctx_create failed.\n"); goto failed_shutdown; } - r = rbd_open(rbd_data->io_ctx, o->rbd_name, &(rbd_data->image), + r = rbd_open(rbd_data->io_ctx, o->rbd_name, &rbd_data->image, NULL /*snap */ ); if (r < 0) { log_err("rbd_open failed.\n"); @@ -167,12 +166,10 @@ static void _fio_rbd_disconnect(struct rbd_data *rbd_data) static void _fio_rbd_finish_aiocb(rbd_completion_t comp, void *data) { - struct io_u *io_u = data; - struct fio_rbd_iou *fri = io_u->engine_data; + struct fio_rbd_iou *fri = data; + struct io_u *io_u = fri->io_u; ssize_t ret; - fri->io_complete = 1; - /* * Looks like return value is 0 for success, or < 0 for * a specific error. So we have to assume that it can't do @@ -199,8 +196,7 @@ static inline int fri_check_complete(struct rbd_data *rbd_data, { struct fio_rbd_iou *fri = io_u->engine_data; - if (fri->io_complete) { - fri->io_complete = 0; + if (rbd_aio_is_complete(fri->completion)) { fri->io_seen = 1; rbd_data->aio_events[*events] = io_u; (*events)++; @@ -271,70 +267,55 @@ static int fio_rbd_queue(struct thread_data *td, struct io_u *io_u) fio_ro_check(td, io_u); - fri->io_complete = 0; fri->io_seen = 0; - if (io_u->ddir == DDIR_WRITE) { - r = rbd_aio_create_completion(io_u, _fio_rbd_finish_aiocb, + r = rbd_aio_create_completion(fri, _fio_rbd_finish_aiocb, &fri->completion); - if (r < 0) { - log_err - ("rbd_aio_create_completion for DDIR_WRITE failed.\n"); - goto failed; - } + if (r < 0) { + log_err("rbd_aio_create_completion failed.\n"); + goto failed; + } + if (io_u->ddir == DDIR_WRITE) { r = rbd_aio_write(rbd_data->image, io_u->offset, io_u->xfer_buflen, io_u->xfer_buf, fri->completion); if (r < 0) { log_err("rbd_aio_write failed.\n"); - rbd_aio_release(fri->completion); - goto failed; + goto failed_comp; } } else if (io_u->ddir == DDIR_READ) { - r = rbd_aio_create_completion(io_u, _fio_rbd_finish_aiocb, - &fri->completion); - if (r < 0) { - log_err - ("rbd_aio_create_completion for DDIR_READ failed.\n"); - goto failed; - } - r = rbd_aio_read(rbd_data->image, io_u->offset, io_u->xfer_buflen, io_u->xfer_buf, fri->completion); if (r < 0) { log_err("rbd_aio_read failed.\n"); - rbd_aio_release(fri->completion); - goto failed; + goto failed_comp; } - - } else if (io_u->ddir == DDIR_SYNC) { - r = rbd_aio_create_completion(io_u, _fio_rbd_finish_aiocb, - &fri->completion); + } else if (io_u->ddir == DDIR_TRIM) { + r = rbd_aio_discard(rbd_data->image, io_u->offset, + io_u->xfer_buflen, fri->completion); if (r < 0) { - log_err - ("rbd_aio_create_completion for DDIR_SYNC failed.\n"); - goto failed; + log_err("rbd_aio_discard failed.\n"); + goto failed_comp; } - + } else if (io_u->ddir == DDIR_SYNC) { r = rbd_aio_flush(rbd_data->image, fri->completion); if (r < 0) { log_err("rbd_flush failed.\n"); - rbd_aio_release(fri->completion); - goto failed; + goto failed_comp; } - } else { dprint(FD_IO, "%s: Warning: unhandled ddir: %d\n", __func__, io_u->ddir); - return FIO_Q_COMPLETED; + goto failed_comp; } return FIO_Q_QUEUED; - +failed_comp: + rbd_aio_release(fri->completion); failed: io_u->error = r; td_verror(td, io_u->error, "xfer");