vfs: make path_openat take a struct filename pointer

...and fix up the callers. For do_file_open_root, just declare a
struct filename on the stack and fill out the .name field. For
do_filp_open, make it also take a struct filename pointer, and fix up its
callers to call it appropriately.

For filp_open, add a variant that takes a struct filename pointer and turn
filp_open into a wrapper around it.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Jeff Layton 2012-10-10 16:43:10 -04:00 committed by Al Viro
parent 873f1eedc1
commit 669abf4e55
7 changed files with 42 additions and 21 deletions

View File

@ -116,7 +116,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
if (IS_ERR(tmp)) if (IS_ERR(tmp))
goto out; goto out;
file = do_filp_open(AT_FDCWD, tmp->name, &uselib_flags, LOOKUP_FOLLOW); file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW);
putname(tmp); putname(tmp);
error = PTR_ERR(file); error = PTR_ERR(file);
if (IS_ERR(file)) if (IS_ERR(file))
@ -751,13 +751,14 @@ struct file *open_exec(const char *name)
{ {
struct file *file; struct file *file;
int err; int err;
struct filename tmp = { .name = name };
static const struct open_flags open_exec_flags = { static const struct open_flags open_exec_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
.acc_mode = MAY_EXEC | MAY_OPEN, .acc_mode = MAY_EXEC | MAY_OPEN,
.intent = LOOKUP_OPEN .intent = LOOKUP_OPEN
}; };
file = do_filp_open(AT_FDCWD, name, &open_exec_flags, LOOKUP_FOLLOW); file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW);
if (IS_ERR(file)) if (IS_ERR(file))
goto out; goto out;

View File

@ -97,8 +97,8 @@ struct open_flags {
int acc_mode; int acc_mode;
int intent; int intent;
}; };
extern struct file *do_filp_open(int dfd, const char *pathname, extern struct file *do_filp_open(int dfd, struct filename *pathname,
const struct open_flags *op, int lookup_flags); const struct open_flags *op, int flags);
extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
const char *, const struct open_flags *, int lookup_flags); const char *, const struct open_flags *, int lookup_flags);

View File

