X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Feventpoll.c;fp=fs%2Feventpoll.c;h=4284cd31eba6dcb6f125f1fd574aa2213439b45f;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=8d544334bcd22d216b057620900834e73b756698;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 8d544334b..4284cd31e 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1,6 +1,6 @@ /* * fs/eventpoll.c ( Efficent event polling implementation ) - * Copyright (C) 2001,...,2006 Davide Libenzi + * Copyright (C) 2001,...,2003 Davide Libenzi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -47,7 +46,7 @@ * LOCKING: * There are three level of locking required by epoll : * - * 1) epmutex (mutex) + * 1) epsem (semaphore) * 2) ep->sem (rw_semaphore) * 3) ep->lock (rw_lock) * @@ -68,9 +67,9 @@ * if a file has been pushed inside an epoll set and it is then * close()d without a previous call toepoll_ctl(EPOLL_CTL_DEL). * It is possible to drop the "ep->sem" and to use the global - * semaphore "epmutex" (together with "ep->lock") to have it working, + * semaphore "epsem" (together with "ep->lock") to have it working, * but having "ep->sem" will make the interface more scalable. - * Events that require holding "epmutex" are very rare, while for + * Events that require holding "epsem" are very rare, while for * normal operations the epoll private "ep->sem" will guarantee * a greater scalability. */ @@ -120,7 +119,7 @@ struct epoll_filefd { */ struct wake_task_node { struct list_head llink; - struct task_struct *task; + task_t *task; wait_queue_head_t *wq; }; @@ -268,29 +267,29 @@ 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 int eventpollfs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, - void *data, struct vfsmount *mnt); +static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data); /* * This semaphore is used to serialize ep_free() and eventpoll_release_file(). */ -static struct mutex epmutex; +static struct semaphore epsem; /* Safe wake up implementation */ static struct poll_safewake psw; /* Slab cache used to allocate "struct epitem" */ -static kmem_cache_t *epi_cache __read_mostly; +static kmem_cache_t *epi_cache; /* Slab cache used to allocate "struct eppoll_entry" */ -static kmem_cache_t *pwq_cache __read_mostly; +static kmem_cache_t *pwq_cache; /* Virtual fs used to allocate inodes for eventpoll files */ -static struct vfsmount *eventpoll_mnt __read_mostly; +static struct vfsmount *eventpoll_mnt; /* File callbacks that implement the eventpoll file behaviour */ -static const struct file_operations eventpoll_fops = { +static struct file_operations eventpoll_fops = { .release = ep_eventpoll_close, .poll = ep_eventpoll_poll }; @@ -337,20 +336,20 @@ static inline int ep_cmp_ffd(struct epoll_filefd *p1, /* Special initialization for the rb-tree node to detect linkage */ static inline void ep_rb_initnode(struct rb_node *n) { - rb_set_parent(n, n); + n->rb_parent = n; } /* Removes a node from the rb-tree and marks it for a fast is-linked check */ static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r) { rb_erase(n, r); - rb_set_parent(n, n); + n->rb_parent = n; } /* Fast check to verify that the item is linked to the main rb-tree */ static inline int ep_rb_linked(struct rb_node *n) { - return rb_parent(n) != n; + return n->rb_parent != n; } /* @@ -413,7 +412,7 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq) { int wake_nests = 0; unsigned long flags; - struct task_struct *this_task = current; + task_t *this_task = current; struct list_head *lsthead = &psw->wake_task_list, *lnk; struct wake_task_node *tncur; struct wake_task_node tnode; @@ -452,6 +451,15 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq) } +/* Used to initialize the epoll bits inside the "struct file" */ +void eventpoll_init_file(struct file *file) +{ + + INIT_LIST_HEAD(&file->f_ep_links); + spin_lock_init(&file->f_ep_lock); +} + + /* * This is called from eventpoll_release() to unlink files from the eventpoll * interface. We need to have this facility to cleanup correctly files that are @@ -469,10 +477,10 @@ void eventpoll_release_file(struct file *file) * cleanup path, and this means that noone is using this file anymore. * The only hit might come from ep_free() but by holding the semaphore * will correctly serialize the operation. We do need to acquire - * "ep->sem" after "epmutex" because ep_remove() requires it when called + * "ep->sem" after "epsem" because ep_remove() requires it when called * from anywhere but ep_free(). */ - mutex_lock(&epmutex); + down(&epsem); while (!list_empty(lsthead)) { epi = list_entry(lsthead->next, struct epitem, fllink); @@ -484,7 +492,7 @@ void eventpoll_release_file(struct file *file) up_write(&ep->sem); } - mutex_unlock(&epmutex); + up(&epsem); } @@ -811,9 +819,9 @@ static void ep_free(struct eventpoll *ep) * We do not need to hold "ep->sem" here because the epoll file * is on the way to be removed and no one has references to it * anymore. The only hit might come from eventpoll_release_file() but - * holding "epmutex" is sufficent here. + * holding "epsem" is sufficent here. */ - mutex_lock(&epmutex); + down(&epsem); /* * Walks through the whole tree by unregistering poll callbacks. @@ -835,7 +843,7 @@ static void ep_free(struct eventpoll *ep) ep_remove(ep, epi); } - mutex_unlock(&epmutex); + up(&epsem); } @@ -1004,7 +1012,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, /* Notify waiting tasks that events are available */ if (waitqueue_active(&ep->wq)) - __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE); + wake_up(&ep->wq); if (waitqueue_active(&ep->poll_wait)) pwake++; } @@ -1083,8 +1091,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even /* Notify waiting tasks that events are available */ if (waitqueue_active(&ep->wq)) - __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE | - TASK_INTERRUPTIBLE); + wake_up(&ep->wq); if (waitqueue_active(&ep->poll_wait)) pwake++; } @@ -1168,7 +1175,7 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi) eexit_1: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n", - current, ep, epi->ffd.file, error)); + current, ep, epi->file, error)); return error; } @@ -1236,7 +1243,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k struct eventpoll *ep = epi->ep; DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n", - current, epi->ffd.file, epi, ep)); + current, epi->file, epi, ep)); write_lock_irqsave(&ep->lock, flags); @@ -1261,8 +1268,7 @@ is_linked: * wait list. */ if (waitqueue_active(&ep->wq)) - __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE | - TASK_INTERRUPTIBLE); + wake_up(&ep->wq); if (waitqueue_active(&ep->poll_wait)) pwake++; @@ -1446,8 +1452,7 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist) * wait list. */ if (waitqueue_active(&ep->wq)) - __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE | - TASK_INTERRUPTIBLE); + wake_up(&ep->wq); if (waitqueue_active(&ep->poll_wait)) pwake++; } @@ -1519,7 +1524,7 @@ retry: * ep_poll_callback() when events will become available. */ init_waitqueue_entry(&wait, current); - __add_wait_queue(&ep->wq, &wait); + add_wait_queue(&ep->wq, &wait); for (;;) { /* @@ -1539,7 +1544,7 @@ retry: jtimeout = schedule_timeout(jtimeout); write_lock_irqsave(&ep->lock, flags); } - __remove_wait_queue(&ep->wq, &wait); + remove_wait_queue(&ep->wq, &wait); set_current_state(TASK_RUNNING); } @@ -1590,6 +1595,7 @@ static struct inode *ep_eventpoll_inode(void) inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_blksize = PAGE_SIZE; return inode; eexit_1: @@ -1597,12 +1603,11 @@ eexit_1: } -static int +static struct super_block * eventpollfs_get_sb(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data, struct vfsmount *mnt) + const char *dev_name, void *data) { - return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC, - mnt); + return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC); } @@ -1610,7 +1615,7 @@ static int __init eventpoll_init(void) { int error; - mutex_init(&epmutex); + init_MUTEX(&epsem); /* Initialize the structure used to perform safe poll wait head wake ups */ ep_poll_safewake_init(&psw);