]> Pileus Git - ~andy/linux/blobdiff - fs/file_table.c
propagate error from get_empty_filp() to its callers
[~andy/linux] / fs / file_table.c
index 0f607ce89acc43f5cebc1b025ffe45a8a5e352b2..cd76d4fdf4a497c5653267affd1e79bff250c791 100644 (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;