mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Sébastien Dugué" <sebastien.dugue@bull.net>
To: "linux-aio kvack.org" <linux-aio@kvack.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [PATCH 5/5] Add support for AIO cancelation against a file descriptor
Date: Thu, 28 Jul 2005 17:46:40 +0200	[thread overview]
Message-ID: <1122565600.2019.85.camel@frecb000686> (raw)

[-- 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*

                 reply	other threads:[~2005-07-28 15:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1122565600.2019.85.camel@frecb000686 \
    --to=sebastien.dugue@bull.net \
    --cc=linux-aio@kvack.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®