@ -2662,7 +2662,7 @@ static int lookup_open(struct nameidata *nd, struct path *path,
*/ */
static int do_last(struct nameidata *nd, struct path *path, static int do_last(struct nameidata *nd, struct path *path,
struct file *file, const struct open_flags *op, struct file *file, const struct open_flags *op,
int *opened, const char *pathname) int *opened, struct filename *name)
{ {
struct dentry *dir = nd->path.dentry; struct dentry *dir = nd->path.dentry;
int open_flag = op->open_flag; int open_flag = op->open_flag;
@ -2674,6 +2674,7 @@ static int do_last(struct nameidata *nd, struct path *path,
struct path save_parent = { .dentry = NULL, .mnt = NULL }; struct path save_parent = { .dentry = NULL, .mnt = NULL };
bool retried = false; bool retried = false;
int error; int error;
const char *pathname = name->name;
nd->flags &= ~LOOKUP_PARENT; nd->flags &= ~LOOKUP_PARENT;
nd->flags |= op->intent; nd->flags |= op->intent;
@ -2908,7 +2909,7 @@ static int do_last(struct nameidata *nd, struct path *path,
goto retry_lookup; goto retry_lookup;
} }
static struct file *path_openat(int dfd, const char *pathname, static struct file *path_openat(int dfd, struct filename *pathname,
struct nameidata *nd, const struct open_flags *op, int flags) struct nameidata *nd, const struct open_flags *op, int flags)
{ {
struct file *base = NULL; struct file *base = NULL;
@ -2923,12 +2924,12 @@ static struct file *path_openat(int dfd, const char *pathname,
file->f_flags = op->open_flag; file->f_flags = op->open_flag;
error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
current->total_link_count = 0; current->total_link_count = 0;
error = link_path_walk(pathname, nd); error = link_path_walk(pathname->name, nd);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
@ -2974,7 +2975,7 @@ static struct file *path_openat(int dfd, const char *pathname,
return file; return file;
} }
struct file *do_filp_open(int dfd, const char *pathname, struct file *do_filp_open(int dfd, struct filename *pathname,
const struct open_flags *op, int flags) const struct open_flags *op, int flags)
{ {
struct nameidata nd; struct nameidata nd;
@ -2993,6 +2994,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
{ {
struct nameidata nd; struct nameidata nd;
struct file *file; struct file *file;
struct filename filename = { .name = name };
nd.root.mnt = mnt; nd.root.mnt = mnt;
nd.root.dentry = dentry; nd.root.dentry = dentry;
@ -3002,11 +3004,11 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN)
return ERR_PTR(-ELOOP); return ERR_PTR(-ELOOP);
file = path_openat(-1, name, &nd, op, flags | LOOKUP_RCU); file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU);
if (unlikely(file == ERR_PTR(-ECHILD))) if (unlikely(file == ERR_PTR(-ECHILD)))
file = path_openat(-1, name, &nd, op, flags); file = path_openat(-1, &filename, &nd, op, flags);
if (unlikely(file == ERR_PTR(-ESTALE))) if (unlikely(file == ERR_PTR(-ESTALE)))
file = path_openat(-1, name, &nd, op, flags | LOOKUP_REVAL); file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_REVAL);
return file; return file;
} }

View File

@ -858,6 +858,24 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
return lookup_flags; return lookup_flags;
} }
/**
* file_open_name - open file and return file pointer
*
* @name: struct filename containing path to open
* @flags: open flags as per the open(2) second argument
* @mode: mode for the new file if O_CREAT is set, else ignored
*
* This is the helper to open a file from kernelspace if you really
* have to. But in generally you should not do this, so please move
* along, nothing to see here..
*/
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);
}
/** /**
* filp_open - open file and return file pointer * filp_open - open file and return file pointer
* *
@ -871,9 +889,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
*/ */
struct file *filp_open(const char *filename, int flags, umode_t mode) struct file *filp_open(const char *filename, int flags, umode_t mode)
{ {
struct open_flags op; struct filename name = {.name = filename};
int lookup = build_open_flags(flags, mode, &op); return file_open_name(&name, flags, mode);
return do_filp_open(AT_FDCWD, filename, &op, lookup);
} }
EXPORT_SYMBOL(filp_open); EXPORT_SYMBOL(filp_open);
@ -901,7 +918,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
if (!IS_ERR(tmp)) { if (!IS_ERR(tmp)) {
fd = get_unused_fd_flags(flags); fd = get_unused_fd_flags(flags);
if (fd >= 0) { if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp->name, &op, lookup); struct file *f = do_filp_open(dfd, tmp, &op, lookup);
if (IS_ERR(f)) { if (IS_ERR(f)) {
put_unused_fd(fd); put_unused_fd(fd);
fd = PTR_ERR(f); fd = PTR_ERR(f);

View File

@ -2207,6 +2207,7 @@ extern int do_fallocate(struct file *file, int mode, loff_t offset,
loff_t len); loff_t len);
extern long do_sys_open(int dfd, const char __user *filename, int flags, extern long do_sys_open(int dfd, const char __user *filename, int flags,
umode_t mode); umode_t mode);
extern struct file *file_open_name(struct filename *, int, umode_t);
extern struct file *filp_open(const char *, int, umode_t); extern struct file *filp_open(const char *, int, umode_t);
extern struct file *file_open_root(struct dentry *, struct vfsmount *, extern struct file *file_open_root(struct dentry *, struct vfsmount *,
const char *, int); const char *, int);

View File

@ -193,7 +193,7 @@ static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file,
} }
} }
static int acct_on(const char *name) static int acct_on(struct filename *pathname)
{ {
struct file *file; struct file *file;
struct vfsmount *mnt; struct vfsmount *mnt;
@ -201,7 +201,7 @@ static int acct_on(const char *name)
struct bsd_acct_struct *acct = NULL; struct bsd_acct_struct *acct = NULL;
/* Difference from BSD - they don't do O_APPEND */ /* Difference from BSD - they don't do O_APPEND */
file = filp_open(name, O_WRONLY|O_APPEND|O_LARGEFILE, 0); file = file_open_name(pathname, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
if (IS_ERR(file)) if (IS_ERR(file))
return PTR_ERR(file); return PTR_ERR(file);
@ -263,7 +263,7 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
struct filename *tmp = getname(name); struct filename *tmp = getname(name);
if (IS_ERR(tmp)) if (IS_ERR(tmp))
return (PTR_ERR(tmp)); return (PTR_ERR(tmp));
error = acct_on(tmp->name); error = acct_on(tmp);
putname(tmp); putname(tmp);
} else { } else {
struct bsd_acct_struct *acct; struct bsd_acct_struct *acct;

View File

@ -1498,7 +1498,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
if (IS_ERR(pathname)) if (IS_ERR(pathname))
goto out; goto out;
victim = filp_open(pathname->name, O_RDWR|O_LARGEFILE, 0); victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0);
err = PTR_ERR(victim); err = PTR_ERR(victim);
if (IS_ERR(victim)) if (IS_ERR(victim))
goto out; goto out;
@ -1966,7 +1966,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
name = NULL; name = NULL;
goto bad_swap; goto bad_swap;
} }
swap_file = filp_open(name->name, O_RDWR|O_LARGEFILE, 0); swap_file = file_open_name(name, O_RDWR|O_LARGEFILE, 0);
if (IS_ERR(swap_file)) { if (IS_ERR(swap_file)) {
error = PTR_ERR(swap_file); error = PTR_ERR(swap_file);
swap_file = NULL; swap_file = NULL;