liowait: This patch adds support for the POSIX listio LIO_WAIT mechanism. This works by adding an IOCB_CMD_CHECKPOINT command. As part of listio submission, the user may choose to prepend an empty iocb to the list with an aio_lio_opcode of IOCB_CMD_CHECKPOINT. All iocbs following this particular CHECKPOINT iocb are in the same group and sys_io_submit will block until all iocbs submitted in the group have completed. Makefile | 2 - fs/aio.c | 94 +++++++++++++++++++++++++++++++++++++++++++++--- include/linux/aio_abi.h | 1 3 files changed, 91 insertions(+), 6 deletions(-) Signed-off-by: Sébastien Dugué Index: linux-2.6.12/fs/aio.c =================================================================== --- linux-2.6.12.orig/fs/aio.c 2005-07-21 11:30:57.000000000 +0200 +++ linux-2.6.12/fs/aio.c 2005-07-21 11:35:03.000000000 +0200 @@ -954,8 +954,24 @@ read_unlock(&tasklist_lock); } +static void wait_for_lio(struct kioctx *ctx, struct lio_event *lio) +{ + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + + add_wait_queue(&ctx->wait, &wait); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + + while ( atomic_read(&lio->lio_users) ) { + schedule(); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + } + __set_task_state(tsk, TASK_RUNNING); + remove_wait_queue(&ctx->wait, &wait); +} + static inline void check_lio(struct kioctx *ctx, - struct lio_event *lio) + struct lio_event *lio, int wait) { int ret; @@ -979,7 +995,52 @@ kfree(lio); } + } else if (wait) { + + /* if needed, wait end of all AIO of this list */ + + wait_for_lio(ctx, lio); + + /* free memory */ + + kfree(lio); + } +} + +static int create_lio_wait(struct kioctx *ctx, struct lio_event **lio, + int enable) +{ + if (*lio != NULL) { + + /* we break an existing sequence (lio exists) + * close the sequence + */ + + check_lio(ctx, *lio, 1); + *lio = NULL; + } + + if (!enable) { + + /* it means we don't want to monitor following commands + * usefull to break current sequence + */ + + return 0; } + + + *lio = kmalloc(sizeof(*lio), GFP_KERNEL); + if (!*lio) + return -EAGAIN; + + atomic_set(&((*lio)->lio_users), 1); + (*lio)->lio_pid = 0; + (*lio)->lio_signo = 0; + (*lio)->lio_notify = 0; + (*lio)->lio_value = 0; + + return 0; } static int create_lio_event(struct kioctx *ctx,struct lio_event **lio, @@ -1023,7 +1084,7 @@ * close the sequence */ - check_lio(ctx, *lio); + check_lio(ctx, *lio, 1); if (signo == 0) { @@ -1153,7 +1214,7 @@ __aio_send_signal(iocb->ki_pid, iocb->ki_signo, iocb->ki_notify, (void*)(unsigned long)iocb->ki_value); - check_lio(ctx, iocb->ki_lio_event); + check_lio(ctx, iocb->ki_lio_event, 0); pr_debug("%ld retries: %d of %d\n", iocb->ki_retried, iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); @@ -1882,7 +1943,30 @@ } } - if (tmp.aio_lio_opcode == IOCB_CMD_EVENT) { + if (tmp.aio_lio_opcode == IOCB_CMD_CHECKPOINT) { + /* this command means that all following IO commands + * are in the same group. + * io_submit() will wait all commands of the group + * have been processed before exiting. + */ + + if (aio_pid) { + ret = -EINVAL; + break; + } + + if ( (aio_signo != 0) && (aio_signo != 1) ) { + ret = -EINVAL; + break; + } + + ret = create_lio_wait(ctx, &lio, aio_signo); + if (ret) + break; + + continue; + + } else if (tmp.aio_lio_opcode == IOCB_CMD_EVENT) { /* this command means that all following IO commands * are in the same group and when the group becomes @@ -1921,7 +2005,7 @@ break; } } - check_lio(ctx, lio); + check_lio(ctx, lio, 1); put_ioctx(ctx); return i ? i : ret; Index: linux-2.6.12/include/linux/aio_abi.h =================================================================== --- linux-2.6.12.orig/include/linux/aio_abi.h 2005-07-21 11:30:03.000000000 +0200 +++ linux-2.6.12/include/linux/aio_abi.h 2005-07-21 11:35:03.000000000 +0200 @@ -42,6 +42,7 @@ */ IOCB_CMD_NOOP = 6, IOCB_CMD_EVENT = 7, + IOCB_CMD_CHECKPOINT = 8, }; /* read() from /dev/aio returns these structures. */ Index: linux-2.6.12/Makefile =================================================================== --- linux-2.6.12.orig/Makefile 2005-07-21 11:30:03.000000000 +0200 +++ linux-2.6.12/Makefile 2005-07-21 11:35:03.000000000 +0200 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 12 -EXTRAVERSION = .PAIO-lioevent +EXTRAVERSION = .PAIO-liowait NAME=Woozy Numbat # *DOCUMENTATION*