Commit f9652e10c12b43d9bb957269745cf2fa5682fa92

Authored by Al Viro
1 parent 50cd2c5776

allow build_open_flags() to return an error

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 4 changed files with 41 additions and 31 deletions Side-by-side Diff

... ... @@ -110,13 +110,14 @@
110 110 static const struct open_flags uselib_flags = {
111 111 .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
112 112 .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN,
113   - .intent = LOOKUP_OPEN
  113 + .intent = LOOKUP_OPEN,
  114 + .lookup_flags = LOOKUP_FOLLOW,
114 115 };
115 116  
116 117 if (IS_ERR(tmp))
117 118 goto out;
118 119  
119   - file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW);
  120 + file = do_filp_open(AT_FDCWD, tmp, &uselib_flags);
120 121 putname(tmp);
121 122 error = PTR_ERR(file);
122 123 if (IS_ERR(file))
123 124  
... ... @@ -756,10 +757,11 @@
756 757 static const struct open_flags open_exec_flags = {
757 758 .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
758 759 .acc_mode = MAY_EXEC | MAY_OPEN,
759   - .intent = LOOKUP_OPEN
  760 + .intent = LOOKUP_OPEN,
  761 + .lookup_flags = LOOKUP_FOLLOW,
760 762 };
761 763  
762   - file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW);
  764 + file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags);
763 765 if (IS_ERR(file))
764 766 goto out;
765 767  
... ... @@ -96,11 +96,12 @@
96 96 umode_t mode;
97 97 int acc_mode;
98 98 int intent;
  99 + int lookup_flags;
99 100 };
100 101 extern struct file *do_filp_open(int dfd, struct filename *pathname,
101   - const struct open_flags *op, int flags);
  102 + const struct open_flags *op);
102 103 extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
103   - const char *, const struct open_flags *, int lookup_flags);
  104 + const char *, const struct open_flags *);
104 105  
105 106 extern long do_handle_open(int mountdirfd,
106 107 struct file_handle __user *ufh, int open_flag);
... ... @@ -2969,9 +2969,10 @@
2969 2969 }
2970 2970  
2971 2971 struct file *do_filp_open(int dfd, struct filename *pathname,
2972   - const struct open_flags *op, int flags)
  2972 + const struct open_flags *op)
2973 2973 {
2974 2974 struct nameidata nd;
  2975 + int flags = op->lookup_flags;
2975 2976 struct file *filp;
2976 2977  
2977 2978 filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
2978 2979  
2979 2980  
... ... @@ -2983,16 +2984,15 @@
2983 2984 }
2984 2985  
2985 2986 struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
2986   - const char *name, const struct open_flags *op, int flags)
  2987 + const char *name, const struct open_flags *op)
2987 2988 {
2988 2989 struct nameidata nd;
2989 2990 struct file *file;
2990 2991 struct filename filename = { .name = name };
  2992 + int flags = op->lookup_flags | LOOKUP_ROOT;
2991 2993  
2992 2994 nd.root.mnt = mnt;
2993 2995 nd.root.dentry = dentry;
2994   -
2995   - flags |= LOOKUP_ROOT;
2996 2996  
2997 2997 if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN)
2998 2998 return ERR_PTR(-ELOOP);
... ... @@ -876,7 +876,8 @@
876 876 lookup_flags |= LOOKUP_DIRECTORY;
877 877 if (!(flags & O_NOFOLLOW))
878 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 @@
893 894 struct file *file_open_name(struct filename *name, int flags, umode_t mode)
894 895 {
895 896 struct open_flags op;
896   - int lookup = build_open_flags(flags, mode, &op);
897   - return do_filp_open(AT_FDCWD, name, &op, lookup);
  897 + int err = build_open_flags(flags, mode, &op);
  898 + return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op);
898 899 }
899 900  
900 901 /**
901 902  
902 903  
903 904  
904 905  
905 906  
... ... @@ -919,37 +920,43 @@
919 920 const char *filename, int flags)
920 921 {
921 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 926 if (flags & O_CREAT)
924 927 return ERR_PTR(-EINVAL);
925 928 if (!filename && (flags & O_DIRECTORY))
926 929 if (!dentry->d_inode->i_op->lookup)
927 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 }
930 933 EXPORT_SYMBOL(file_open_root);
931 934  
932 935 long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
933 936 {
934 937 struct open_flags op;
935   - int lookup = build_open_flags(flags, mode, &op);
936   - struct filename *tmp = getname(filename);
937   - int fd = PTR_ERR(tmp);
  938 + int fd = build_open_flags(flags, mode, &op);
  939 + struct filename *tmp;
938 940  
939   - if (!IS_ERR(tmp)) {
940   - fd = get_unused_fd_flags(flags);
941   - if (fd >= 0) {
942   - struct file *f = do_filp_open(dfd, tmp, &op, lookup);
943   - if (IS_ERR(f)) {
944   - put_unused_fd(fd);
945   - fd = PTR_ERR(f);
946   - } else {
947   - fsnotify_open(f);
948   - fd_install(fd, f);
949   - }
  941 + if (fd)
  942 + return fd;
  943 +
  944 + tmp = getname(filename);
  945 + if (IS_ERR(tmp))
  946 + return PTR_ERR(tmp);
  947 +
  948 + fd = get_unused_fd_flags(flags);
  949 + if (fd >= 0) {
  950 + struct file *f = do_filp_open(dfd, tmp, &op);
  951 + if (IS_ERR(f)) {
  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 960 return fd;
954 961 }
955 962