]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/eventpoll.c
epoll: use anonymous inodes
[linux-2.6-omap-h63xx.git] / fs / eventpoll.c
index 3ae644e7e8606cddcdc1cb02791e51dfc73cb941..2831c8f9f3e356ff10b7f76f95a2c0c1addcdd08 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/hash.h>
@@ -35,6 +34,7 @@
 #include <linux/mount.h>
 #include <linux/bitops.h>
 #include <linux/mutex.h>
+#include <linux/anon_inodes.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -76,8 +76,6 @@
  */
 
 
-#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
-
 #define DEBUG_EPOLL 0
 
 #if DEBUG_EPOLL > 0
@@ -185,7 +183,7 @@ struct eppoll_entry {
 
 /*
  * Each file descriptor added to the eventpoll interface will
- * have an entry of this type linked to the hash.
+ * have an entry of this type linked to the "rbr" RB tree.
  */
 struct epitem {
        /* RB-Tree node used to link this structure to the eventpoll rb-tree */
@@ -217,15 +215,6 @@ struct epitem {
 
        /* List header used to link this item to the "struct file" items list */
        struct list_head fllink;
-
-       /* List header used to link the item to the transfer list */
-       struct list_head txlink;
-
-       /*
-        * This is used during the collection/transfer of events to userspace
-        * to pin items empty events set.
-        */
-       unsigned int revents;
 };
 
 /* Wrapper struct used by poll queueing */
@@ -238,8 +227,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);
@@ -258,21 +245,13 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi);
 static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key);
 static int ep_eventpoll_close(struct inode *inode, struct file *file);
 static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
-static int ep_collect_ready_items(struct eventpoll *ep,
-                                 struct list_head *txlist, int maxevents);
 static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
-                         struct epoll_event __user *events);
-static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist);
+                         struct epoll_event __user *events, int maxevents);
 static int ep_events_transfer(struct eventpoll *ep,
                              struct epoll_event __user *events,
                              int maxevents);
 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);
 
 /*
  * This semaphore is used to serialize ep_free() and eventpoll_release_file().
@@ -288,30 +267,12 @@ static struct kmem_cache *epi_cache __read_mostly;
 /* Slab cache used to allocate "struct eppoll_entry" */
 static struct kmem_cache *pwq_cache __read_mostly;
 
-/* Virtual fs used to allocate inodes for eventpoll files */
-static struct vfsmount *eventpoll_mnt __read_mostly;
-
 /* File callbacks that implement the eventpoll file behaviour */
 static const struct file_operations eventpoll_fops = {
        .release        = ep_eventpoll_close,
        .poll           = ep_eventpoll_poll
 };
 
-/*
- * This is used to register the virtual file system from where
- * eventpoll inodes are allocated.
- */
-static struct file_system_type eventpoll_fs_type = {
-       .name           = "eventpollfs",
-       .get_sb         = eventpollfs_get_sb,
-       .kill_sb        = kill_anon_super,
-};
-
-/* Very basic directory entry operations for the eventpoll virtual file system */
-static struct dentry_operations eventpollfs_dentry_operations = {
-       .d_delete       = eventpollfs_delete_dentry,
-};
-
 
 
 /* Fast test to see if the file is an evenpoll file */
@@ -355,17 +316,6 @@ static inline int ep_rb_linked(struct rb_node *n)
        return rb_parent(n) != n;
 }
 
-/*
- * Remove the item from the list and perform its initialization.
- * This is useful for us because we can test if the item is linked
- * using "ep_is_linked(p)".
- */
-static inline void ep_list_del(struct list_head *p)
-{
-       list_del(p);
-       INIT_LIST_HEAD(p);
-}
-
 /* Tells us if the item is currently linked */
 static inline int ep_is_linked(struct list_head *p)
 {
@@ -385,7 +335,7 @@ static inline struct epitem * ep_item_from_epqueue(poll_table *p)
 }
 
 /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
-static inline int ep_op_hash_event(int op)
+static inline int ep_op_has_event(int op)
 {
        return op != EPOLL_CTL_DEL;
 }
@@ -477,10 +427,10 @@ void eventpoll_release_file(struct file *file)
        mutex_lock(&epmutex);
 
        while (!list_empty(lsthead)) {
-               epi = list_entry(lsthead->next, struct epitem, fllink);
+               epi = list_first_entry(lsthead, struct epitem, fllink);
 
                ep = epi->ep;
-               ep_list_del(&epi->fllink);
+               list_del_init(&epi->fllink);
                down_write(&ep->sem);
                ep_remove(ep, epi);
                up_write(&ep->sem);
@@ -519,7 +469,8 @@ asmlinkage long sys_epoll_create(int size)
         * 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 = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]",
