aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-06-11 00:23:01 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:57:09 -0400
commitf9652e10c12b43d9bb957269745cf2fa5682fa92 (patch)
treefd358891b9778f7bdd8764163aa2029d01efcf9c /fs/open.c
parent50cd2c577668a170750b15f9a88f022f681ce3c7 (diff)
allow build_open_flags() to return an error
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/fs/open.c b/fs/open.c
index 8c741002f947..5a40a4a51757 100644
--- 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
876 lookup_flags |= LOOKUP_DIRECTORY; 876 lookup_flags |= LOOKUP_DIRECTORY;
877 if (!(flags & O_NOFOLLOW)) 877 if (!(flags & O_NOFOLLOW))
878 lookup_flags |= LOOKUP_FOLLOW; 878 lookup_flags |= LOOKUP_FOLLOW;
879 return lookup_flags; 879 op->lookup_flags = lookup_flags;
880 return 0;
880} 881}
881 882
882/** 883/**
@@ -893,8 +894,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
893struct file *file_open_name(struct filename *name, int flags, umode_t mode) 894struct file *file_open_name(struct filename *name, int flags, umode_t mode)
894{ 895{
895 struct open_flags op; 896 struct open_flags op;
896 int lookup = build_open_flags(flags, mode, &op); 897 int err = build_open_flags(flags, mode, &op);
897 return do_filp_open(AT_FDCWD, name, &op, lookup); 898 return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op);
898} 899}
899 900
900/** 901/**
@@ -919,37 +920,43 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
919 const char *filename, int flags) 920 const char *filename, int flags)
920{ 921{
921 struct open_flags op; 922 struct open_flags op;
922 int lookup = build_open_flags(flags, 0, &op); 923 int err = build_open_flags(flags, 0, &op);
924 if (err)
925 return ERR_PTR(err);
923 if (flags & O_CREAT) 926 if (flags & O_CREAT)
924 return ERR_PTR(-EINVAL); 927 return ERR_PTR(-EINVAL);
925 if (!filename && (flags & O_DIRECTORY)) 928 if (!filename && (flags & O_DIRECTORY))
926 if (!dentry->d_inode->i_op->lookup) 929 if (!dentry->d_inode->i_op->lookup)
927 return ERR_PTR(-ENOTDIR); 930 return ERR_PTR(-ENOTDIR);
928 return do_file_open_root(dentry, mnt, filename, &op, lookup); 931 return do_file_open_root(dentry, mnt, filename, &op);
929} 932}
930EXPORT_SYMBOL(file_open_root); 933EXPORT_SYMBOL(file_open_root);
931 934
932long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) 935long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
933{ 936{
934 struct open_flags op; 937 struct open_flags op;
935 int lookup = build_open_flags(flags, mode, &op); 938 int fd = build_open_flags(flags, mode, &op);
936 struct filename *tmp = getname(filename); 939 struct filename *tmp;
937 int fd = PTR_ERR(tmp); 940
938 941 if (fd)
939 if (!IS_ERR(tmp)) { 942 return fd;
940 fd = get_unused_fd_flags(flags); 943
941 if (fd >= 0) { 944 tmp = getname(filename);
942 struct file *f = do_filp_open(dfd, tmp, &op, lookup); 945 if (IS_ERR(tmp))
943 if (IS_ERR(f)) { 946 return PTR_ERR(tmp);
944 put_unused_fd(fd); 947
945 fd = PTR_ERR(f); 948 fd = get_unused_fd_flags(flags);
946 } else { 949 if (fd >= 0) {
947 fsnotify_open(f); 950 struct file *f = do_filp_open(dfd, tmp, &op);
948 fd_install(fd, f); 951 if (IS_ERR(f)) {
949 } 952 put_unused_fd(fd);
953 fd = PTR_ERR(f);
954 } else {
955 fsnotify_open(f);
956 fd_install(fd, f);
950 } 957 }
951 putname(tmp);
952 } 958 }
959 putname(tmp);
953 return fd; 960 return fd;
954} 961}
955 962