* [PATCH 5/5] Add support for AIO cancelation against a file descriptor
@ 2005-07-28 15:46 Sébastien Dugué
0 siblings, 0 replies; only message in thread
From: Sébastien Dugué @ 2005-07-28 15:46 UTC (permalink / raw)
To: linux-aio kvack.org, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: cancelfd --]
[-- Type: application/octet-stream, Size: 5919 bytes --]
cancelfd:
This patch adds support for POSIX AIO cancelation against a file descriptor.
Makefile | 2
fs/aio.c | 141 +++++++++++++++++++++++++++++++++++++-----------
include/linux/aio_abi.h | 6 ++
3 files changed, 118 insertions(+), 31 deletions(-)
Signed-off-by: Sébastien Dugué <sebastien.dugue@bull.net>
Index: linux-2.6.12/fs/aio.c
===================================================================
--- linux-2.6.12.orig/fs/aio.c 2005-07-21 11:43:26.000000000 +0200
+++ linux-2.6.12/fs/aio.c 2005-07-21 11:43:27.000000000 +0200
@@ -263,6 +263,28 @@
return ctx;
}
+static int __aio_cancel(struct kiocb *kiocb, struct io_event *result)
+{
+ int (*cancel)(struct kiocb *iocb, struct io_event *res);
+
+ if (kiocb == NULL)
+ return -EFAULT;
+
+ cancel = kiocb->ki_cancel;
+ if (NULL == cancel) {
+ printk(KERN_DEBUG "iocb has no cancel operation\n");
+ return -EFAULT;
+ }
+
+ kiocb->ki_users ++;
+
+ memset(result, 0, sizeof(*result));
+ result->obj = (u64)(unsigned long)kiocb->ki_obj.user;
+ result->data = kiocb->ki_user_data;
+
+ return cancel(kiocb, result);
+}
+
/* aio_cancel_all
* Cancels all outstanding aio requests on an aio context. Used
* when the processes owning a context have all exited to encourage
@@ -270,7 +292,6 @@
*/
static void aio_cancel_all(struct kioctx *ctx)
{
- int (*cancel)(struct kiocb *, struct io_event *);
struct io_event res;
spin_lock_irq(&ctx->ctx_lock);
ctx->dead = 1;
@@ -278,14 +299,10 @@
struct list_head *pos = ctx->active_reqs.next;
struct kiocb *iocb = list_kiocb(pos);
list_del_init(&iocb->ki_list);
- cancel = iocb->ki_cancel;
kiocbSetCancelled(iocb);
- if (cancel) {
- iocb->ki_users++;
- spin_unlock_irq(&ctx->ctx_lock);
- cancel(iocb, &res);
- spin_lock_irq(&ctx->ctx_lock);
- }
+ spin_unlock_irq(&ctx->ctx_lock);
+ __aio_cancel(iocb, &res);
+ spin_lock_irq(&ctx->ctx_lock);
}
spin_unlock_irq(&ctx->ctx_lock);
}
@@ -2028,6 +2045,67 @@
return NULL;
}
+static int aio_cancel_fd(aio_context_t ctx_id, int fildes)
+{
+ struct kioctx *ctx;
+ struct kiocb *kiocb;
+ int ret;
+ struct file *file;
+ struct list_head *pos;
+ int all_done;
+ int not_canceled;
+ struct io_event result_event;
+
+ /* cancel all I/O belonging to filedes */
+
+ file = fget(fildes);
+ if (unlikely(!file))
+ return -EBADF;
+
+ /* we must exit on EBADF before EINVAL */
+
+ ctx = lookup_ioctx(ctx_id);
+ if (unlikely(!ctx)) {
+ return -EINVAL;
+ }
+
+ /* get all operation for this file descriptor */
+
+ all_done = 1;
+ not_canceled = 0;
+ spin_lock_irq(&ctx->ctx_lock);
+
+ list_for_each(pos, &ctx->active_reqs) {
+
+ kiocb = list_kiocb(pos);
+
+ if (kiocb->ki_filp == file) {
+
+ all_done = 0;
+
+ spin_unlock_irq(&ctx->ctx_lock);
+ ret = __aio_cancel(kiocb, &result_event);
+ spin_lock_irq(&ctx->ctx_lock);
+ if (ret)
+ not_canceled++;
+ else
+ __aio_write_evt(kiocb->ki_ctx, &result_event);
+ }
+ }
+
+ spin_unlock_irq(&ctx->ctx_lock);
+
+ put_ioctx(ctx);
+
+ if (all_done)
+ return AIO_ALLDONE;
+
+ if (not_canceled)
+ return AIO_NOTCANCELED;
+
+ return AIO_CANCELED;
+}
+
/* sys_io_cancel:
* Attempts to cancel an iocb previously passed to io_submit. If
* the operation is successfully cancelled, the resulting event is
@@ -2041,9 +2119,9 @@
asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
struct io_event __user *result)
{
- int (*cancel)(struct kiocb *iocb, struct io_event *res);
struct kioctx *ctx;
struct kiocb *kiocb;
+ struct io_event tmp;
u32 key;
int ret;
@@ -2051,37 +2129,40 @@
if (unlikely(ret))
return -EFAULT;
+ if ( (key == 0) && (result == NULL) ) {
+ /* cancel all IOCBs belonging to iocb->aio_fildes */
+
+ ret = aio_cancel_fd(ctx_id, iocb->aio_fildes);
+
+ return ret;
+ }
+
ctx = lookup_ioctx(ctx_id);
if (unlikely(!ctx))
return -EINVAL;
spin_lock_irq(&ctx->ctx_lock);
- ret = -EAGAIN;
kiocb = lookup_kiocb(ctx, iocb, key);
- if (kiocb && kiocb->ki_cancel) {
- cancel = kiocb->ki_cancel;
- kiocb->ki_users ++;
- kiocbSetCancelled(kiocb);
- } else
- cancel = NULL;
spin_unlock_irq(&ctx->ctx_lock);
- if (NULL != cancel) {
- struct io_event tmp;
- pr_debug("calling cancel\n");
- memset(&tmp, 0, sizeof(tmp));
- tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user;
- tmp.data = kiocb->ki_user_data;
- ret = cancel(kiocb, &tmp);
- if (!ret) {
- /* Cancellation succeeded -- copy the result
- * into the user's buffer.
- */
+ if (kiocb == NULL) {
+ put_ioctx(ctx);
+ return -EINVAL;
+ }
+
+ ret = __aio_cancel(kiocb, &tmp);
+ if (!ret) {
+ /* Cancellation succeeded -- copy the result
+ * into the user's buffer.
+ */
+ if (result == NULL) {
+ spin_lock_irq(&ctx->ctx_lock);
+ __aio_write_evt(kiocb->ki_ctx, &tmp);
+ spin_unlock_irq(&ctx->ctx_lock);
+ } else
if (copy_to_user(result, &tmp, sizeof(tmp)))
ret = -EFAULT;
- }
- } else
- printk(KERN_DEBUG "iocb has no cancel operation\n");
+ }
put_ioctx(ctx);
Index: linux-2.6.12/include/linux/aio_abi.h
===================================================================
--- linux-2.6.12.orig/include/linux/aio_abi.h 2005-07-21 11:43:26.000000000 +0200
+++ linux-2.6.12/include/linux/aio_abi.h 2005-07-21 11:43:27.000000000 +0200
@@ -45,6 +45,12 @@
IOCB_CMD_CHECKPOINT = 8,
};
+enum {
+ AIO_CANCELED = 0,
+ AIO_NOTCANCELED = 1,
+ AIO_ALLDONE = 2,
+};
+
/* read() from /dev/aio returns these structures. */
struct io_event {
__u64 data; /* the data field from the iocb */
Index: linux-2.6.12/Makefile
===================================================================
--- linux-2.6.12.orig/Makefile 2005-07-21 11:43:26.000000000 +0200
+++ linux-2.6.12/Makefile 2005-07-21 11:43:27.000000000 +0200
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 12
-EXTRAVERSION = .PAIO-liowait
+EXTRAVERSION = .PAIO
NAME=Woozy Numbat
# *DOCUMENTATION*
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2005-07-28 15:48 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-28 15:46 [PATCH 5/5] Add support for AIO cancelation against a file descriptor Sébastien Dugué
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®