[PATCH -mm 7/7][AIO] - Add listio syscall support

2007-02-01 Thread Sébastien Dugué

From: Bharata B Rao <[EMAIL PROTECTED]>

This patch provides POSIX listio support by means of a new system call.

long lio_submit(aio_context_t ctx_id, int mode, long nr,
struct iocb __user * __user *iocbpp, struct sigevent __user *event)

This system call is similar to the io_submit() system call, but takes
two more arguments.

'mode' argument can be LIO_WAIT or LIO_NOWAIT.

'event' argument specifies the signal notification mechanism.

This patch is built on support provided by the aio signal notification
patch by Sebastien. The following two structures together provide
the support for grouping iocbs belonging to a list (lio).

struct aio_notify {
struct task_struct  *target;
__u16   signo;
__u16   notify;
sigval_tvalue;
struct sigqueue *sigq;
};

struct lio_event {
atomic_tlio_users;
struct aio_notify   lio_notify;
};

A single lio_event struct is maintained for the list of iocbs.
lio_users holds the number of requests attached to this lio and lio_notify
has the necessary information for generating completion notification
signal.

If the mode is LIO_WAIT, the event argument is ignored and the system
call waits until all the requests of the lio are completed.

If the mode is LIO_NOWAIT, the system call returns immediately after
submitting the io requests and may optionally notify the process on
list io completion depending on the event argument.

Signed-off-by: Sébastien Dugué <[EMAIL PROTECTED]>
Signed-off-by: Laurent Vivier <[EMAIL PROTECTED]>
Signed-off-by: Bharata B Rao <[EMAIL PROTECTED]>
---

 arch/i386/kernel/syscall_table.S |1 
 arch/x86_64/ia32/ia32entry.S |5 -
 fs/aio.c |  193 ++-
 fs/compat.c  |  125 +
 include/asm-i386/unistd.h|3 
 include/asm-x86_64/unistd.h  |4 
 include/linux/aio.h  |   14 ++
 include/linux/aio_abi.h  |5 +
 include/linux/syscalls.h |2 
 9 files changed, 307 insertions(+), 45 deletions(-)

Index: linux-2.6.20-rc6-mm3/arch/i386/kernel/syscall_table.S
===
--- linux-2.6.20-rc6-mm3.orig/arch/i386/kernel/syscall_table.S  2007-01-31 
15:31:59.0 +0100
+++ linux-2.6.20-rc6-mm3/arch/i386/kernel/syscall_table.S   2007-01-31 
15:58:55.0 +0100
@@ -320,3 +320,4 @@ ENTRY(sys_call_table)
.long sys_getcpu
.long sys_epoll_pwait
.long sys_lutimesat /* 320 */
+   .long sys_lio_submit
Index: linux-2.6.20-rc6-mm3/arch/x86_64/ia32/ia32entry.S
===
--- linux-2.6.20-rc6-mm3.orig/arch/x86_64/ia32/ia32entry.S  2007-01-31 
15:31:59.0 +0100
+++ linux-2.6.20-rc6-mm3/arch/x86_64/ia32/ia32entry.S   2007-01-31 
15:58:55.0 +0100
@@ -714,8 +714,11 @@ ia32_sys_call_table:
.quad compat_sys_get_robust_list
.quad sys_splice
.quad sys_sync_file_range
-   .quad sys_tee
+   .quad sys_tee   /* 315 */
.quad compat_sys_vmsplice
.quad compat_sys_move_pages
.quad sys_getcpu
+   .quad quiet_ni_syscall  /* sys_epoll_wait */
+   .quad quiet_ni_syscall  /* 320: sys_lutimesat */
+   .quad compat_sys_lio_submit
 ia32_syscall_end:  
Index: linux-2.6.20-rc6-mm3/fs/aio.c
===
--- linux-2.6.20-rc6-mm3.orig/fs/aio.c  2007-01-31 15:31:59.0 +0100
+++ linux-2.6.20-rc6-mm3/fs/aio.c   2007-01-31 16:00:57.0 +0100
@@ -416,6 +416,7 @@ static struct kiocb fastcall *__aio_get_
req->ki_ctx = ctx;
req->ki_cancel = NULL;
req->ki_retry = NULL;
+   req->ki_lio = NULL;
req->ki_dtor = NULL;
req->private = NULL;
req->ki_iovec = NULL;
@@ -995,6 +996,72 @@ out_unlock:
return -EINVAL;
 }
 
