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