+                                &eventpoll_fops, ep);
        if (error)
                goto eexit_2;
 
@@ -557,7 +508,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
                     current, epfd, op, fd, event));
 
        error = -EFAULT;
-       if (ep_op_hash_event(op) &&
+       if (ep_op_has_event(op) &&
            copy_from_user(&epds, event, sizeof(struct epoll_event)))
                goto eexit_1;
 
@@ -594,7 +545,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
 
        down_write(&ep->sem);
 
-       /* Try to lookup the file inside our hash table */
+       /* Try to lookup the file inside our RB tree */
        epi = ep_find(ep, tfile, fd);
 
        error = -EINVAL;
@@ -749,82 +700,6 @@ asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
 #endif /* #ifdef TIF_RESTORE_SIGMASK */
 
 
-/*
- * 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)
-{
-       struct qstr this;
-       char name[32];
-       struct dentry *dentry;
-       struct inode *inode;
-       struct file *file;
-       int error, fd;
-
-       /* Get an ready to use file */
-       error = -ENFILE;
-       file = get_empty_filp();
-       if (!file)
-               goto eexit_1;
-
-       /* Allocates an inode from the eventpoll file system */
-       inode = ep_eventpoll_inode();
-       if (IS_ERR(inode)) {
-               error = PTR_ERR(inode);
-               goto eexit_2;
-       }
-
-       /* Allocates a free descriptor to plug the file onto */
-       error = get_unused_fd();
-       if (error < 0)
-               goto eexit_3;
-       fd = error;
-
-       /*
-        * Link the inode to a directory entry by creating a unique name
-        * using the inode number.
-        */
-       error = -ENOMEM;
-       sprintf(name, "[%lu]", inode->i_ino);
-       this.name = name;
-       this.len = strlen(name);
-       this.hash = inode->i_ino;
-       dentry = d_alloc(eventpoll_mnt->mnt_sb->s_root, &this);
-       if (!dentry)
-               goto eexit_4;
-       dentry->d_op = &eventpollfs_dentry_operations;
-       d_add(dentry, inode);
-       file->f_path.mnt = mntget(eventpoll_mnt);
-       file->f_path.dentry = dentry;
-       file->f_mapping = inode->i_mapping;
-
-       file->f_pos = 0;
-       file->f_flags = O_RDONLY;
-       file->f_op = &eventpoll_fops;
-       file->f_mode = FMODE_READ;
-       file->f_version = 0;
-       file->private_data = ep;
-
-       /* Install the new setup file into the allocated fd. */
-       fd_install(fd, file);
-
-       *efd = fd;
-       *einode = inode;
-       *efile = file;
-       return 0;
-
-eexit_4:
-       put_unused_fd(fd);
-eexit_3:
-       iput(inode);
-eexit_2:
-       put_filp(file);
-eexit_1:
-       return error;
-}
-
-
 static int ep_alloc(struct eventpoll **pep)
 {
        struct eventpoll *ep = kzalloc(sizeof(*ep), GFP_KERNEL);
@@ -876,7 +751,7 @@ static void ep_free(struct eventpoll *ep)
        }
 
        /*
-        * Walks through the whole hash by freeing each "struct epitem". At this
+        * Walks through the whole tree by freeing each "struct epitem". At this
         * point we are sure no poll callbacks will be lingering around, and also by
         * write-holding "sem" we can be sure that no file cleanup code will hit
         * us during this operation. So we can avoid the lock on "ep->lock".
@@ -891,7 +766,7 @@ static void ep_free(struct eventpoll *ep)
 
 
 /*
- * Search the file inside the eventpoll hash. It add usage count to
+ * Search the file inside the eventpoll tree. It add usage count to
  * the returned item, so the caller must call ep_release_epitem()
  * after finished using the "struct epitem".
  */
@@ -1011,7 +886,6 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
        ep_rb_initnode(&epi->rbn);
        INIT_LIST_HEAD(&epi->rdllink);
        INIT_LIST_HEAD(&epi->fllink);
-       INIT_LIST_HEAD(&epi->txlink);
        INIT_LIST_HEAD(&epi->pwqlist);
        epi->ep = ep;
        ep_set_ffd(&epi->ffd, tfile, fd);
@@ -1080,7 +954,7 @@ eexit_2:
         */
        write_lock_irqsave(&ep->lock, flags);
        if (ep_is_linked(&epi->rdllink))
