SOURCES (AC-branch): kernel24-epoll-lt.patch (NEW) - epoll for 2.4...

glen glen at pld-linux.org
Sat Apr 12 19:48:47 CEST 2008


Author: glen                         Date: Sat Apr 12 17:48:47 2008 GMT
Module: SOURCES                       Tag: AC-branch
---- Log message:
- epoll for 2.4 kernel
  raw from http://www.xmailserver.org/linux-patches/epoll-lt-2.4.32-0.23.diff

---- Files affected:
SOURCES:
   kernel24-epoll-lt.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/kernel24-epoll-lt.patch
diff -u /dev/null SOURCES/kernel24-epoll-lt.patch:1.1.2.1
--- /dev/null	Sat Apr 12 19:48:47 2008
+++ SOURCES/kernel24-epoll-lt.patch	Sat Apr 12 19:48:42 2008
@@ -0,0 +1,2624 @@
+diff -urN linux-2.4.32/arch/i386/kernel/entry.S linux-2.4.32-epoll-lt-0.23/arch/i386/kernel/entry.S
+--- linux-2.4.32/arch/i386/kernel/entry.S	Mon Apr 21 22:40:57 2003
++++ linux-2.4.32-epoll-lt-0.23/arch/i386/kernel/entry.S	Sun Jun  4 22:54:01 2006
+@@ -658,9 +658,9 @@
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_free_hugepages */
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_exit_group */
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_lookup_dcookie */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_create */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_ctl 255 */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_wait */
++	.long SYMBOL_NAME(sys_epoll_create)	/* sys_epoll_create */
++	.long SYMBOL_NAME(sys_epoll_ctl)	/* sys_epoll_ctl 255 */
++	.long SYMBOL_NAME(sys_epoll_wait)	/* sys_epoll_wait */
+  	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_remap_file_pages */
+  	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_set_tid_address */
+ 
+diff -urN linux-2.4.32/arch/ia64/ia32/ia32_entry.S linux-2.4.32-epoll-lt-0.23/arch/ia64/ia32/ia32_entry.S
+--- linux-2.4.32/arch/ia64/ia32/ia32_entry.S	Fri Feb 20 07:38:25 2004
++++ linux-2.4.32-epoll-lt-0.23/arch/ia64/ia32/ia32_entry.S	Sun Jun  4 22:54:01 2006
+@@ -421,10 +421,37 @@
+ 	data8 sys_ni_syscall		/* reserved for Security */
+ 	data8 sys_gettid
+ 	data8 sys_readahead	  /* 225 */
+-	data8 sys_ni_syscall
+-	data8 sys_ni_syscall
+-	data8 sys_ni_syscall
+-	data8 sys_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall  /* 230 */
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall  /* 235 */
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall  /* 240 */
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall  /* 245 */
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall  /* 250 */
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys32_ni_syscall
++	data8 sys_epoll_create
++	data8 sys32_epoll_ctl  /* 255 */
++	data8 sys32_epoll_wait
+ 	/*
+ 	 *  CAUTION: If any system calls are added beyond this point
+ 	 *	then the check in `arch/ia64/kernel/ivt.S' will have
+diff -urN linux-2.4.32/arch/ia64/ia32/sys_ia32.c linux-2.4.32-epoll-lt-0.23/arch/ia64/ia32/sys_ia32.c
+--- linux-2.4.32/arch/ia64/ia32/sys_ia32.c	Sun Dec  4 22:06:00 2005
++++ linux-2.4.32-epoll-lt-0.23/arch/ia64/ia32/sys_ia32.c	Sun Jun  4 22:54:01 2006
+@@ -46,6 +46,7 @@
+ #include <linux/nfsd/xdr.h>
+ #include <linux/nfsd/syscall.h>
+ #include <linux/poll.h>
++#include <linux/eventpoll.h>
+ #include <linux/personality.h>
+ #include <linux/stat.h>
+ #include <linux/ipc.h>
+@@ -4056,6 +4057,82 @@
+ 	put_unused_fd(fd);
+ 	fd = error;
+ 	goto out;
++}
++
++/* Structure for ia32 emulation on ia64 */
++struct epoll_event32 
++{
++	u32 events;
++	u64 data;
++} __attribute__((packed));
++
++asmlinkage long 
++sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 *event)
++{
++	mm_segment_t old_fs = get_fs();
++	struct epoll_event event64;
++	int error = -EFAULT;
++	u32 data_halfword;
++  
++	if ((error = verify_area(VERIFY_READ, event,
++				 sizeof(struct epoll_event32))))
++		return error;
++  
++	__get_user(event64.events, &event->events);
++	__get_user(data_halfword, (u32*)(&event->data));
++	event64.data = data_halfword;
++	__get_user(data_halfword, ((u32*)(&event->data) + 1));
++ 	event64.data |= ((u64)data_halfword) << 32; 
++
++	set_fs(KERNEL_DS);
++	error = sys_epoll_ctl(epfd, op, fd, &event64);
++	set_fs(old_fs);
++
++	return error;
++}
++
++asmlinkage long
++sys32_epoll_wait(int epfd, struct epoll_event32 *events, int maxevents,
++		 int timeout)
++{
++	struct epoll_event *events64 = NULL;
++	mm_segment_t old_fs = get_fs();
++	int i, error, nevents;
++  
++	if (maxevents <= 0)
++		return -EINVAL;
++
++	/* Verify that the area passed by the user is writeable */
++	if ((error = verify_area(VERIFY_WRITE, events,
++				 maxevents * sizeof(struct epoll_event32))))
++		return error;
++
++	/* Allocate the space needed for the intermediate copy */
++	events64 = kmalloc(maxevents * sizeof(struct epoll_event), GFP_KERNEL);
++	if (events64 == NULL)
++		return -ENOMEM;
++  
++	/* Do the system call */
++	set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
++	error = nevents = sys_epoll_wait(epfd, events64, maxevents, timeout);
++	set_fs(old_fs);
++
++	/* Don't modify userspace memory if we're returning an error */ 
++	if (!error) {
++		/* Translate the 64-bit structures back into the 32-bit 
++		   structures */
++		for (i = 0; i < nevents; i++) {
++			__put_user(events64[i].events, 
++				   &events[i].events);
++			__put_user((u32)(events64[i].data),
++				   (u32*)(&events[i].data));
++			__put_user((u32)(events64[i].data >> 32),
++				   ((u32*)(&events[i].data) + 1));
++		}
++	}
++
++	kfree(events64);
++	return error;
+ }
+ 
+ #ifdef	NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
+diff -urN linux-2.4.32/arch/ia64/kernel/entry.S linux-2.4.32-epoll-lt-0.23/arch/ia64/kernel/entry.S
+--- linux-2.4.32/arch/ia64/kernel/entry.S	Sun Apr 17 15:32:22 2005
++++ linux-2.4.32-epoll-lt-0.23/arch/ia64/kernel/entry.S	Sun Jun  4 22:54:01 2006
+@@ -1419,9 +1419,9 @@
+ 	data8 ia64_ni_syscall			// 1240
+ 	data8 ia64_ni_syscall
+ 	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall			// 1245
++	data8 sys_epoll_create
++	data8 sys_epoll_ctl
++	data8 sys_epoll_wait			// 1245
+ 	data8 ia64_ni_syscall
+ 	data8 ia64_ni_syscall
+ 	data8 ia64_ni_syscall
+diff -urN linux-2.4.32/arch/ia64/kernel/ivt.S linux-2.4.32-epoll-lt-0.23/arch/ia64/kernel/ivt.S
+--- linux-2.4.32/arch/ia64/kernel/ivt.S	Sun Apr 17 15:32:22 2005
++++ linux-2.4.32-epoll-lt-0.23/arch/ia64/kernel/ivt.S	Sun Jun  4 22:54:01 2006
+@@ -1509,7 +1509,7 @@
+ 	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
+ 	;;
+ 	ld4 r8=[r14],8		// r8 == eax (syscall number)
+-	mov r15=230		// number of entries in ia32 system call table
++	mov r15=257		// number of entries in ia32 system call table
+ 	;;
+ 	cmp.ltu.unc p6,p7=r8,r15
+ 	ld4 out1=[r14],8	// r9 == ecx
+diff -urN linux-2.4.32/arch/sparc64/solaris/timod.c linux-2.4.32-epoll-lt-0.23/arch/sparc64/solaris/timod.c
+--- linux-2.4.32/arch/sparc64/solaris/timod.c	Sun Aug  4 12:04:59 2002
++++ linux-2.4.32-epoll-lt-0.23/arch/sparc64/solaris/timod.c	Sun Jun  4 22:54:01 2006
+@@ -651,10 +651,11 @@
+ 		SOLD("LISTEN done");
+ 	}
+ 	if (!(filp->f_flags & O_NONBLOCK)) {
+-		poll_table wait_table, *wait;
++		struct poll_wqueues wait_table;
++		poll_table *wait;
+ 
+ 		poll_initwait(&wait_table);
+-		wait = &wait_table;
++		wait = &wait_table.pt;
+ 		for(;;) {
+ 			SOLD("loop");
+ 			set_current_state(TASK_INTERRUPTIBLE);
+diff -urN linux-2.4.32/fs/Makefile linux-2.4.32-epoll-lt-0.23/fs/Makefile
+--- linux-2.4.32/fs/Makefile	Fri Feb 20 07:38:31 2004
++++ linux-2.4.32-epoll-lt-0.23/fs/Makefile	Sun Jun  4 22:54:01 2006
+@@ -14,7 +14,7 @@
+ 		super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \
+ 		fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
+ 		dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \
+-		filesystems.o namespace.o seq_file.o xattr.o quota.o
++		filesystems.o namespace.o seq_file.o xattr.o quota.o eventpoll.o
+ 
+ obj-$(CONFIG_QUOTA)		+= dquot.o quota_v1.o
+ obj-$(CONFIG_QFMT_V2)		+= quota_v2.o
+diff -urN linux-2.4.32/fs/eventpoll.c linux-2.4.32-epoll-lt-0.23/fs/eventpoll.c
+--- linux-2.4.32/fs/eventpoll.c	Thu Jan  1 01:00:00 1970
++++ linux-2.4.32-epoll-lt-0.23/fs/eventpoll.c	Sun Jun  4 22:54:52 2006
+@@ -0,0 +1,1776 @@
++/*
++ *  fs/eventpoll.c ( Efficent event polling implementation )
++ *  Copyright (C) 2001,...,2006	 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
++ *  the Free Software Foundation; either version 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  Davide Libenzi <davidel at xmailserver.org>
++ *  
++ *  11 December 2002	
++ *	Ported from 2.5.51 - janetinc at us.ibm.com
++ *		
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/signal.h>
++#include <linux/errno.h>
++#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>
++#include <linux/spinlock.h>
++#include <linux/rwsem.h>
++#include <linux/wait.h>
++#include <linux/eventpoll.h>
++#include <linux/mount.h>
++#include <asm/bitops.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/mman.h>
++#include <asm/atomic.h>
++#include <asm/semaphore.h>
++
++
++/*
++ * LOCKING:
++ * There are three level of locking required by epoll :
++ *
++ * 1) epsem (semaphore)
++ * 2) ep->sem (rw_semaphore)
++ * 3) ep->lock (rw_lock)
++ *
++ * The acquire order is the one listed above, from 1 to 3.
++ * We need a spinlock (ep->lock) because we manipulate objects
++ * from inside the poll callback, that might be triggered from
++ * a wake_up() that in turn might be called from IRQ context.
++ * So we can't sleep inside the poll callback and hence we need
++ * a spinlock. During the event transfer loop (from kernel to
++ * user space) we could end up sleeping due a copy_to_user(), so
++ * we need a lock that will allow us to sleep. This lock is a
++ * read-write semaphore (ep->sem). It is acquired on read during
++ * the event transfer loop and in write during epoll_ctl(EPOLL_CTL_DEL)
++ * and during eventpoll_release(). Then we also need a global
++ * semaphore to serialize eventpoll_release() and ep_free().
++ * This semaphore is acquired by ep_free() during the epoll file
++ * cleanup path and it is also acquired by eventpoll_release()
++ * 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 "epsem" (together with "ep->lock") to have it working,
++ * but having "ep->sem" will make the interface more scalable.
++ * Events that require holding "epsem" are very rare, while for
++ * normal operations the epoll private "ep->sem" will guarantee
++ * a greater scalability.
++ */
++
++
++#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
++
++#define DEBUG_EPOLL 0
++
++#if DEBUG_EPOLL > 0
++#define DPRINTK(x) printk x
++#define DNPRINTK(n, x) do { if ((n) <= DEBUG_EPOLL) printk x; } while (0)
++#else /* #if DEBUG_EPOLL > 0 */
++#define DPRINTK(x) (void) 0
++#define DNPRINTK(n, x) (void) 0
++#endif /* #if DEBUG_EPOLL > 0 */
++
++#define DEBUG_EPI 0
++
++#if DEBUG_EPI != 0
++#define EPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
++#else /* #if DEBUG_EPI != 0 */
++#define EPI_SLAB_DEBUG 0
++#endif /* #if DEBUG_EPI != 0 */
++
++/* Epoll private bits inside the event mask */
++#define EP_PRIVATE_BITS (EPOLLONESHOT | EPOLLET)
++
++/* Maximum number of poll wake up nests we are allowing */
++#define EP_MAX_POLLWAKE_NESTS 4
++
++/* Maximum size of the hash in bits ( 2^N ) */
++#define EP_MAX_HASH_BITS 17
++
++/* Minimum size of the hash in bits ( 2^N ) */
++#define EP_MIN_HASH_BITS 9
++
++/* Number of hash entries ( "struct list_head" ) inside a page */
++#define EP_HENTRY_X_PAGE (PAGE_SIZE / sizeof(struct list_head))
++
++/* Maximum size of the hash in pages */
++#define EP_MAX_HPAGES ((1 << EP_MAX_HASH_BITS) / EP_HENTRY_X_PAGE + 1)
++
++/* Number of pages allocated for an "hbits" sized hash table */
++#define EP_HASH_PAGES(hbits) ((int) ((1 << (hbits)) / EP_HENTRY_X_PAGE + \
++				     ((1 << (hbits)) % EP_HENTRY_X_PAGE ? 1: 0)))
++
++/* Macro to allocate a "struct epitem" from the slab cache */
++#define EPI_MEM_ALLOC()	(struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
++
++/* Macro to free a "struct epitem" to the slab cache */
++#define EPI_MEM_FREE(p) kmem_cache_free(epi_cache, p)
++
++/* Macro to allocate a "struct eppoll_entry" from the slab cache */
++#define PWQ_MEM_ALLOC()	(struct eppoll_entry *) kmem_cache_alloc(pwq_cache, SLAB_KERNEL)
++
++/* Macro to free a "struct eppoll_entry" to the slab cache */
++#define PWQ_MEM_FREE(p) kmem_cache_free(pwq_cache, p)
++
++/* Fast test to see if the file is an evenpoll file */
++#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
++
++/*
++ * Remove the item from the list and perform its initialization.
++ * This is usefull for us because we can test if the item is linked
++ * using "EP_IS_LINKED(p)".
++ */
++#define EP_LIST_DEL(p) do { list_del(p); INIT_LIST_HEAD(p); } while (0)
++
++/* Tells us if the item is currently linked */
++#define EP_IS_LINKED(p) (!list_empty(p))
++
++/* Get the "struct epitem" from a wait queue pointer */
++#define EP_ITEM_FROM_WAIT(p) ((struct epitem *) container_of(p, struct eppoll_entry, wait)->base)
++
++/* Get the "struct epitem" from an epoll queue wrapper */
++#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
++
++/*
++ * This is used to optimize the event transfer to userspace. Since this
++ * is kept on stack, it should be pretty small.
++ */
++#define EP_MAX_BUF_EVENTS 32
++
++
++
++/*
++ * Node that is linked into the "wake_task_list" member of the "struct poll_safewake".
++ * It is used to keep track on all tasks that are currently inside the wake_up() code
++ * to 1) short-circuit the one coming from the same task and same wait queue head
++ * ( loop ) 2) allow a maximum number of epoll descriptors inclusion nesting
++ * 3) let go the ones coming from other tasks.
++ */
++struct wake_task_node {
++	struct list_head llink;
++	task_t *task;
++	wait_queue_head_t *wq;
++};
++
++/*
++ * This is used to implement the safe poll wake up avoiding to reenter
++ * the poll callback from inside wake_up().
++ */
++struct poll_safewake {
++	struct list_head wake_task_list;
++	spinlock_t lock;
++};
++
++/*
++ * This structure is stored inside the "private_data" member of the file
++ * structure and represent the main data sructure for the eventpoll
++ * interface.
++ */
++struct eventpoll {
++	/* Protect the this structure access */
++	rwlock_t lock;
++
++	/*
++	 * This semaphore is used to ensure that files are not removed
++	 * while epoll is using them. This is read-held during the event
++	 * collection loop and it is write-held during the file cleanup
++	 * path, the epoll file exit code and the ctl operations.
++	 */
++	struct rw_semaphore sem;
++
++	/* Wait queue used by sys_epoll_wait() */
++	wait_queue_head_t wq;
++
++	/* Wait queue used by file->poll() */
++	wait_queue_head_t poll_wait;
++
++	/* List of ready file descriptors */
++	struct list_head rdllist;
++
++	/* Size of the hash */
++	unsigned int hashbits;
++
++	/* Pages for the "struct epitem" hash */
++	char *hpages[EP_MAX_HPAGES];
++};
++
++/* Wait structure used by the poll hooks */
++struct eppoll_entry {
++	/* List header used to link this structure to the "struct epitem" */
++	struct list_head llink;
++
++	/* The "base" pointer is set to the container "struct epitem" */
++	void *base;
++
++	/*
++	 * Wait queue item that will be linked to the target file wait
++	 * queue head.
++	 */
++	wait_queue_t wait;
++
++	/* The wait queue head that linked the "wait" wait queue item */
++	wait_queue_head_t *whead;
++};
++
++/*
++ * Each file descriptor added to the eventpoll interface will
++ * have an entry of this type linked to the hash.
++ */
++struct epitem {
++	/* List header used to link this structure to the eventpoll hash */
++	struct list_head llink;
++
++	/* List header used to link this structure to the eventpoll ready list */
++	struct list_head rdllink;
++
++	/* Number of active wait queue attached to poll operations */
++	int nwait;
++
++	/* List containing poll wait queues */
++	struct list_head pwqlist;
++
++	/* The "container" of this item */
++	struct eventpoll *ep;
++
++	/* The file descriptor this item refers to */
++	int fd;
++
++	/* The file this item refers to */
++	struct file *file;
++
++	/* The structure that describe the interested events and the source fd */
++	struct epoll_event event;
++
++	/*
++	 * Used to keep track of the usage count of the structure. This avoids
++	 * that the structure will desappear from underneath our processing.
++	 */
++	atomic_t usecnt;
++
++	/* 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 */
++struct ep_pqueue {
++	poll_table pt;
++	struct epitem *epi;
++};
++
++
++
++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 unsigned int ep_get_hash_bits(unsigned int hintsize);
++static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
++static int ep_alloc_pages(char **pages, int numpages);
++static int ep_free_pages(char **pages, int numpages);
++static int ep_file_init(struct file *file, unsigned int hashbits);
++static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file, int fd);
++static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index);
++static int ep_init(struct eventpoll *ep, unsigned int hashbits);
++static void ep_free(struct eventpoll *ep);
++static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
++static void ep_use_epitem(struct epitem *epi);
++static void ep_release_epitem(struct epitem *epi);
++static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
++				 poll_table *pt);
++static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
++		     struct file *tfile, int fd);
++static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event);
++static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
++static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
++static int ep_remove(struct eventpoll *ep, struct epitem *epi);
++static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync);
++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 *events);
++static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist);
++static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents);
++static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
++		   long timeout);
++static int eventpollfs_statfs(struct super_block *sb, struct statfs *buf);
++static struct super_block *eventpollfs_read_super(struct super_block *sb, void *data, int silent);
++static int eventpollfs_delete_dentry(struct dentry *dentry);
++static struct inode *ep_eventpoll_inode(void);
++
++/*
++ * This semaphore is used to serialize ep_free() and eventpoll_release().
++ */
++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;
++
++/* Slab cache used to allocate "struct eppoll_entry" */
++static kmem_cache_t *pwq_cache;
++
++/* Virtual fs used to allocate inodes for eventpoll files */
++static struct vfsmount *eventpoll_mnt;
++
++/* File callbacks that implement the eventpoll file behaviour */
++static struct file_operations eventpoll_fops = {
++	.release	= ep_eventpoll_close,
++	.poll		= ep_eventpoll_poll
++};
++
++/* Virtual fs operations */
++static struct super_operations eventpollfs_ops = {
++	.statfs		= eventpollfs_statfs,
++};
++
++/* Virtual fs structure declaration */
++static DECLARE_FSTYPE(eventpoll_fs_type, "eventpollfs", eventpollfs_read_super, FS_NOMOUNT);
++
++/* Very basic directory entry operations for the eventpoll virtual file system */
++static struct dentry_operations eventpollfs_dentry_operations = {
++	.d_delete	= eventpollfs_delete_dentry,
++};
++
++
++
++
++/* Initialize the poll safe wake up structure */
++static void ep_poll_safewake_init(struct poll_safewake *psw)
++{
++
++	INIT_LIST_HEAD(&psw->wake_task_list);
++	spin_lock_init(&psw->lock);
++}
++
++
++/*
++ * Perform a safe wake up of the poll wait list. The problem is that
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list