aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c63
1 files changed, 37 insertions, 26 deletions
diff --git a/fs/open.c b/fs/open.c
index 8c741002f947..fca72c4d3f17 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -840,11 +840,15 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
840 if (flags & __O_SYNC) 840 if (flags & __O_SYNC)
841 flags |= O_DSYNC; 841 flags |= O_DSYNC;
842 842
843 /* 843 if (flags & O_TMPFILE) {
844 * If we have O_PATH in the open flag. Then we 844 if (!(flags & O_CREAT))
845 * cannot have anything other than the below set of flags 845 return -EINVAL;
846 */ 846 acc_mode = MAY_OPEN | ACC_MODE(flags);
847 if (flags & O_PATH) { 847 } else if (flags & O_PATH) {
848 /*
849 * If we have O_PATH in the open flag. Then we
850 * cannot have anything other than the below set of flags
851 */
848 flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH; 852 flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH;
849 acc_mode = 0; 853 acc_mode = 0;
850 } else { 854 } else {
@@ -876,7 +880,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
876 lookup_flags |= LOOKUP_DIRECTORY; 880 lookup_flags |= LOOKUP_DIRECTORY;
877 if (!(flags & O_NOFOLLOW)) 881 if (!(flags & O_NOFOLLOW))
878 lookup_flags |= LOOKUP_FOLLOW; 882 lookup_flags |= LOOKUP_FOLLOW;
879 return lookup_flags; 883 op->lookup_flags = lookup_flags;
884 return 0;
880} 885}
881 886
882/** 887/**
@@ -893,8 +898,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) 898struct file *file_open_name(struct filename *name, int flags, umode_t mode)
894{ 899{
895 struct open_flags op; 900 struct open_flags op;
896 int lookup = build_open_flags(flags, mode, &op); 901 int err = build_open_flags(flags, mode, &op);
897 return do_filp_open(AT_FDCWD, name, &op, lookup); 902 return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op);
898} 903}
899 904
900/** 905/**
@@ -919,37 +924,43 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
919 const char *filename, int flags) 924 const char *filename, int flags)
920{ 925{
921 struct open_flags op; 926 struct open_flags op;
922 int lookup = build_open_flags(flags, 0, &op); 927 int err = build_open_flags(flags, 0, &op);
928 if (err)
929 return ERR_PTR(err);
923 if (flags & O_CREAT) 930 if (flags & O_CREAT)
924 return ERR_PTR(-EINVAL); 931 return ERR_PTR(-EINVAL);
925 if (!filename && (flags & O_DIRECTORY)) 932 if (!filename && (flags & O_DIRECTORY))
926 if (!dentry->d_inode->i_op->lookup) 933 if (!dentry->d_inode->i_op->lookup)
927 return ERR_PTR(-ENOTDIR); 934 return ERR_PTR(-ENOTDIR);
928 return do_file_open_root(dentry, mnt, filename, &op, lookup); 935 return do_file_open_root(dentry, mnt, filename, &op);
929} 936}
930EXPORT_SYMBOL(file_open_root); 937EXPORT_SYMBOL(file_open_root);
931 938
932long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) 939long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
933{ 940{
934 struct open_flags op; 941 struct open_flags op;
935 int lookup = build_open_flags(flags, mode, &op); 942 int fd = build_open_flags(flags, mode, &op);
936 struct filename *tmp = getname(filename); 943 struct filename *tmp;
937 int fd = PTR_ERR(tmp); 944
938 945 if (fd)
939 if (!IS_ERR(tmp)) { 946 return fd;
940 fd = get_unused_fd_flags(flags); 947
941 if (fd >= 0) { 948 tmp = getname(filename);
942 struct file *f = do_filp_open(dfd, tmp, &op, lookup); 949 if (IS_ERR(tmp))
943 if (IS_ERR(f)) { 950 return PTR_ERR(tmp);
944 put_unused_fd(fd); 951
945 fd = PTR_ERR(f); 952 fd = get_unused_fd_flags(flags);
946 } else { 953 if (fd >= 0) {
947 fsnotify_open(f); 954 struct file *f = do_filp_open(dfd, tmp, &op);
948 fd_install(fd, f); 955 if (IS_ERR(f)) {
949 } 956 put_unused_fd(fd);
957 fd = PTR_ERR(f);
958 } else {
959 fsnotify_open(f);
960 fd_install(fd, f);
950 } 961 }
951 putname(tmp);
952 } 962 }
963 putname(tmp);
953 return fd; 964 return fd;
954} 965}
955 966