sysfs: Make poll behaviour consistent
[pandora-kernel.git] / fs / file.c
index cea7cbe..b3c6b82 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -125,7 +125,8 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
                kmem_cache_free(files_cachep, fdt->free_files);
                return;
        }
-       if (fdt->max_fdset <= __FD_SETSIZE && fdt->max_fds <= NR_OPEN_DEFAULT) {
+       if (fdt->max_fdset <= EMBEDDED_FD_SET_SIZE &&
+               fdt->max_fds <= NR_OPEN_DEFAULT) {
                /*
                 * The fdtable was embedded
                 */
@@ -155,8 +156,9 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
 
 void free_fdtable(struct fdtable *fdt)
 {
-       if (fdt->free_files || fdt->max_fdset > __FD_SETSIZE ||
-                                       fdt->max_fds > NR_OPEN_DEFAULT)
+       if (fdt->free_files ||
+               fdt->max_fdset > EMBEDDED_FD_SET_SIZE ||
+               fdt->max_fds > NR_OPEN_DEFAULT)
                call_rcu(&fdt->rcu, free_fdtable_rcu);
 }
 
@@ -199,7 +201,6 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *fdt)
                       (nfdt->max_fds - fdt->max_fds) *
                                        sizeof(struct file *));
        }
-       nfdt->next_fd = fdt->next_fd;
 }
 
 /*
@@ -220,11 +221,9 @@ fd_set * alloc_fdset(int num)
 
 void free_fdset(fd_set *array, int num)
 {
-       int size = num / 8;
-
-       if (num <= __FD_SETSIZE) /* Don't free an embedded fdset */
+       if (num <= EMBEDDED_FD_SET_SIZE) /* Don't free an embedded fdset */
                return;
-       else if (size <= PAGE_SIZE)
+       else if (num <= 8 * PAGE_SIZE)
                kfree(array);
        else
                vfree(array);
@@ -237,22 +236,13 @@ static struct fdtable *alloc_fdtable(int nr)
        fd_set *new_openset = NULL, *new_execset = NULL;
        struct file **new_fds;
 
-       fdt = kmalloc(sizeof(*fdt), GFP_KERNEL);
+       fdt = kzalloc(sizeof(*fdt), GFP_KERNEL);
        if (!fdt)
                goto out;
-       memset(fdt, 0, sizeof(*fdt));
 
-       nfds = __FD_SETSIZE;
-       /* Expand to the max in easy steps */
-       do {
-               if (nfds < (PAGE_SIZE * 8))
-                       nfds = PAGE_SIZE * 8;
-               else {
-                       nfds = nfds * 2;
-                       if (nfds > NR_OPEN)
-                               nfds = NR_OPEN;
-               }
-       } while (nfds <= nr);
+       nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nr + 1));
+       if (nfds > NR_OPEN)
+               nfds = NR_OPEN;
 
        new_openset = alloc_fdset(nfds);
        new_execset = alloc_fdset(nfds);
@@ -283,11 +273,13 @@ static struct fdtable *alloc_fdtable(int nr)
        } while (nfds <= nr);
        new_fds = alloc_fd_array(nfds);
        if (!new_fds)
-               goto out;
+               goto out2;
        fdt->fd = new_fds;
        fdt->max_fds = nfds;
        fdt->free_files = NULL;
        return fdt;
+out2:
+       nfds = fdt->max_fdset;
 out:
        if (new_openset)
                free_fdset(new_openset, nfds);
@@ -379,6 +371,6 @@ static void __devinit fdtable_defer_list_init(int cpu)
 void __init files_defer_init(void)
 {
        int i;
-       for_each_cpu(i)
+       for_each_possible_cpu(i)
                fdtable_defer_list_init(i);
 }