WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] Imported patch blktap-aio-16_03_06.pa

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] Imported patch blktap-aio-16_03_06.patch from xen-unstable.hg 15200:bd3d6b4c52ec
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 11 Jun 2007 02:22:48 -0700
Delivery-date: Mon, 11 Jun 2007 02:25:24 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Date 1180947923 -3600
# Node ID 4763065c587cb72db94f34670803cc9ad0e3041c
# Parent  405dae994591a785c16c59e50658bea7814b7000
Imported patch blktap-aio-16_03_06.patch from xen-unstable.hg 15200:bd3d6b4c52ec
---
 fs/aio.c                  |  119 ++++++++++++++++++++++++++++++++++++++++++----
 fs/eventpoll.c            |   18 +++---
 include/linux/aio.h       |    5 +
 include/linux/eventpoll.h |    6 ++
 4 files changed, 129 insertions(+), 19 deletions(-)

diff -r 405dae994591 -r 4763065c587c fs/aio.c
--- a/fs/aio.c  Mon Jun 04 10:05:23 2007 +0100
+++ b/fs/aio.c  Mon Jun 04 10:05:23 2007 +0100
@@ -33,6 +33,11 @@
 #include <asm/kmap_types.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
+
+#ifdef CONFIG_EPOLL
+#include <linux/poll.h>
+#include <linux/eventpoll.h>
+#endif
 
 #if DEBUG > 1
 #define dprintk                printk
@@ -1015,6 +1020,10 @@ put_rq:
        if (waitqueue_active(&ctx->wait))
                wake_up(&ctx->wait);
 
+#ifdef CONFIG_EPOLL
+       if (ctx->file && waitqueue_active(&ctx->poll_wait))
+               wake_up(&ctx->poll_wait);
+#endif
        if (ret)
                put_ioctx(ctx);
 
@@ -1024,6 +1033,8 @@ put_rq:
 /* aio_read_evt
  *     Pull an event off of the ioctx's event ring.  Returns the number of 
  *     events fetched (0 or 1 ;-)
+ *     If ent parameter is 0, just returns the number of events that would
+ *     be fetched.
  *     FIXME: make this use cmpxchg.
  *     TODO: make the ringbuffer user mmap()able (requires FIXME).
  */
