aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavide Libenzi <davidel@xmailserver.org>2007-05-11 01:23:21 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 11:29:37 -0400
commitda66f7cb0f69ab27dbf5b9d0b85c4b97716c44d1 (patch)
tree3d2dc033eb92d18f8b2debe2fd472d6f3a7b6b9f /fs
parent9c3060bedd84144653a2ad7bea32389f65598d40 (diff)
epoll: use anonymous inodes
Cut out lots of code from epoll, by reusing the anonymous inode source patch (fs/anon_inodes.c). Signed-off-by: Davide Libenzi <davidel@xmailserver.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/eventpoll.c172
1 files changed, 3 insertions, 169 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index b5c7ca584939..2831c8f9f3e3 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -34,6 +34,7 @@
34#include <linux/mount.h> 34#include <linux/mount.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/anon_inodes.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
38#include <asm/system.h> 39#include <asm/system.h>
39#include <asm/io.h> 40#include <asm/io.h>
@@ -75,8 +76,6 @@
75 */ 76 */
76 77
77 78
78#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
79
80#define DEBUG_EPOLL 0 79#define DEBUG_EPOLL 0
81 80
82#if DEBUG_EPOLL > 0 81#if DEBUG_EPOLL > 0
@@ -228,8 +227,6 @@ struct ep_pqueue {
228 227
229static void ep_poll_safewake_init(struct poll_safewake *psw); 228static void ep_poll_safewake_init(struct poll_safewake *psw);
230static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq); 229static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
231static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
232 struct eventpoll *ep);
233static int ep_alloc(struct eventpoll **pep); 230static int ep_alloc(struct eventpoll **pep);
234static void ep_free(struct eventpoll *ep); 231static void ep_free(struct eventpoll *ep);
235static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd); 232static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
@@ -255,11 +252,6 @@ static int ep_events_transfer(struct eventpoll *ep,
255 int maxevents); 252 int maxevents);
256static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, 253static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
257 int maxevents, long timeout); 254 int maxevents, long timeout);
258static int eventpollfs_delete_dentry(struct dentry *dentry);
259static struct inode *ep_eventpoll_inode(void);
260static int eventpollfs_get_sb(struct file_system_type *fs_type,
261 int flags, const char *dev_name,
262 void *data, struct vfsmount *mnt);
263 255
264/* 256/*
265 * This semaphore is used to serialize ep_free() and eventpoll_release_file(). 257 * This semaphore is used to serialize ep_free() and eventpoll_release_file().
@@ -275,30 +267,12 @@ static struct kmem_cache *epi_cache __read_mostly;
275/* Slab cache used to allocate "struct eppoll_entry" */ 267/* Slab cache used to allocate "struct eppoll_entry" */
276static struct kmem_cache *pwq_cache __read_mostly; 268static struct kmem_cache *pwq_cache __read_mostly;
277 269
278/* Virtual fs used to allocate inodes for eventpoll files */
279static struct vfsmount *eventpoll_mnt __read_mostly;
280
281/* File callbacks that implement the eventpoll file behaviour */ 270/* File callbacks that implement the eventpoll file behaviour */
282static const struct file_operations eventpoll_fops = { 271static const struct file_operations eventpoll_fops = {
283 .release = ep_eventpoll_close, 272 .release = ep_eventpoll_close,
284 .poll = ep_eventpoll_poll 273 .poll = ep_eventpoll_poll
285}; 274};
286 275
287/*
288 * This is used to register the virtual file system from where
289 * eventpoll inodes are allocated.
290 */
291static struct file_system_type eventpoll_fs_type = {
292 .name = "eventpollfs",
293 .get_sb = eventpollfs_get_sb,
294 .kill_sb = kill_anon_super,
295};
296
297/* Very basic directory entry operations for the eventpoll virtual file system */
298static struct dentry_operations eventpollfs_dentry_operations = {
299 .d_delete = eventpollfs_delete_dentry,
300};
301
302 276
303 277
304/* Fast test to see if the file is an evenpoll file */ 278/* Fast test to see if the file is an evenpoll file */
@@ -495,7 +469,8 @@ asmlinkage long sys_epoll_create(int size)
495 * Creates all the items needed to setup an eventpoll file. That is, 469 * Creates all the items needed to setup an eventpoll file. That is,
496 * a file structure, and inode and a free file descriptor. 470 * a file structure, and inode and a free file descriptor.
497 */ 471 */
498 error = ep_getfd(&fd, &inode, &file, ep); 472 error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]",
473 &eventpoll_fops, ep);
499 if (error) 474 if (error)
500 goto eexit_2; 475 goto eexit_2;
501 476
@@ -725,82 +700,6 @@ asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
725#endif /* #ifdef TIF_RESTORE_SIGMASK */ 700#endif /* #ifdef TIF_RESTORE_SIGMASK */
726 701
727 702
728/*
729 * Creates the file descriptor to be used by the epoll interface.
730 */
731static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
732 struct eventpoll *ep)
733{
734 struct qstr this;
735 char name[32];
736 struct dentry *dentry;
737 struct inode *inode;
738 struct file *file;
739 int error, fd;
740
741 /* Get an ready to use file */
742 error = -ENFILE;
743 file = get_empty_filp();
744 if (!file)
745 goto eexit_1;
746
747 /* Allocates an inode from the eventpoll file system */
748 inode = ep_eventpoll_inode();
749 if (IS_ERR(inode)) {
750 error = PTR_ERR(inode);
751 goto eexit_2;
752 }
753
754 /* Allocates a free descriptor to plug the file onto */
755 error = get_unused_fd();
756 if (error < 0)
757 goto eexit_3;
758 fd = error;
759
760 /*
761 * Link the inode to a directory entry by creating a unique name
762 * using the inode number.
763 */
764 error = -ENOMEM;
765 sprintf(name, "[%lu]", inode->i_ino);
766 this.name = name;
767 this.len = strlen(name);
768 this.hash = inode->i_ino;
769 dentry = d_alloc(eventpoll_mnt->mnt_sb->s_root, &this);
770 if (!dentry)
771 goto eexit_4;
772 dentry->d_op = &eventpollfs_dentry_operations;
773 d_add(dentry, inode);
774 file->f_path.mnt = mntget(eventpoll_mnt);
775 file->f_path.dentry = dentry;
776 file->f_mapping = inode->i_mapping;
777
778 file->f_pos = 0;
779 file->f_flags = O_RDONLY;
780 file->f_op = &eventpoll_fops;
781 file->f_mode = FMODE_READ;
782 file->f_version = 0;
783 file->private_data = ep;
784
785 /* Install the new setup file into the allocated fd. */
786 fd_install(fd, file);
787
788 *efd = fd;
789 *einode = inode;
790 *efile = file;
791 return 0;
792
793eexit_4:
794 put_unused_fd(fd);
795eexit_3:
796 iput(inode);
797eexit_2:
798 put_filp(file);
799eexit_1:
800 return error;
801}
802
803
804static int ep_alloc(struct eventpoll **pep) 703static int ep_alloc(struct eventpoll **pep)
805{ 704{
806 struct eventpoll *ep = kzalloc(sizeof(*ep), GFP_KERNEL); 705 struct eventpoll *ep = kzalloc(sizeof(*ep), GFP_KERNEL);
@@ -1553,52 +1452,8 @@ retry:
1553 return res; 1452 return res;
1554} 1453}
1555 1454
1556static int eventpollfs_delete_dentry(struct dentry *dentry)
1557{
1558
1559 return 1;
1560}
1561
1562static struct inode *ep_eventpoll_inode(void)
1563{
1564 int error = -ENOMEM;
1565 struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
1566
1567 if (!inode)
1568 goto eexit_1;
1569
1570 inode->i_fop = &eventpoll_fops;
1571
1572 /*
1573 * Mark the inode dirty from the very beginning,
1574 * that way it will never be moved to the dirty
1575 * list because mark_inode_dirty() will think
1576 * that it already _is_ on the dirty list.
1577 */
1578 inode->i_state = I_DIRTY;
1579 inode->i_mode = S_IRUSR | S_IWUSR;
1580 inode->i_uid = current->fsuid;
1581 inode->i_gid = current->fsgid;
1582 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
1583 return inode;
1584
1585eexit_1:
1586 return ERR_PTR(error);
1587}
1588
1589static int
1590eventpollfs_get_sb(struct file_system_type *fs_type, int flags,
1591 const char *dev_name, void *data, struct vfsmount *mnt)
1592{
1593 return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC,
1594 mnt);
1595}
1596
1597
1598static int __init eventpoll_init(void) 1455static int __init eventpoll_init(void)
1599{ 1456{
1600 int error;
1601
1602 mutex_init(&epmutex); 1457 mutex_init(&epmutex);
1603 1458
1604 /* Initialize the structure used to perform safe poll wait head wake ups */ 1459 /* Initialize the structure used to perform safe poll wait head wake ups */
@@ -1614,34 +1469,13 @@ static int __init eventpoll_init(void)
1614 sizeof(struct eppoll_entry), 0, 1469 sizeof(struct eppoll_entry), 0,
1615 EPI_SLAB_DEBUG|SLAB_PANIC, NULL, NULL); 1470 EPI_SLAB_DEBUG|SLAB_PANIC, NULL, NULL);
1616 1471
1617 /*
1618 * Register the virtual file system that will be the source of inodes
1619 * for the eventpoll files
1620 */
1621 error = register_filesystem(&eventpoll_fs_type);
1622 if (error)
1623 goto epanic;
1624
1625 /* Mount the above commented virtual file system */
1626 eventpoll_mnt = kern_mount(&eventpoll_fs_type);
1627 error = PTR_ERR(eventpoll_mnt);
1628 if (IS_ERR(eventpoll_mnt))
1629 goto epanic;
1630
1631 DNPRINTK(3, (KERN_INFO "[%p] eventpoll: successfully initialized.\n",
1632 current));
1633 return 0; 1472 return 0;
1634
1635epanic:
1636 panic("eventpoll_init() failed\n");
1637} 1473}
1638 1474
1639 1475
1640static void __exit eventpoll_exit(void) 1476static void __exit eventpoll_exit(void)
1641{ 1477{
1642 /* Undo all operations done inside eventpoll_init() */ 1478 /* Undo all operations done inside eventpoll_init() */
1643 unregister_filesystem(&eventpoll_fs_type);
1644 mntput(eventpoll_mnt);
1645 kmem_cache_destroy(pwq_cache); 1479 kmem_cache_destroy(pwq_cache);
1646 kmem_cache_destroy(epi_cache); 1480 kmem_cache_destroy(epi_cache);
1647} 1481}