diff options
-rw-r--r-- | fs/file.c | 43 |
1 files changed, 15 insertions, 28 deletions
@@ -273,31 +273,6 @@ static int count_open_files(struct fdtable *fdt) | |||
273 | return i; | 273 | return i; |
274 | } | 274 | } |
275 | 275 | ||
276 | static struct files_struct *alloc_files(void) | ||
277 | { | ||
278 | struct files_struct *newf; | ||
279 | struct fdtable *fdt; | ||
280 | |||
281 | newf = kmem_cache_alloc(files_cachep, GFP_KERNEL); | ||
282 | if (!newf) | ||
283 | goto out; | ||
284 | |||
285 | atomic_set(&newf->count, 1); | ||
286 | |||
287 | spin_lock_init(&newf->file_lock); | ||
288 | newf->next_fd = 0; | ||
289 | fdt = &newf->fdtab; | ||
290 | fdt->max_fds = NR_OPEN_DEFAULT; | ||
291 | fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; | ||
292 | fdt->open_fds = (fd_set *)&newf->open_fds_init; | ||
293 | fdt->fd = &newf->fd_array[0]; | ||
294 | INIT_RCU_HEAD(&fdt->rcu); | ||
295 | fdt->next = NULL; | ||
296 | rcu_assign_pointer(newf->fdt, fdt); | ||
297 | out: | ||
298 | return newf; | ||
299 | } | ||
300 | |||
301 | /* | 276 | /* |
302 | * Allocate a new files structure and copy contents from the | 277 | * Allocate a new files structure and copy contents from the |
303 | * passed in files structure. | 278 | * passed in files structure. |
@@ -311,13 +286,24 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
311 | struct fdtable *old_fdt, *new_fdt; | 286 | struct fdtable *old_fdt, *new_fdt; |
312 | 287 | ||
313 | *errorp = -ENOMEM; | 288 | *errorp = -ENOMEM; |
314 | newf = alloc_files(); | 289 | newf = kmem_cache_alloc(files_cachep, GFP_KERNEL); |
315 | if (!newf) | 290 | if (!newf) |
316 | goto out; | 291 | goto out; |
317 | 292 | ||
293 | atomic_set(&newf->count, 1); | ||
294 | |||
295 | spin_lock_init(&newf->file_lock); | ||
296 | newf->next_fd = 0; | ||
297 | new_fdt = &newf->fdtab; | ||
298 | new_fdt->max_fds = NR_OPEN_DEFAULT; | ||
299 | new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; | ||
300 | new_fdt->open_fds = (fd_set *)&newf->open_fds_init; | ||
301 | new_fdt->fd = &newf->fd_array[0]; | ||
302 | INIT_RCU_HEAD(&new_fdt->rcu); | ||
303 | new_fdt->next = NULL; | ||
304 | |||
318 | spin_lock(&oldf->file_lock); | 305 | spin_lock(&oldf->file_lock); |
319 | old_fdt = files_fdtable(oldf); | 306 | old_fdt = files_fdtable(oldf); |
320 | new_fdt = files_fdtable(newf); | ||
321 | open_files = count_open_files(old_fdt); | 307 | open_files = count_open_files(old_fdt); |
322 | 308 | ||
323 | /* | 309 | /* |
@@ -341,7 +327,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
341 | *errorp = -EMFILE; | 327 | *errorp = -EMFILE; |
342 | goto out_release; | 328 | goto out_release; |
343 | } | 329 | } |
344 | rcu_assign_pointer(files->fdt, new_fdt); | ||
345 | 330 | ||
346 | /* | 331 | /* |
347 | * Reacquire the oldf lock and a pointer to its fd table | 332 | * Reacquire the oldf lock and a pointer to its fd table |
@@ -391,6 +376,8 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
391 | memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); | 376 | memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); |
392 | } | 377 | } |
393 | 378 | ||
379 | rcu_assign_pointer(newf->fdt, new_fdt); | ||
380 | |||
394 | return newf; | 381 | return newf; |
395 | 382 | ||
396 | out_release: | 383 | out_release: |