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: |
