linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / file.c
index b3c6b82..44ab07a 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -125,8 +125,7 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
                kmem_cache_free(files_cachep, fdt->free_files);
                return;
        }
-       if (fdt->max_fdset <= EMBEDDED_FD_SET_SIZE &&
-               fdt->max_fds <= NR_OPEN_DEFAULT) {
+       if (fdt->max_fdset <= __FD_SETSIZE && fdt->max_fds <= NR_OPEN_DEFAULT) {
                /*
                 * The fdtable was embedded
                 */
@@ -156,9 +155,8 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
 
 void free_fdtable(struct fdtable *fdt)
 {
-       if (fdt->free_files ||
-               fdt->max_fdset > EMBEDDED_FD_SET_SIZE ||
-               fdt->max_fds > NR_OPEN_DEFAULT)
+       if (fdt->free_files || fdt->max_fdset > __FD_SETSIZE ||
+                                       fdt->max_fds > NR_OPEN_DEFAULT)
                call_rcu(&fdt->rcu, free_fdtable_rcu);
 }
 
@@ -201,6 +199,7 @@ 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;
 }
 
 /*
@@ -221,9 +220,11 @@ fd_set * alloc_fdset(int num)
 
 void free_fdset(fd_set *array, int num)
 {
-       if (num <= EMBEDDED_FD_SET_SIZE) /* Don't free an embedded fdset */
+       int size = num / 8;
+
+       if (num <= __FD_SETSIZE) /* Don't free an embedded fdset */
                return;
-       else if (num <= 8 * PAGE_SIZE)
+       else if (size <= PAGE_SIZE)
                kfree(array);
        else
                vfree(array);
@@ -236,13 +237,22 @@ static struct fdtable *alloc_fdtable(int nr)
        fd_set *new_openset = NULL, *new_execset = NULL;
        struct file **new_fds;
 
-       fdt = kzalloc(sizeof(*fdt), GFP_KERNEL);
+       fdt = kmalloc(sizeof(*fdt), GFP_KERNEL);
        if (!fdt)
                goto out;
+       memset(fdt, 0, sizeof(*fdt));
 
-       nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nr + 1));
-       if (nfds > NR_OPEN)
-               nfds = NR_OPEN;
+       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);
 
        new_openset = alloc_fdset(nfds);
        new_execset = alloc_fdset(nfds);
@@ -371,6 +381,6 @@ static void __devinit fdtable_defer_list_init(int cpu)
 void __init files_defer_init(void)
 {
        int i;
-       for_each_possible_cpu(i)
+       for_each_cpu(i)
                fdtable_defer_list_init(i);
 }