source: trunk/packages/xen-3.1/xen-3.1/patches/linux-2.6.18/blktap-aio-16_03_06.patch @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

  • Property svn:mime-type set to text/x-patch
File size: 8.7 KB
  • fs/aio.c

    diff -pruN ../orig-linux-2.6.18/fs/aio.c ./fs/aio.c
    old new  
    3434#include <asm/uaccess.h>
    3535#include <asm/mmu_context.h>
    3636
     37#ifdef CONFIG_EPOLL
     38#include <linux/poll.h>
     39#include <linux/eventpoll.h>
     40#endif
     41
    3742#if DEBUG > 1
    3843#define dprintk         printk
    3944#else
    put_rq: 
    10151020        if (waitqueue_active(&ctx->wait))
    10161021                wake_up(&ctx->wait);
    10171022
     1023#ifdef CONFIG_EPOLL
     1024        if (ctx->file && waitqueue_active(&ctx->poll_wait))
     1025                wake_up(&ctx->poll_wait);
     1026#endif
    10181027        if (ret)
    10191028                put_ioctx(ctx);
    10201029
    put_rq: 
    10241033/* aio_read_evt
    10251034 *      Pull an event off of the ioctx's event ring.  Returns the number of
    10261035 *      events fetched (0 or 1 ;-)
     1036 *      If ent parameter is 0, just returns the number of events that would
     1037 *      be fetched.
    10271038 *      FIXME: make this use cmpxchg.
    10281039 *      TODO: make the ringbuffer user mmap()able (requires FIXME).
    10291040 */
    static int aio_read_evt(struct kioctx *i 
    10461057
    10471058        head = ring->head % info->nr;
    10481059        if (head != ring->tail) {
    1049                 struct io_event *evp = aio_ring_event(info, head, KM_USER1);
    1050                 *ent = *evp;
    1051                 head = (head + 1) % info->nr;
    1052                 smp_mb(); /* finish reading the event before updatng the head */
    1053                 ring->head = head;
    1054                 ret = 1;
    1055                 put_aio_ring_event(evp, KM_USER1);
     1060                if (ent) { /* event requested */
     1061                        struct io_event *evp =
     1062                                aio_ring_event(info, head, KM_USER1);
     1063                        *ent = *evp;
     1064                        head = (head + 1) % info->nr;
     1065                        /* finish reading the event before updatng the head */
     1066                        smp_mb();
     1067                        ring->head = head;
     1068                        ret = 1;
     1069                        put_aio_ring_event(evp, KM_USER1);
     1070                } else /* only need to know availability */
     1071                        ret = 1;
    10561072        }
    10571073        spin_unlock(&info->ring_lock);
    10581074
    static void io_destroy(struct kioctx *io 
    12351251
    12361252        aio_cancel_all(ioctx);
    12371253        wait_for_all_aios(ioctx);
     1254#ifdef CONFIG_EPOLL
     1255        /* forget the poll file, but it's up to the user to close it */
     1256        if (ioctx->file) {
     1257                ioctx->file->private_data = 0;
     1258                ioctx->file = 0;
     1259        }
     1260#endif
    12381261        put_ioctx(ioctx);       /* once for the lookup */
    12391262}
    12401263
     1264#ifdef CONFIG_EPOLL
     1265
     1266static int aio_queue_fd_close(struct inode *inode, struct file *file)
     1267{
     1268        struct kioctx *ioctx = file->private_data;
     1269        if (ioctx) {
     1270                file->private_data = 0;
     1271                spin_lock_irq(&ioctx->ctx_lock);
     1272                ioctx->file = 0;
     1273                spin_unlock_irq(&ioctx->ctx_lock);
     1274        }
     1275        return 0;
     1276}
     1277
     1278static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait)
     1279{       unsigned int pollflags = 0;
     1280        struct kioctx *ioctx = file->private_data;
     1281
     1282        if (ioctx) {
     1283
     1284                spin_lock_irq(&ioctx->ctx_lock);
     1285                /* Insert inside our poll wait queue */
     1286                poll_wait(file, &ioctx->poll_wait, wait);
     1287
     1288                /* Check our condition */
     1289                if (aio_read_evt(ioctx, 0))
     1290                        pollflags = POLLIN | POLLRDNORM;
     1291                spin_unlock_irq(&ioctx->ctx_lock);
     1292        }
     1293
     1294        return pollflags;
     1295}
     1296
     1297static const struct file_operations aioq_fops = {
     1298        .release        = aio_queue_fd_close,
     1299        .poll           = aio_queue_fd_poll
     1300};
     1301
     1302/* make_aio_fd:
     1303 *  Create a file descriptor that can be used to poll the event queue.
     1304 *  Based and piggybacked on the excellent epoll code.
     1305 */
     1306
     1307static int make_aio_fd(struct kioctx *ioctx)
     1308{
     1309        int error, fd;
     1310        struct inode *inode;
     1311        struct file *file;
     1312
     1313        error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops);
     1314        if (error)
     1315                return error;
     1316
     1317        /* associate the file with the IO context */
     1318        file->private_data = ioctx;
     1319        ioctx->file = file;
     1320        init_waitqueue_head(&ioctx->poll_wait);
     1321        return fd;
     1322}
     1323#endif
     1324
     1325
    12411326/* sys_io_setup:
    12421327 *      Create an aio_context capable of receiving at least nr_events.
    12431328 *      ctxp must not point to an aio_context that already exists, and
    static void io_destroy(struct kioctx *io 
    12501335 *      resources are available.  May fail with -EFAULT if an invalid
    12511336 *      pointer is passed for ctxp.  Will fail with -ENOSYS if not
    12521337 *      implemented.
     1338 *
     1339 *      To request a selectable fd, the user context has to be initialized
     1340 *      to 1, instead of 0, and the return value is the fd.
     1341 *      This keeps the system call compatible, since a non-zero value
     1342 *      was not allowed so far.
    12531343 */
    12541344asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
    12551345{
    12561346        struct kioctx *ioctx = NULL;
    12571347        unsigned long ctx;
    12581348        long ret;
     1349        int make_fd = 0;
    12591350
    12601351        ret = get_user(ctx, ctxp);
    12611352        if (unlikely(ret))
    12621353                goto out;
    12631354
    12641355        ret = -EINVAL;
     1356#ifdef CONFIG_EPOLL
     1357        if (ctx == 1) {
     1358                make_fd = 1;
     1359                ctx = 0;
     1360        }
     1361#endif
    12651362        if (unlikely(ctx || nr_events == 0)) {
    12661363                pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
    12671364                         ctx, nr_events);
    asmlinkage long sys_io_setup(unsigned nr 
    12721369        ret = PTR_ERR(ioctx);
    12731370        if (!IS_ERR(ioctx)) {
    12741371                ret = put_user(ioctx->user_id, ctxp);
    1275                 if (!ret)
    1276                         return 0;
     1372#ifdef CONFIG_EPOLL
     1373                if (make_fd && ret >= 0)
     1374                        ret = make_aio_fd(ioctx);
     1375#endif
     1376                if (ret >= 0)
     1377                        return ret;
    12771378
    12781379                get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
    12791380                io_destroy(ioctx);
  • fs/eventpoll.c

    diff -pruN ../orig-linux-2.6.18/fs/eventpoll.c ./fs/eventpoll.c
    old new struct ep_pqueue { 
    236236
    237237static void ep_poll_safewake_init(struct poll_safewake *psw);
    238238static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
    239 static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
    240                     struct eventpoll *ep);
    241239static int ep_alloc(struct eventpoll **pep);
    242240static void ep_free(struct eventpoll *ep);
    243241static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
    static int ep_events_transfer(struct eve 
    267265static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
    268266                   int maxevents, long timeout);
    269267static int eventpollfs_delete_dentry(struct dentry *dentry);
    270 static struct inode *ep_eventpoll_inode(void);
     268static struct inode *ep_eventpoll_inode(const struct file_operations *fops);
    271269static int eventpollfs_get_sb(struct file_system_type *fs_type,
    272270                              int flags, const char *dev_name,
    273271                              void *data, struct vfsmount *mnt);
    asmlinkage long sys_epoll_create(int siz 
    517515         * Creates all the items needed to setup an eventpoll file. That is,
    518516         * a file structure, and inode and a free file descriptor.
    519517         */
    520         error = ep_getfd(&fd, &inode, &file, ep);
     518        error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops);
    521519        if (error)
    522520                goto eexit_2;
    523521
    eexit_1: 
    702700/*
    703701 * Creates the file descriptor to be used by the epoll interface.
    704702 */
    705 static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
    706                     struct eventpoll *ep)
     703int ep_getfd(int *efd, struct inode **einode, struct file **efile,
     704                    struct eventpoll *ep, const struct file_operations *fops)
    707705{
    708706        struct qstr this;
    709707        char name[32];
    static int ep_getfd(int *efd, struct ino 
    719717                goto eexit_1;
    720718
    721719        /* Allocates an inode from the eventpoll file system */
    722         inode = ep_eventpoll_inode();
     720        inode = ep_eventpoll_inode(fops);
    723721        error = PTR_ERR(inode);
    724722        if (IS_ERR(inode))
    725723                goto eexit_2;
    static int ep_getfd(int *efd, struct ino 
    750748
    751749        file->f_pos = 0;
    752750        file->f_flags = O_RDONLY;
    753         file->f_op = &eventpoll_fops;
     751        file->f_op = fops;
    754752        file->f_mode = FMODE_READ;
    755753        file->f_version = 0;
    756754        file->private_data = ep;
    static int eventpollfs_delete_dentry(str 
    15691567}
    15701568
    15711569
    1572 static struct inode *ep_eventpoll_inode(void)
     1570static struct inode *ep_eventpoll_inode(const struct file_operations *fops)
    15731571{
    15741572        int error = -ENOMEM;
    15751573        struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
    static struct inode *ep_eventpoll_inode( 
    15771575        if (!inode)
    15781576                goto eexit_1;
    15791577
    1580         inode->i_fop = &eventpoll_fops;
     1578        inode->i_fop = fops;
    15811579
    15821580        /*
    15831581         * Mark the inode dirty from the very beginning,
  • include/linux/aio.h

    diff -pruN ../orig-linux-2.6.18/include/linux/aio.h ./include/linux/aio.h
    old new struct kioctx { 
    191191        struct aio_ring_info    ring_info;
    192192
    193193        struct work_struct      wq;
     194#ifdef CONFIG_EPOLL
     195        // poll integration
     196        wait_queue_head_t       poll_wait;
     197        struct file             *file;
     198#endif
    194199};
    195200
    196201/* prototypes */
  • include/linux/eventpoll.h

    diff -pruN ../orig-linux-2.6.18/include/linux/eventpoll.h ./include/linux/eventpoll.h
    old new static inline void eventpoll_release(str 
    9090        eventpoll_release_file(file);
    9191}
    9292
     93/*
     94 * called by aio code to create fd that can poll the  aio event queueQ
     95 */
     96struct eventpoll;
     97int ep_getfd(int *efd, struct inode **einode, struct file **efile,
     98             struct eventpoll *ep, const struct file_operations *fops);
    9399#else
    94100
    95101static inline void eventpoll_init_file(struct file *file) {}
Note: See TracBrowser for help on using the repository browser.