-               ep_list_del(&epi->rdllink);
+               list_del_init(&epi->rdllink);
        write_unlock_irqrestore(&ep->lock, flags);
 
        kmem_cache_free(epi_cache, epi);
@@ -1119,7 +993,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
        epi->event.data = event->data;
 
        /*
-        * If the item is not linked to the hash it means that it's on its
+        * If the item is not linked to the RB tree it means that it's on its
         * way toward the removal. Do nothing in this case.
         */
        if (ep_rb_linked(&epi->rbn)) {
@@ -1168,9 +1042,9 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
 
        if (nwait) {
                while (!list_empty(lsthead)) {
-                       pwq = list_entry(lsthead->next, struct eppoll_entry, llink);
+                       pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
 
-                       ep_list_del(&pwq->llink);
+                       list_del_init(&pwq->llink);
                        remove_wait_queue(pwq->whead, &pwq->wait);
                        kmem_cache_free(pwq_cache, pwq);
                }
@@ -1213,7 +1087,7 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
         * we want to remove it from this list to avoid stale events.
         */
        if (ep_is_linked(&epi->rdllink))
-               ep_list_del(&epi->rdllink);
+               list_del_init(&epi->rdllink);
 
        error = 0;
 eexit_1:
@@ -1226,7 +1100,7 @@ eexit_1:
 
 
 /*
- * Removes a "struct epitem" from the eventpoll hash and deallocates
+ * Removes a "struct epitem" from the eventpoll RB tree and deallocates
  * all the associated resources.
  */
 static int ep_remove(struct eventpoll *ep, struct epitem *epi)
@@ -1248,13 +1122,13 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
        /* Remove the current item from the list of epoll hooks */
        spin_lock(&file->f_ep_lock);
        if (ep_is_linked(&epi->fllink))
-               ep_list_del(&epi->fllink);
+               list_del_init(&epi->fllink);
        spin_unlock(&file->f_ep_lock);
 
        /* We need to acquire the write IRQ lock before calling ep_unlink() */
        write_lock_irqsave(&ep->lock, flags);
 
-       /* Really unlink the item from the hash */
+       /* Really unlink the item from the RB tree */
        error = ep_unlink(ep, epi);
 
        write_unlock_irqrestore(&ep->lock, flags);
@@ -1361,72 +1235,31 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
 }
 
 
-/*
- * Since we have to release the lock during the __copy_to_user() operation and
- * during the f_op->poll() call, we try to collect the maximum number of items
- * by reducing the irqlock/irqunlock switching rate.
- */
-static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist, int maxevents)
-{
-       int nepi;
-       unsigned long flags;
-       struct list_head *lsthead = &ep->rdllist, *lnk;
-       struct epitem *epi;
-
-       write_lock_irqsave(&ep->lock, flags);
-
-       for (nepi = 0, lnk = lsthead->next; lnk != lsthead && nepi < maxevents;) {
-               epi = list_entry(lnk, struct epitem, rdllink);
-
-               lnk = lnk->next;
-
-               /* If this file is already in the ready list we exit soon */
-               if (!ep_is_linked(&epi->txlink)) {
-                       /*
-                        * This is initialized in this way so that the default
-                        * behaviour of the reinjecting code will be to push back
-                        * the item inside the ready list.
-                        */
-                       epi->revents = epi->event.events;
-
-                       /* Link the ready item into the transfer list */
-                       list_add(&epi->txlink, txlist);
-                       nepi++;
-
-                       /*
-                        * Unlink the item from the ready list.
-                        */
-                       ep_list_del(&epi->rdllink);
-               }
-       }
-
-       write_unlock_irqrestore(&ep->lock, flags);
-
-       return nepi;
-}
-
-
 /*
  * This function is called without holding the "ep->lock" since the call to
  * __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ
  * because of the way poll() is traditionally implemented in Linux.
  */
 static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
