]> Pileus Git - ~andy/linux/blobdiff - fs/open.c
allow build_open_flags() to return an error
[~andy/linux] / fs / open.c
index 8c741002f947908d26788ad83c91f28bc44c8295..5a40a4a5175739fd1c08c498a38598f84f457242 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -876,7 +876,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
                lookup_flags |= LOOKUP_DIRECTORY;
        if (!(flags & O_NOFOLLOW))
                lookup_flags |= LOOKUP_FOLLOW;
-       return lookup_flags;
+       op->lookup_flags = lookup_flags;
+       return 0;
 }
 
 /**
@@ -893,8 +894,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
 struct file *file_open_name(struct filename *name, int flags, umode_t mode)
 {
        struct open_flags op;
-       int lookup = build_open_flags(flags, mode, &op);
-       return do_filp_open(AT_FDCWD, name, &op, lookup);
+       int err = build_open_flags(flags, mode, &op);
+       return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op);
 }
 
 /**
@@ -919,37 +920,43 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
                            const char *filename, int flags)
 {
        struct open_flags op;
-       int lookup = build_open_flags(flags, 0, &op);
+       int err = build_open_flags(flags, 0, &op);
+       if (err)
+               return ERR_PTR(err);
        if (flags & O_CREAT)
                return ERR_PTR(-EINVAL);
        if (!filename && (flags & O_DIRECTORY))
                if (!dentry->d_inode->i_op->lookup)
                        return ERR_PTR(-ENOTDIR);
-       return do_file_open_root(dentry, mnt, filename, &op, lookup);
+       return do_file_open_root(dentry, mnt, filename, &op);
 }
 EXPORT_SYMBOL(file_open_root);
 
 long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
 {
        struct open_flags op;
-       int lookup = build_open_flags(flags, mode, &op);
-       struct filename *tmp = getname(filename);
-       int fd = PTR_ERR(tmp);
-
-       if (!IS_ERR(tmp)) {
-               fd = get_unused_fd_flags(flags);
-               if (fd >= 0) {
-                       struct file *f = do_filp_open(dfd, tmp, &op, lookup);
-                       if (IS_ERR(f)) {
-                               put_unused_fd(fd);
-                               fd = PTR_ERR(f);
-                       } else {
-                               fsnotify_open(f);
-                               fd_install(fd, f);
-                       }
+       int fd = build_open_flags(flags, mode, &op);
+       struct filename *tmp;
+
+       if (fd)
+               return fd;
+
+       tmp = getname(filename);
+       if (IS_ERR(tmp))
+               return PTR_ERR(tmp);
+
+       fd = get_unused_fd_flags(flags);
+       if (fd >= 0) {
+               struct file *f = do_filp_open(dfd, tmp, &op);
+               if (IS_ERR(f)) {
+                       put_unused_fd(fd);
+                       fd = PTR_ERR(f);
+               } else {
+                       fsnotify_open(f);
+                       fd_install(fd, f);
                }
-               putname(tmp);
        }
+       putname(tmp);
        return fd;
 }