+/*
+ * lio_notify
+ * When all iocbs belonging to an lio are complete, this initiates
+ * the completion notification for the lio.
+ *
+ * NOTE: lio is freed here after the last iocb completes, but only
+ * for LIO_NOWAIT case. In case of LIO_WAIT, the submitting thread
+ * waits for iocbs to complete and later frees the lio.
+ */
+void lio_notify(struct lio_event *lio)
+{
+   int ret;
+
+   ret = atomic_dec_and_test(>lio_users);
+
+   if (unlikely(ret) && lio->lio_notify.notify != SIGEV_NONE) {
+   /* last one -> notify process */
+   if (aio_send_signal(>lio_notify))
+   __sigqueue_free(lio->lio_notify.sigq);
+   kfree(lio);
+   }
+}
+
+/*
+ * lio_create
+ * Allocates a lio_event structure which groups the iocbs belonging
+ * to the lio and sets up the completion notification.
+ *
+ * Case 1: LIO_NOWAIT and NULL sigevent - No 

[PATCH -mm 7/7][AIO] - Add listio syscall support

2007-02-01 Thread Sébastien Dugué

From: Bharata B Rao [EMAIL PROTECTED]

This patch provides POSIX listio support by means of a new system call.

long lio_submit(aio_context_t ctx_id, int mode, long nr,
struct iocb __user * __user *iocbpp, struct sigevent __user *event)

This system call is similar to the io_submit() system call, but takes
two more arguments.

'mode' argument can be LIO_WAIT or LIO_NOWAIT.

'event' argument specifies the signal notification mechanism.

This patch is built on support provided by the aio signal notification
patch by Sebastien. The following two structures together provide
the support for grouping iocbs belonging to a list (lio).

struct aio_notify {
struct task_struct  *target;
__u16   signo;
__u16   notify;
sigval_tvalue;
struct sigqueue *sigq;
};

struct lio_event {
atomic_tlio_users;
struct aio_notify   lio_notify;
};

A single lio_event struct is maintained for the list of iocbs.
lio_users holds the number of requests attached to this lio and lio_notify
has the necessary information for generating completion notification
signal.

If the mode is LIO_WAIT, the event argument is ignored and the system
call waits until all the requests of the lio are completed.

If the mode is LIO_NOWAIT, the system call returns immediately after
submitting the io requests and may optionally notify the process on
list io completion depending on the event argument.

Signed-off-by: Sébastien Dugué [EMAIL PROTECTED]
Signed-off-by: Laurent Vivier [EMAIL PROTECTED]
Signed-off-by: Bharata B Rao [EMAIL PROTECTED]
---

 arch/i386/kernel/syscall_table.S |1 
 arch/x86_64/ia32/ia32entry.S |5 -
 fs/aio.c |  193 ++-
 fs/compat.c  |  125 +
 include/asm-i386/unistd.h|3 
 include/asm-x86_64/unistd.h  |4 
 include/linux/aio.h  |   14 ++
 include/linux/aio_abi.h  |5 +
 include/linux/syscalls.h |2 
 9 files changed, 307 insertions(+), 45 deletions(-)

Index: linux-2.6.20-rc6-mm3/arch/i386/kernel/syscall_table.S
===
--- linux-2.6.20-rc6-mm3.orig/arch/i386/kernel/syscall_table.S  2007-01-31 
15:31:59.0 +0100
+++ linux-2.6.20-rc6-mm3/arch/i386/kernel/syscall_table.S   2007-01-31 
15:58:55.0 +0100
@@ -320,3 +320,4 @@ ENTRY(sys_call_table)
.long sys_getcpu
.long sys_epoll_pwait
.long sys_lutimesat /* 320 */
+   .long sys_lio_submit
Index: linux-2.6.20-rc6-mm3/arch/x86_64/ia32/ia32entry.S
===
--- linux-2.6.20-rc6-mm3.orig/arch/x86_64/ia32/ia32entry.S  2007-01-31 
15:31:59.0 +0100
+++ linux-2.6.20-rc6-mm3/arch/x86_64/ia32/ia32entry.S   2007-01-31 
15:58:55.0 +0100
@@ -714,8 +714,11 @@ ia32_sys_call_table:
.quad compat_sys_get_robust_list
.quad sys_splice
.quad sys_sync_file_range
-   .quad sys_tee
+   .quad sys_tee   /* 315 */
.quad compat_sys_vmsplice
.quad compat_sys_move_pages
.quad sys_getcpu
+   .quad quiet_ni_syscall  /* sys_epoll_wait */
+   .quad quiet_ni_syscall  /* 320: sys_lutimesat */
+   .quad compat_sys_lio_submit
 ia32_syscall_end:  
Index: linux-2.6.20-rc6-mm3/fs/aio.c
===
--- linux-2.6.20-rc6-mm3.orig/fs/aio.c  2007-01-31 15:31:59.0 +0100
+++ linux-2.6.20-rc6-mm3/fs/aio.c   2007-01-31 16:00:57.0 +0100
@@ -416,6 +416,7 @@ static struct kiocb fastcall *__aio_get_
req-ki_ctx = ctx;
req-ki_cancel = NULL;
req-ki_retry = NULL;
+   req-ki_lio = NULL;
req-ki_dtor = NULL;
req-private = NULL;
req-ki_iovec = NULL;
@@ -995,6 +996,72 @@ out_unlock:
return -EINVAL;
 }
 
+/*
+ * lio_notify
+ * When all iocbs belonging to an lio are complete, this initiates
+ * the completion notification for the lio.
+ *
+ * NOTE: lio is freed here after the last iocb completes, but only
+ * for LIO_NOWAIT case. In case of LIO_WAIT, the submitting thread
+ * waits for iocbs to complete and later frees the lio.
+ */
+void lio_notify(struct lio_event *lio)
+{
+   int ret;
+
+   ret = atomic_dec_and_test(lio-lio_users);
+
+   if (unlikely(ret)  lio-lio_notify.notify != SIGEV_NONE) {
+   /* last one - notify process */
+   if (aio_send_signal(lio-lio_notify))
+   __sigqueue_free(lio-lio_notify.sigq);
+   kfree(lio);
+   }
+}
+
+/*
+ * lio_create
+ * Allocates a lio_event structure which groups the iocbs belonging
+ * to the lio and sets up the completion notification.
+ *
+ * Case 1: LIO_NOWAIT and NULL sigevent - No need to group