-                         struct epoll_event __user *events)
+                         struct epoll_event __user *events, int maxevents)
 {
-       int eventcnt = 0;
+       int eventcnt, error = -EFAULT, pwake = 0;
        unsigned int revents;
-       struct list_head *lnk;
+       unsigned long flags;
        struct epitem *epi;
+       struct list_head injlist;
+
+       INIT_LIST_HEAD(&injlist);
 
        /*
         * We can loop without lock because this is a task private list.
-        * The test done during the collection loop will guarantee us that
-        * another task will not try to collect this file. Also, items
-        * cannot vanish during the loop because we are holding "sem".
+        * We just splice'd out the ep->rdllist in ep_collect_ready_items().
+        * Items cannot vanish during the loop because we are holding "sem" in
+        * read.
         */
-       list_for_each(lnk, txlist) {
-               epi = list_entry(lnk, struct epitem, txlink);
+       for (eventcnt = 0; !list_empty(txlist) && eventcnt < maxevents;) {
+               epi = list_first_entry(txlist, struct epitem, rdllink);
+               prefetch(epi->rdllink.next);
 
                /*
                 * Get the ready file event set. We can safely use the file
@@ -1434,64 +1267,65 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
                 * guarantee that both the file and the item will not vanish.
                 */
                revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
+               revents &= epi->event.events;
 
                /*
-                * Set the return event set for the current file descriptor.
-                * Note that only the task task was successfully able to link
-                * the item to its "txlist" will write this field.
+                * Is the event mask intersect the caller-requested one,
+                * deliver the event to userspace. Again, we are holding
+                * "sem" in read, so no operations coming from userspace
+                * can change the item.
                 */
-               epi->revents = revents & epi->event.events;
-
-               if (epi->revents) {
-                       if (__put_user(epi->revents,
+               if (revents) {
+                       if (__put_user(revents,
                                       &events[eventcnt].events) ||
                            __put_user(epi->event.data,
                                       &events[eventcnt].data))
-                               return -EFAULT;
+                               goto errxit;
                        if (epi->event.events & EPOLLONESHOT)
                                epi->event.events &= EP_PRIVATE_BITS;
                        eventcnt++;
                }
-       }
-       return eventcnt;
-}
-
-
-/*
- * Walk through the transfer list we collected with ep_collect_ready_items()
- * and, if 1) the item is still "alive" 2) its event set is not empty 3) it's
- * not already linked, links it to the ready list. Same as above, we are holding
- * "sem" so items cannot vanish underneath our nose.
- */
-static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
-{
-       int ricnt = 0, pwake = 0;
-       unsigned long flags;
-       struct epitem *epi;
-
-       write_lock_irqsave(&ep->lock, flags);
-
-       while (!list_empty(txlist)) {
-               epi = list_entry(txlist->next, struct epitem, txlink);
-
-               /* Unlink the current item from the transfer list */
-               ep_list_del(&epi->txlink);
 
                /*
-                * If the item is no more linked to the interest set, we don't
-                * have to push it inside the ready list because the following
-                * ep_release_epitem() is going to drop it. Also, if the current
-                * item is set to have an Edge Triggered behaviour, we don't have
-                * to push it back either.
+                * This is tricky. We are holding the "sem" in read, and this
+                * means that the operations that can change the "linked" status
+                * of the epoll item (epi->rbn and epi->rdllink), cannot touch
+                * them.  Also, since we are "linked" from a epi->rdllink POV
+                * (the item is linked to our transmission list we just
+                * spliced), the ep_poll_callback() cannot touch us either,
+                * because of the check present in there. Another parallel
+                * epoll_wait() will not get the same result set, since we
+                * spliced the ready list before.  Note that list_del() still
+                * shows the item as linked to the test in ep_poll_callback().
                 */
-               if (ep_rb_linked(&epi->rbn) && !(epi->event.events & EPOLLET) &&
-                   (epi->revents & epi->event.events) && !ep_is_linked(&epi->rdllink)) {
-                       list_add_tail(&epi->rdllink, &ep->rdllist);
-                       ricnt++;
+               list_del(&epi->rdllink);
+               if (!(epi->event.events & EPOLLET) &&
+                               (revents & epi->event.events))
+                       list_add_tail(&epi->rdllink, &injlist);
+               else {
+                       /*
+                        * Be sure the item is totally detached before re-init
+                        * the list_head. After INIT_LIST_HEAD() is committed,
+                        * the ep_poll_callback() can requeue the item again,
+                        * but we don't care since we are already past it.
+                        */
+                       smp_mb();
+                       INIT_LIST_HEAD(&epi->rdllink);
                }
        }
+       error = 0;
+
+       errxit:
 
-       if (ricnt) {
+       /*
+        * If the re-injection list or the txlist are not empty, re-splice
+        * them to the ready list and do proper wakeups.
+        */
+       if (!list_empty(&injlist) || !list_empty(txlist)) {
+               write_lock_irqsave(&ep->lock, flags);
+
+               list_splice(txlist, &ep->rdllist);
+               list_splice(&injlist, &ep->rdllist);
                /*
                 * Wake up ( if active ) both the eventpoll wait list and the ->poll()
                 * wait list.
@@ -1501,13 +1335,15 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
                                         TASK_INTERRUPTIBLE);
                if (waitqueue_active(&ep->poll_wait))
                        pwake++;
-       }
 
-       write_unlock_irqrestore(&ep->lock, flags);
+               write_unlock_irqrestore(&ep->lock, flags);
+       }
 
        /* We have to call this outside the lock */
        if (pwake)
                ep_poll_safewake(&psw, &ep->poll_wait);
+
+       return eventcnt == 0 ? error: eventcnt;
 }
 
 
@@ -1517,7 +1353,8 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
 static int ep_events_transfer(struct eventpoll *ep,
                              struct epoll_event __user *events, int maxevents)
 {
-       int eventcnt = 0;
+       int eventcnt;
+       unsigned long flags;
        struct list_head txlist;
 
        INIT_LIST_HEAD(&txlist);
@@ -1528,14 +1365,17 @@ static int ep_events_transfer(struct eventpoll *ep,
         */
        down_read(&ep->sem);
 
-       /* Collect/extract ready items */
-       if (ep_collect_ready_items(ep, &txlist, maxevents) > 0) {
-               /* Build result set in userspace */
-               eventcnt = ep_send_events(ep, &txlist, events);
+       /*
+        * Steal the ready list, and re-init the original one to the
+        * empty list.
+        */
+       write_lock_irqsave(&ep->lock, flags);
+       list_splice(&ep->rdllist, &txlist);
+       INIT_LIST_HEAD(&ep->rdllist);
+       write_unlock_irqrestore(&ep->lock, flags);
 
-               /* Reinject ready items into the ready list */
-               ep_reinject_items(ep, &txlist);
-       }
+       /* Build result set in userspace */
+       eventcnt = ep_send_events(ep, &txlist, events, maxevents);
 
        up_read(&ep->sem);
 
@@ -1612,55 +1452,8 @@ retry:
        return res;
 }
 
-
-static int eventpollfs_delete_dentry(struct dentry *dentry)
-{
-
-       return 1;
-}
-
-
-static struct inode *ep_eventpoll_inode(void)
-{
-       int error = -ENOMEM;
-       struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
-
-       if (!inode)
-               goto eexit_1;
-
-       inode->i_fop = &eventpoll_fops;
-
-       /*
-        * Mark the inode dirty from the very beginning,
-        * that way it will never be moved to the dirty
-        * list because mark_inode_dirty() will think
-        * that it already _is_ on the dirty list.
-        */
-       inode->i_state = I_DIRTY;
-       inode->i_mode = S_IRUSR | S_IWUSR;
-       inode->i_uid = current->fsuid;
-       inode->i_gid = current->fsgid;
-       inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       return inode;
-
-eexit_1:
-       return ERR_PTR(error);
-}
-
-
-static int
-eventpollfs_get_sb(struct file_system_type *fs_type, int flags,
-                  const char *dev_name, void *data, struct vfsmount *mnt)
-{
-       return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC,
-                            mnt);
-}
-
-
 static int __init eventpoll_init(void)
 {
-       int error;
-
        mutex_init(&epmutex);
 
        /* Initialize the structure used to perform safe poll wait head wake ups */
@@ -1676,34 +1469,13 @@ static int __init eventpoll_init(void)
                        sizeof(struct eppoll_entry), 0,
                        EPI_SLAB_DEBUG|SLAB_PANIC, NULL, NULL);
 
-       /*
-        * Register the virtual file system that will be the source of inodes
-        * for the eventpoll files
-        */
-       error = register_filesystem(&eventpoll_fs_type);
-       if (error)
-               goto epanic;
-
-       /* Mount the above commented virtual file system */
-       eventpoll_mnt = kern_mount(&eventpoll_fs_type);
-       error = PTR_ERR(eventpoll_mnt);
-       if (IS_ERR(eventpoll_mnt))
-               goto epanic;
-
-       DNPRINTK(3, (KERN_INFO "[%p] eventpoll: successfully initialized.\n",
-                       current));
        return 0;
-
-epanic:
-       panic("eventpoll_init() failed\n");
 }
 
 
 static void __exit eventpoll_exit(void)
 {
        /* Undo all operations done inside eventpoll_init() */
-       unregister_filesystem(&eventpoll_fs_type);
-       mntput(eventpoll_mnt);
        kmem_cache_destroy(pwq_cache);
        kmem_cache_destroy(epi_cache);
 }