aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/file.c43
1 files changed, 15 insertions, 28 deletions
diff --git a/fs/file.c b/fs/file.c
index 6491b2b5bc38..689d2b6947e3 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -273,31 +273,6 @@ static int count_open_files(struct fdtable *fdt)
273 return i; 273 return i;
274} 274}
275 275
276static 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);
297out:
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
396out_release: 383out_release: