summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c5
-rw-r--r--fs/internal.h4
-rw-r--r--fs/namei.c18
-rw-r--r--fs/open.c25
4 files changed, 36 insertions, 16 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 4e591e20e10..8b9011b6704 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -116,7 +116,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
if (IS_ERR(tmp))
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);
error = PTR_ERR(file);
if (IS_ERR(file))
@@ -751,13 +751,14 @@ struct file *open_exec(const char *name)
{
struct file *file;
int err;
+ struct filename tmp = { .name = name };
static const struct open_flags open_exec_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
.acc_mode = MAY_EXEC | MAY_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))
goto out;
diff --git a/fs/internal.h b/fs/internal.h
index 371bcc4b169..916b7cbf3e3 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -97,8 +97,8 @@ struct open_flags {
int acc_mode;
int intent;
};
-extern struct file *do_filp_open(int dfd, const char *pathname,
- const struct open_flags *op, int lookup_flags);
+extern struct file *do_filp_open(int dfd, struct filename *pathname,
+ const struct open_flags *op, int flags);
extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
const char *, const struct open_flags *, int lookup_flags);
diff --git a/fs/namei.c b/fs/namei.c
index 8c14353fb75..6bbd8fdfb1f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2662,7 +2662,7 @@ out_dput:
*/
static int do_last(struct nameidata *nd, struct path *path,
struct file *file, const struct open_flags *op,
- int *opened, const char *pathname)
+ int *opened, struct filename *name)
{
struct dentry *dir = nd->path.dentry;
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 };
bool retried = false;
int error;
+ const char *pathname = name->name;
nd->flags &= ~LOOKUP_PARENT;
nd->flags |= op->intent;
@@ -2908,7 +2909,7 @@ stale_open:
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 file *base = NULL;
@@ -2923,12 +2924,12 @@ static struct file *path_openat(int dfd, const char *pathname,
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))
goto out;
current->total_link_count = 0;
- error = link_path_walk(pathname, nd);
+ error = link_path_walk(pathname->name, nd);
if (unlikely(error))
goto out;
@@ -2974,7 +2975,7 @@ out:
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)
{
struct nameidata nd;
@@ -2993,6 +2994,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
{
struct nameidata nd;
struct file *file;
+ struct filename filename = { .name = name };
nd.root.mnt = mnt;
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)
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)))
- file = path_openat(-1, name, &nd, op, flags);
+ file = path_openat(-1, &filename, &nd, op, flags);
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;
}
diff --git a/fs/open.c b/fs/open.c
index 81dd92ac10f..59071f55bf7 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -859,6 +859,24 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
}
/**
+ * 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
*
* @filename: path to open
@@ -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 open_flags op;
- int lookup = build_open_flags(flags, mode, &op);
- return do_filp_open(AT_FDCWD, filename, &op, lookup);
+ struct filename name = {.name = filename};
+ return file_open_name(&name, flags, mode);
}
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)) {
fd = get_unused_fd_flags(flags);
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)) {
put_unused_fd(fd);
fd = PTR_ERR(f);