return ERR_PTR() on failure, get rid of errorp Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> --- fs/file.c | 14 ++++---------- include/linux/fdtable.h | 2 +- kernel/fork.c | 26 ++++++++++++-------------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/fs/file.c b/fs/file.c index 01cef75ef132..b8b5b615d116 100644 --- a/fs/file.c +++ b/fs/file.c @@ -306,17 +306,16 @@ static unsigned int sane_fdtable_size(struct fdtable *fdt, unsigned int max_fds) * passed in files structure. * errorp will be valid only when the returned files_struct is NULL. */ -struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int *errorp) +struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds) { struct files_struct *newf; struct file **old_fds, **new_fds; unsigned int open_files, i; struct fdtable *old_fdt, *new_fdt; - *errorp = -ENOMEM; newf = kmem_cache_alloc(files_cachep, GFP_KERNEL); if (!newf) - goto out; + return ERR_PTR(-ENOMEM); atomic_set(&newf->count, 1); @@ -346,8 +345,8 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int new_fdt = alloc_fdtable(open_files); if (IS_ERR(new_fdt)) { - *errorp = PTR_ERR(new_fdt); - goto out_release; + kmem_cache_free(files_cachep, newf); + return ERR_CAST(new_fdt); } /* @@ -388,11 +387,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int rcu_assign_pointer(newf->fdt, new_fdt); return newf; - -out_release: - kmem_cache_free(files_cachep, newf); -out: - return NULL; } static struct fdtable *close_files(struct files_struct * files) diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 42cadad89f99..b1a913a17d04 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -102,7 +102,7 @@ struct task_struct; void put_files_struct(struct files_struct *fs); int unshare_files(void); -struct files_struct *dup_fd(struct files_struct *, unsigned, int *) __latent_entropy; +struct files_struct *dup_fd(struct files_struct *, unsigned) __latent_entropy; void do_close_on_exec(struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), diff --git a/kernel/fork.c b/kernel/fork.c index cc760491f201..67ab37db6400 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1754,33 +1754,30 @@ static int copy_files(unsigned long clone_flags, struct task_struct *tsk, int no_files) { struct files_struct *oldf, *newf; - int error = 0; /* * A background process may not have any files ... */ oldf = current->files; if (!oldf) - goto out; + return 0; if (no_files) { tsk->files = NULL; - goto out; + return 0; } if (clone_flags & CLONE_FILES) { atomic_inc(&oldf->count); - goto out; + return 0; } - newf = dup_fd(oldf, NR_OPEN_MAX, &error); - if (!newf) - goto out; + newf = dup_fd(oldf, NR_OPEN_MAX); + if (IS_ERR(newf)) + return PTR_ERR(newf); tsk->files = newf; - error = 0; -out: - return error; + return 0; } static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) @@ -3236,13 +3233,14 @@ int unshare_fd(unsigned long unshare_flags, unsigned int max_fds, struct files_struct **new_fdp) { struct files_struct *fd = current->files; - int error = 0; if ((unshare_flags & CLONE_FILES) && (fd && atomic_read(&fd->count) > 1)) { - *new_fdp = dup_fd(fd, max_fds, &error); - if (!*new_fdp) - return error; + *new_fdp = dup_fd(fd, max_fds); + if (IS_ERR(*new_fdp)) { + *new_fdp = NULL; + return PTR_ERR(new_fdp); + } } return 0; -- 2.39.2