@@ -1046,13 +1057,18 @@ static int aio_read_evt(struct kioctx *i
 
        head = ring->head % info->nr;
        if (head != ring->tail) {
-               struct io_event *evp = aio_ring_event(info, head, KM_USER1);
-               *ent = *evp;
-               head = (head + 1) % info->nr;
-               smp_mb(); /* finish reading the event before updatng the head */
-               ring->head = head;
-               ret = 1;
-               put_aio_ring_event(evp, KM_USER1);
+               if (ent) { /* event requested */
+                       struct io_event *evp =
+                               aio_ring_event(info, head, KM_USER1);
+                       *ent = *evp;
+                       head = (head + 1) % info->nr;
+                       /* finish reading the event before updatng the head */
+                       smp_mb();
+                       ring->head = head;
+                       ret = 1;
+                       put_aio_ring_event(evp, KM_USER1);
+               } else /* only need to know availability */
+                       ret = 1;
        }
        spin_unlock(&info->ring_lock);
 
@@ -1235,8 +1251,77 @@ static void io_destroy(struct kioctx *io
 
        aio_cancel_all(ioctx);
        wait_for_all_aios(ioctx);
+#ifdef CONFIG_EPOLL
+       /* forget the poll file, but it's up to the user to close it */
+       if (ioctx->file) {
+               ioctx->file->private_data = 0;
+               ioctx->file = 0;
+       }
+#endif
        put_ioctx(ioctx);       /* once for the lookup */
 }
+
+#ifdef CONFIG_EPOLL
+
+static int aio_queue_fd_close(struct inode *inode, struct file *file)
+{
+       struct kioctx *ioctx = file->private_data;
+       if (ioctx) {
+               file->private_data = 0;
+               spin_lock_irq(&ioctx->ctx_lock);
+               ioctx->file = 0;
+               spin_unlock_irq(&ioctx->ctx_lock);
+       }
+       return 0;
+}
+
+static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait)
+{      unsigned int pollflags = 0;
+       struct kioctx *ioctx = file->private_data;
+
+       if (ioctx) {
+
+               spin_lock_irq(&ioctx->ctx_lock);
+               /* Insert inside our poll wait queue */
+               poll_wait(file, &ioctx->poll_wait, wait);
+
+               /* Check our condition */
+               if (aio_read_evt(ioctx, 0))
+                       pollflags = POLLIN | POLLRDNORM;
+               spin_unlock_irq(&ioctx->ctx_lock);
+       }
+
+       return pollflags;
+}
+
+static const struct file_operations aioq_fops = {
+       .release        = aio_queue_fd_close,
+       .poll           = aio_queue_fd_poll
+};
+
+/* make_aio_fd:
+ *  Create a file descriptor that can be used to poll the event queue.
+ *  Based and piggybacked on the excellent epoll code.
+ */
+
+static int make_aio_fd(struct kioctx *ioctx)
+{
+       int error, fd;
+       struct inode *inode;
+       struct file *file;
+
+       error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops);
+       if (error)
+               return error;
+
+       /* associate the file with the IO context */
+       file->private_data = ioctx;
+       ioctx->file = file;
+       init_waitqueue_head(&ioctx->poll_wait);
+       return fd;
+}
+#endif
+
 
 /* sys_io_setup:
  *     Create an aio_context capable of receiving at least nr_events.
@@ -1250,18 +1335,30 @@ static void io_destroy(struct kioctx *io
  *     resources are available.  May fail with -EFAULT if an invalid
  *     pointer is passed for ctxp.  Will fail with -ENOSYS if not
  *     implemented.
+ *
+ *     To request a selectable fd, the user context has to be initialized
+ *     to 1, instead of 0, and the return value is the fd.
+ *     This keeps the system call compatible, since a non-zero value
+ *     was not allowed so far.
  */
 asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
 {
        struct kioctx *ioctx = NULL;
        unsigned long ctx;
        long ret;
+       int make_fd = 0;
 
        ret = get_user(ctx, ctxp);
        if (unlikely(ret))
                goto out;
 
        ret = -EINVAL;
+#ifdef CONFIG_EPOLL
+       if (ctx == 1) {
+               make_fd = 1;
+               ctx = 0;
+       }
+#endif
        if (unlikely(ctx || nr_events == 0)) {
                pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
                         ctx, nr_events);
@@ -1272,8 +1369,12 @@ asmlinkage long sys_io_setup(unsigned nr
        ret = PTR_ERR(ioctx);
        if (!IS_ERR(ioctx)) {
                ret = put_user(ioctx->user_id, ctxp);
-               if (!ret)
-                       return 0;
+#ifdef CONFIG_EPOLL
+               if (make_fd && ret >= 0)
+                       ret = make_aio_fd(ioctx);
+#endif
+               if (ret >= 0)
+                       return ret;
 
                get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
                io_destroy(ioctx);
diff -r 405dae994591 -r 4763065c587c fs/eventpoll.c
--- a/fs/eventpoll.c    Mon Jun 04 10:05:23 2007 +0100
+++ b/fs/eventpoll.c    Mon Jun 04 10:05:23 2007 +0100
@@ -236,8 +236,6 @@ struct ep_pqueue {
 
 static void ep_poll_safewake_init(struct poll_safewake *psw);
 static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
-                   struct eventpoll *ep);
 static int ep_alloc(struct eventpoll **pep);
 static void ep_free(struct eventpoll *ep);
 static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
@@ -267,7 +265,7 @@ static int ep_poll(struct eventpoll *ep,
 static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
                   int maxevents, long timeout);
 static int eventpollfs_delete_dentry(struct dentry *dentry);
-static struct inode *ep_eventpoll_inode(void);
+static struct inode *ep_eventpoll_inode(const struct file_operations *fops);
 static int eventpollfs_get_sb(struct file_system_type *fs_type,
                              int flags, const char *dev_name,
                              void *data, struct vfsmount *mnt);
@@ -517,7 +515,7 @@ asmlinkage long sys_epoll_create(int siz
         * Creates all the items needed to setup an eventpoll file. That is,
         * a file structure, and inode and a free file descriptor.
         */
-       error = ep_getfd(&fd, &inode, &file, ep);
+       error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops);
        if (error)
                goto eexit_2;
 
@@ -702,8 +700,8 @@ eexit_1:
 /*
  * Creates the file descriptor to be used by the epoll interface.
  */
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
-                   struct eventpoll *ep)
+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
+                   struct eventpoll *ep, const struct file_operations *fops)
 {
        struct qstr this;
        char name[32];
@@ -719,7 +717,7 @@ static int ep_getfd(int *efd, struct ino
                goto eexit_1;
 
        /* Allocates an inode from the eventpoll file system */
-       inode = ep_eventpoll_inode();
+       inode = ep_eventpoll_inode(fops);
        error = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto eexit_2;
@@ -750,7 +748,7 @@ static int ep_getfd(int *efd, struct ino
 
        file->f_pos = 0;
        file->f_flags = O_RDONLY;
-       file->f_op = &eventpoll_fops;
+       file->f_op = fops;
        file->f_mode = FMODE_READ;
        file->f_version = 0;
        file->private_data = ep;
@@ -1569,7 +1567,7 @@ static int eventpollfs_delete_dentry(str
 }
 
 
-static struct inode *ep_eventpoll_inode(void)
+static struct inode *ep_eventpoll_inode(const struct file_operations *fops)
 {
        int error = -ENOMEM;
        struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
@@ -1577,7 +1575,7 @@ static struct inode *ep_eventpoll_inode(
        if (!inode)
                goto eexit_1;
 
-       inode->i_fop = &eventpoll_fops;
+       inode->i_fop = fops;
 
        /*
         * Mark the inode dirty from the very beginning,
diff -r 405dae994591 -r 4763065c587c include/linux/aio.h
--- a/include/linux/aio.h       Mon Jun 04 10:05:23 2007 +0100
+++ b/include/linux/aio.h       Mon Jun 04 10:05:23 2007 +0100
@@ -191,6 +191,11 @@ struct kioctx {
        struct aio_ring_info    ring_info;
 
        struct work_struct      wq;
+#ifdef CONFIG_EPOLL
+       // poll integration
+       wait_queue_head_t       poll_wait;
+       struct file             *file;
+#endif
 };
 
 /* prototypes */
diff -r 405dae994591 -r 4763065c587c include/linux/eventpoll.h
--- a/include/linux/eventpoll.h Mon Jun 04 10:05:23 2007 +0100
+++ b/include/linux/eventpoll.h Mon Jun 04 10:05:23 2007 +0100
@@ -90,6 +90,12 @@ static inline void eventpoll_release(str
        eventpoll_release_file(file);
 }
 
+/*
+ * called by aio code to create fd that can poll the  aio event queueQ
+ */
+struct eventpoll;
+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
+             struct eventpoll *ep, const struct file_operations *fops);
 #else
 
 static inline void eventpoll_init_file(struct file *file) {}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] Imported patch blktap-aio-16_03_06.patch from xen-unstable.hg 15200:bd3d6b4c52ec, Xen patchbot-linux-2.6.18-xen <=