diff -ur linux/fs/select.c linux-poll/fs/select.c
--- linux/fs/select.c	Sat Dec 12 18:39:02 1998
+++ linux-poll/fs/select.c	Sat Dec 12 14:29:41 1998
@@ -41,28 +41,35 @@
 
 static void free_wait(poll_table * p)
 {
-	struct poll_table_entry * entry = p->entry + p->nr;
+	struct poll_table_entry * entry;
+	poll_table *old;
 
-	while (p->nr > 0) {
-		p->nr--;
-		entry--;
-		remove_wait_queue(entry->wait_address,&entry->wait);
-		fput(entry->filp);
+	while (p) {
+		entry = p->entry + p->nr;
+		while (p->nr > 0) {
+			p->nr--;
+			entry--;
+			remove_wait_queue(entry->wait_address,&entry->wait);
+			fput(entry->filp);
+		}
+		old = p;
+		p = p->next;
+		free_page((unsigned long) old);
 	}
 }
 
-#define __IN(in)	(in)
-#define __OUT(in)	(in + sizeof(kernel_fd_set)/sizeof(unsigned long))
-#define __EX(in)	(in + 2*sizeof(kernel_fd_set)/sizeof(unsigned long))
-#define __RES_IN(in)	(in + 3*sizeof(kernel_fd_set)/sizeof(unsigned long))
-#define __RES_OUT(in)	(in + 4*sizeof(kernel_fd_set)/sizeof(unsigned long))
-#define __RES_EX(in)	(in + 5*sizeof(kernel_fd_set)/sizeof(unsigned long))
+#define __IN(fds, n)		(fds->in + n)
+#define __OUT(fds, n)		(fds->out + n)
+#define __EX(fds, n)		(fds->ex + n)
+#define __RES_IN(fds, n)	(fds->res_in + n)
+#define __RES_OUT(fds, n)	(fds->res_out + n)
+#define __RES_EX(fds, n)	(fds->res_ex + n)
 
-#define BITS(in)	(*__IN(in)|*__OUT(in)|*__EX(in))
+#define BITS(fds, n)		(*__IN(fds, n)|*__OUT(fds, n)|*__EX(fds, n))
 
-static int max_select_fd(unsigned long n, fd_set_buffer *fds)
+static int max_select_fd(unsigned long n, fd_set_bits *fds)
 {
-	unsigned long *open_fds, *in;
+	unsigned long *open_fds;
 	unsigned long set;
 	int max;
 
@@ -70,10 +77,9 @@
 	set = ~(~0UL << (n & (__NFDBITS-1)));
 	n /= __NFDBITS;
 	open_fds = current->files->open_fds->fds_bits+n;
-	in = fds->in+n;
 	max = 0;
 	if (set) {
-		set &= BITS(in);
+		set &= BITS(fds, n);
 		if (set) {
 			if (!(set & ~*open_fds))
 				goto get_max;
@@ -81,10 +87,9 @@
 		}
 	}
 	while (n) {
-		in--;
 		open_fds--;
 		n--;
-		set = BITS(in);
+		set = BITS(fds, n);
 		if (!set)
 			continue;
 		if (set & ~*open_fds)
@@ -111,21 +116,22 @@
 #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
 #define POLLEX_SET (POLLPRI)
 
-int do_select(int n, fd_set_buffer *fds, long *timeout)
+int do_select(int n, fd_set_bits *fds, long *timeout)
 {
-	poll_table wait_table, *wait;
-	int retval, i;
+	poll_table *wait_table, *wait;
+	int retval, i, off;
 	long __timeout = *timeout;
 
-	wait = NULL;
+	wait = wait_table = NULL;
 	if (__timeout) {
-		struct poll_table_entry *entry = (struct poll_table_entry *) __get_free_page(GFP_KERNEL);
-		if (!entry)
+		wait_table = (poll_table *) __get_free_page(GFP_KERNEL);
+		if (!wait_table)
 			return -ENOMEM;
 
-		wait_table.nr = 0;
-		wait_table.entry = entry;
-		wait = &wait_table;
+		wait_table->nr = 0;
+		wait_table->entry = (struct poll_table_entry *)(wait_table + 1);
+		wait_table->next = NULL;
+		wait = wait_table;
 	}
 
 	lock_kernel();
@@ -139,11 +145,11 @@
 		current->state = TASK_INTERRUPTIBLE;
 		for (i = 0 ; i < n; i++) {
 			unsigned long bit = BIT(i);
-			unsigned long *in = MEM(i,fds->in);
 			unsigned long mask;
 			struct file *file;
 
-			if (!(bit & BITS(in)))
+			off = i / __NFDBITS;
+			if (!(bit & BITS(fds, off)))
 				continue;
 			/*
 			 * The poll_wait routine will increment f_count if
@@ -157,18 +163,18 @@
 				if (file->f_op && file->f_op->poll)
 					mask = file->f_op->poll(file, wait);
 			}
-			if ((mask & POLLIN_SET) && ISSET(bit, __IN(in))) {
-				SET(bit, __RES_IN(in));
+			if ((mask & POLLIN_SET) && ISSET(bit, __IN(fds,off))) {
+				SET(bit, __RES_IN(fds,off));
 				retval++;
 				wait = NULL;
 			}
-			if ((mask & POLLOUT_SET) && ISSET(bit, __OUT(in))) {
-				SET(bit, __RES_OUT(in));
+			if ((mask & POLLOUT_SET) && ISSET(bit, __OUT(fds,off))) {
+				SET(bit, __RES_OUT(fds,off));
 				retval++;
 				wait = NULL;
 			}
-			if ((mask & POLLEX_SET) && ISSET(bit, __EX(in))) {
-				SET(bit, __RES_EX(in));
+			if ((mask & POLLEX_SET) && ISSET(bit, __EX(fds,off))) {
+				SET(bit, __RES_EX(fds,off));
 				retval++;
 				wait = NULL;
 			}
@@ -181,10 +187,8 @@
 	current->state = TASK_RUNNING;
 
 out:
-	if (*timeout) {
-		free_wait(&wait_table);
-		free_page((unsigned long) wait_table.entry);
-	}
+	if (*timeout)
+		free_wait(wait_table);
 
 	/*
 	 * Up-to-date the caller timeout.
@@ -208,9 +212,10 @@
 asmlinkage int
 sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
 {
-	fd_set_buffer *fds;
+	fd_set_bits fds;
+	char *bits;
 	long timeout;
-	int ret;
+	int ret, size;
 
 	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (tvp) {
@@ -227,24 +232,36 @@
 		}
 	}
 
+	ret = -EINVAL;
+	if (n <= 0 || n > current->files->max_fdset + 1)
+		goto out_nofds;
+	/*
+	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
+	 * since we used fdset we need to allocate memory in units of
+	 * long-words.
+	 */
+
 	ret = -ENOMEM;
-	fds = (fd_set_buffer *) __get_free_page(GFP_KERNEL);
-	if (!fds)
+	size = (n + 8 * sizeof(long) - 1) / (8 * sizeof(long)) * sizeof(long);
+	bits = kmalloc(6 * size, GFP_KERNEL);
+	if (!bits)
 		goto out_nofds;
-	ret = -EINVAL;
-	if (n < 0)
+	fds.in      = (unsigned long *)  bits;
+	fds.out     = (unsigned long *) (bits +   size);
+	fds.ex      = (unsigned long *) (bits + 2*size);
+	fds.res_in  = (unsigned long *) (bits + 3*size);
+	fds.res_out = (unsigned long *) (bits + 4*size);
+	fds.res_ex  = (unsigned long *) (bits + 5*size);
+
+	if ((ret = get_fd_set(n, inp, fds.in)) ||
+	    (ret = get_fd_set(n, outp, fds.out)) ||
+	    (ret = get_fd_set(n, exp, fds.ex)))
 		goto out;
-	if (n > KFDS_NR)
-		n = KFDS_NR;
-	if ((ret = get_fd_set(n, inp, fds->in)) ||
-	    (ret = get_fd_set(n, outp, fds->out)) ||
-	    (ret = get_fd_set(n, exp, fds->ex)))
-		goto out;
-	zero_fd_set(n, fds->res_in);
-	zero_fd_set(n, fds->res_out);
-	zero_fd_set(n, fds->res_ex);
+	zero_fd_set(n, fds.res_in);
+	zero_fd_set(n, fds.res_out);
+	zero_fd_set(n, fds.res_ex);
 
-	ret = do_select(n, fds, &timeout);
+	ret = do_select(n, &fds, &timeout);
 
 	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
 		time_t sec = 0, usec = 0;
@@ -266,12 +283,12 @@
 		ret = 0;
 	}
 
-	set_fd_set(n, inp, fds->res_in);
-	set_fd_set(n, outp, fds->res_out);
-	set_fd_set(n, exp, fds->res_ex);
+	set_fd_set(n, inp, fds.res_in);
+	set_fd_set(n, outp, fds.res_out);
+	set_fd_set(n, exp, fds.res_ex);
 
 out:
-	free_page((unsigned long) fds);
+	kfree(bits);
 out_nofds:
 	return ret;
 }
@@ -323,7 +340,7 @@
 {
 	int i, fdcount, err, size;
 	struct pollfd * fds, *fds1;
-	poll_table wait_table, *wait = NULL;
+	poll_table *wait_table = NULL, *wait = NULL;
 
 	lock_kernel();
 	/* Do a sanity check on nfds ... */
@@ -338,13 +355,13 @@
 
 	err = -ENOMEM;
 	if (timeout) {
-		struct poll_table_entry *entry;
-		entry = (struct poll_table_entry *) __get_free_page(GFP_KERNEL);
-		if (!entry)
+		wait_table = (poll_table *) __get_free_page(GFP_KERNEL);
+		if (!wait_table)
 			goto out;
-		wait_table.nr = 0;
-		wait_table.entry = entry;
-		wait = &wait_table;
+		wait_table->nr = 0;
+		wait_table->entry = (struct poll_table_entry *)(wait_table + 1);
+		wait_table->next = NULL;
+		wait = wait_table;
 	}
 
 	size = nfds * sizeof(struct pollfd);
@@ -371,10 +388,8 @@
 out_fds:
 	kfree(fds);
 out:
-	if (wait) {
-		free_wait(&wait_table);
-		free_page((unsigned long) wait->entry);
-	}
+	if (wait)
+		free_wait(wait_table);
 	unlock_kernel();
 	return err;
 }
diff -ur linux/include/linux/poll.h linux-poll/include/linux/poll.h
--- linux/include/linux/poll.h	Tue Nov 24 15:56:25 1998
+++ linux-poll/include/linux/poll.h	Sat Dec 12 14:31:36 1998
@@ -7,6 +7,7 @@
 
 #include <linux/wait.h>
 #include <linux/string.h>
+#include <linux/mm.h>
 #include <asm/uaccess.h>
 
 
@@ -17,11 +18,12 @@
 };
 
 typedef struct poll_table_struct {
+	struct poll_table_struct * next;
 	unsigned int nr;
 	struct poll_table_entry * entry;
 } poll_table;
 
-#define __MAX_POLL_TABLE_ENTRIES (PAGE_SIZE / sizeof (struct poll_table_entry))
+#define __MAX_POLL_TABLE_ENTRIES ((PAGE_SIZE - sizeof (poll_table)) / sizeof (struct poll_table_entry))
 
 extern inline void poll_wait(struct file * filp, struct wait_queue ** wait_address, poll_table *p)
 {
@@ -29,8 +31,18 @@
 
 	if (!p || !wait_address)
 		return;
-	if (p->nr >= __MAX_POLL_TABLE_ENTRIES)
-		return;
+	while (p->nr >= __MAX_POLL_TABLE_ENTRIES && p->next != NULL)
+		p = p->next;
+	if (p->nr >= __MAX_POLL_TABLE_ENTRIES) {
+		poll_table *tmp = (poll_table *) __get_free_page(GFP_KERNEL);
+		if (!tmp)
+			return;
+		tmp->nr = 0;
+		tmp->entry = (struct poll_table_entry *)(tmp + 1);
+		tmp->next = NULL;
+		p->next = tmp;
+		p = tmp;
+	}
  	entry = p->entry + p->nr;
  	entry->filp = filp;
  	filp->f_count++;
@@ -59,11 +71,23 @@
 #define KFDS_NR (KFDS_64BLOCK*8 > NR_OPEN ? NR_OPEN : KFDS_64BLOCK*8)
 typedef unsigned long kernel_fd_set[KFDS_NR/__NFDBITS];
 
+/*
+ * XXX - still used by alpha osf and sparc32 compatiblity.
+ */
+
 typedef struct {
 	kernel_fd_set in, out, ex;
 	kernel_fd_set res_in, res_out, res_ex;
 } fd_set_buffer;
 
+/*
+ * Scaleable version of the fd_set.
+ */
+
+typedef struct {
+	unsigned long *in, *out, *ex;
+	unsigned long *res_in, *res_out, *res_ex;
+} fd_set_bits;
 
 /*
  * We do a VERIFY_WRITE here even though we are only reading this time:
@@ -103,7 +127,7 @@
 	memset(fdset, 0, nr);
 }
 
-extern int do_select(int n, fd_set_buffer *fds, long *timeout);
+extern int do_select(int n, fd_set_bits *fds, long *timeout);
 
 #endif /* KERNEL */
 
diff -ur linux/kernel/fork.c linux-poll/kernel/fork.c
--- linux/kernel/fork.c	Sat Dec 12 18:39:11 1998
+++ linux-poll/kernel/fork.c	Thu Dec 10 18:42:16 1998
@@ -1,4 +1,4 @@
-#define FDSET_DEBUG
+#undef FDSET_DEBUG
 
 /*
  *  linux/kernel/fork.c
