propagate error from get_empty_filp() to its callers

Based on parts from Anatol's patch (the rest is the next commit).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2013-02-14 20:41:04 -05:00
parent 496ad9aa8e
commit 1afc99beaf
3 changed files with 28 additions and 30 deletions

View File

@ -94,8 +94,8 @@ int proc_nr_files(ctl_table *table, int write,
#endif
/* Find an unused file structure and return a pointer to it.
* Returns NULL, if there are no more free file structures or
* we run out of memory.
* Returns an error pointer if some error happend e.g. we over file
* structures limit, run out of memory or operation is not permitted.
*
* Be very careful using this. You are responsible for
* getting write access to any mount that you might assign
@ -107,7 +107,8 @@ struct file *get_empty_filp(void)
{
const struct cred *cred = current_cred();
static long old_max;
struct file * f;
struct file *f;
int error;
/*
* Privileged users can go above max_files
@ -122,13 +123,16 @@ struct file *get_empty_filp(void)
}
f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL);
if (f == NULL)
goto fail;
if (unlikely(!f))
return ERR_PTR(-ENOMEM);
percpu_counter_inc(&nr_files);
f->f_cred = get_cred(cred);
if (security_file_alloc(f))
goto fail_sec;
error = security_file_alloc(f);
if (unlikely(error)) {
file_free(f);
return ERR_PTR(error);
}
INIT_LIST_HEAD(&f->f_u.fu_list);
atomic_long_set(&f->f_count, 1);
@ -144,12 +148,7 @@ over:
pr_info("VFS: file-max limit %lu reached\n", get_max_files());
old_max = get_nr_files();
}
goto fail;
fail_sec:
file_free(f);
fail:
return NULL;
return ERR_PTR(-ENFILE);
}
/**
@ -173,7 +172,7 @@ struct file *alloc_file(struct path *path, fmode_t mode,
struct file *file;
file = get_empty_filp();
if (!file)
if (IS_ERR(file))
return NULL;
file->f_path = *path;

View File

@ -2941,8 +2941,8 @@ static struct file *path_openat(int dfd, struct filename *pathname,
int error;
file = get_empty_filp();
if (!file)
return ERR_PTR(-ENFILE);
if (IS_ERR(file))
return file;
file->f_flags = op->open_flag;

View File

@ -810,23 +810,22 @@ struct file *dentry_open(const struct path *path, int flags,
/* We must always pass in a valid mount pointer. */
BUG_ON(!path->mnt);
error = -ENFILE;
f = get_empty_filp();
if (f == NULL)
return ERR_PTR(error);
f->f_flags = flags;
f->f_path = *path;
error = do_dentry_open(f, NULL, cred);
if (!error) {
error = open_check_o_direct(f);
if (error) {
fput(f);
if (!IS_ERR(f)) {
f->f_flags = flags;
f->f_path = *path;
error = do_dentry_open(f, NULL, cred);
if (!error) {
/* from now on we need fput() to dispose of f */
error = open_check_o_direct(f);
if (error) {
fput(f);
f = ERR_PTR(error);
}
} else {
put_filp(f);
f = ERR_PTR(error);
}
} else {
put_filp(f);
f = ERR_PTR(error);
}
return f;
}