|
@@ -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;
|
|
|
}
|
|
|
|