aboutsummaryrefslogtreecommitdiffstats
path: root/fs/file.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-05-08 21:02:45 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-05-16 17:22:33 -0400
commit9dec3c4d306b09b31331e475e895bb9674e16d81 (patch)
treea4755dd7f368d78cfe24696b7e469b41562f1aea /fs/file.c
parent02afc6267f6d55d47aba9fcafdbd1b7230d2294a (diff)
[PATCH] dup_fd() part 2
use alloc_fdtable() instead of expand_files(), get rid of pointless grabbing newf->file_lock, kill magic in copy_fdtable() that used to be there only to skip copying when called from dup_fd(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/file.c')
-rw-r--r--fs/file.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/fs/file.c b/fs/file.c
index 7dbadaaf00f0..6491b2b5bc38 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -119,8 +119,6 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
119 unsigned int cpy, set; 119 unsigned int cpy, set;
120 120
121 BUG_ON(nfdt->max_fds < ofdt->max_fds); 121 BUG_ON(nfdt->max_fds < ofdt->max_fds);
122 if (ofdt->max_fds == 0)
123 return;
124 122
125 cpy = ofdt->max_fds * sizeof(struct file *); 123 cpy = ofdt->max_fds * sizeof(struct file *);
126 set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *); 124 set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *);
@@ -327,14 +325,24 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
327 * Note: we're not a clone task, so the open count won't change. 325 * Note: we're not a clone task, so the open count won't change.
328 */ 326 */
329 if (open_files > new_fdt->max_fds) { 327 if (open_files > new_fdt->max_fds) {
330 new_fdt->max_fds = 0;
331 spin_unlock(&oldf->file_lock); 328 spin_unlock(&oldf->file_lock);
332 spin_lock(&newf->file_lock); 329
333 *errorp = expand_files(newf, open_files-1); 330 new_fdt = alloc_fdtable(open_files - 1);
334 spin_unlock(&newf->file_lock); 331 if (!new_fdt) {
335 if (*errorp < 0) 332 *errorp = -ENOMEM;
333 goto out_release;
334 }
335
336 /* beyond sysctl_nr_open; nothing to do */
337 if (unlikely(new_fdt->max_fds < open_files)) {
338 free_fdarr(new_fdt);
339 free_fdset(new_fdt);
340 kfree(new_fdt);
341 *errorp = -EMFILE;
336 goto out_release; 342 goto out_release;
337 new_fdt = files_fdtable(newf); 343 }
344 rcu_assign_pointer(files->fdt, new_fdt);
345
338 /* 346 /*
339 * Reacquire the oldf lock and a pointer to its fd table 347 * Reacquire the oldf lock and a pointer to its fd table
340 * who knows it may have a new bigger fd table. We need 348 * who knows it may have a new bigger fd table. We need