diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-05-08 21:02:45 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-05-16 17:22:33 -0400 |
commit | 9dec3c4d306b09b31331e475e895bb9674e16d81 (patch) | |
tree | a4755dd7f368d78cfe24696b7e469b41562f1aea /fs/file.c | |
parent | 02afc6267f6d55d47aba9fcafdbd1b7230d2294a (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.c | 24 |
1 files changed, 16 insertions, 8 deletions
@@ -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 |