|
@@ -2042,32 +2042,47 @@ static int filename_lookup(int dfd, struct filename *name,
|
|
static int do_path_lookup(int dfd, const char *name,
|
|
static int do_path_lookup(int dfd, const char *name,
|
|
unsigned int flags, struct nameidata *nd)
|
|
unsigned int flags, struct nameidata *nd)
|
|
{
|
|
{
|
|
- struct filename filename = { .name = name };
|
|
|
|
|
|
+ struct filename *filename = getname_kernel(name);
|
|
|
|
+ int retval = PTR_ERR(filename);
|
|
|
|
|
|
- return filename_lookup(dfd, &filename, flags, nd);
|
|
|
|
|
|
+ if (!IS_ERR(filename)) {
|
|
|
|
+ retval = filename_lookup(dfd, filename, flags, nd);
|
|
|
|
+ putname(filename);
|
|
|
|
+ }
|
|
|
|
+ return retval;
|
|
}
|
|
}
|
|
|
|
|
|
/* does lookup, returns the object with parent locked */
|
|
/* does lookup, returns the object with parent locked */
|
|
struct dentry *kern_path_locked(const char *name, struct path *path)
|
|
struct dentry *kern_path_locked(const char *name, struct path *path)
|
|
{
|
|
{
|
|
|
|
+ struct filename *filename = getname_kernel(name);
|
|
struct nameidata nd;
|
|
struct nameidata nd;
|
|
struct dentry *d;
|
|
struct dentry *d;
|
|
- struct filename filename = {.name = name};
|
|
|
|
- int err = filename_lookup(AT_FDCWD, &filename, LOOKUP_PARENT, &nd);
|
|
|
|
- if (err)
|
|
|
|
- return ERR_PTR(err);
|
|
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ if (IS_ERR(filename))
|
|
|
|
+ return ERR_CAST(filename);
|
|
|
|
+
|
|
|
|
+ err = filename_lookup(AT_FDCWD, filename, LOOKUP_PARENT, &nd);
|
|
|
|
+ if (err) {
|
|
|
|
+ d = ERR_PTR(err);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
if (nd.last_type != LAST_NORM) {
|
|
if (nd.last_type != LAST_NORM) {
|
|
path_put(&nd.path);
|
|
path_put(&nd.path);
|
|
- return ERR_PTR(-EINVAL);
|
|
|
|
|
|
+ d = ERR_PTR(-EINVAL);
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
|
|
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
|
|
d = __lookup_hash(&nd.last, nd.path.dentry, 0);
|
|
d = __lookup_hash(&nd.last, nd.path.dentry, 0);
|
|
if (IS_ERR(d)) {
|
|
if (IS_ERR(d)) {
|
|
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
|
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
|
path_put(&nd.path);
|
|
path_put(&nd.path);
|
|
- return d;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
*path = nd.path;
|
|
*path = nd.path;
|
|
|
|
+out:
|
|
|
|
+ putname(filename);
|
|
return d;
|
|
return d;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2399,8 +2414,14 @@ int
|
|
kern_path_mountpoint(int dfd, const char *name, struct path *path,
|
|
kern_path_mountpoint(int dfd, const char *name, struct path *path,
|
|
unsigned int flags)
|
|
unsigned int flags)
|
|
{
|
|
{
|
|
- struct filename s = {.name = name};
|
|
|
|
- return filename_mountpoint(dfd, &s, path, flags);
|
|
|
|
|
|
+ struct filename *s = getname_kernel(name);
|
|
|
|
+ int retval = PTR_ERR(s);
|
|
|
|
+
|
|
|
|
+ if (!IS_ERR(s)) {
|
|
|
|
+ retval = filename_mountpoint(dfd, s, path, flags);
|
|
|
|
+ putname(s);
|
|
|
|
+ }
|
|
|
|
+ return retval;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(kern_path_mountpoint);
|
|
EXPORT_SYMBOL(kern_path_mountpoint);
|
|
|
|
|
|
@@ -3280,7 +3301,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 };
|
|
|
|
|
|
+ struct filename *filename;
|
|
int flags = op->lookup_flags | LOOKUP_ROOT;
|
|
int flags = op->lookup_flags | LOOKUP_ROOT;
|
|
|
|
|
|
nd.root.mnt = mnt;
|
|
nd.root.mnt = mnt;
|
|
@@ -3289,11 +3310,16 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
|
|
if (d_is_symlink(dentry) && op->intent & LOOKUP_OPEN)
|
|
if (d_is_symlink(dentry) && op->intent & LOOKUP_OPEN)
|
|
return ERR_PTR(-ELOOP);
|
|
return ERR_PTR(-ELOOP);
|
|
|
|
|
|
- file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU);
|
|
|
|
|
|
+ filename = getname_kernel(name);
|
|
|
|
+ if (unlikely(IS_ERR(filename)))
|
|
|
|
+ return ERR_CAST(filename);
|
|
|
|
+
|
|
|
|
+ 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, &filename, &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, &filename, &nd, op, flags | LOOKUP_REVAL);
|
|
|
|
|
|
+ file = path_openat(-1, filename, &nd, op, flags | LOOKUP_REVAL);
|
|
|
|
+ putname(filename);
|
|
return file;
|
|
return file;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3370,8 +3396,14 @@ out:
|
|
struct dentry *kern_path_create(int dfd, const char *pathname,
|
|
struct dentry *kern_path_create(int dfd, const char *pathname,
|
|
struct path *path, unsigned int lookup_flags)
|
|
struct path *path, unsigned int lookup_flags)
|
|
{
|
|
{
|
|
- struct filename filename = {.name = pathname};
|
|
|
|
- return filename_create(dfd, &filename, path, lookup_flags);
|
|
|
|
|
|
+ struct filename *filename = getname_kernel(pathname);
|
|
|
|
+ struct dentry *res;
|
|
|
|
+
|
|
|
|
+ if (IS_ERR(filename))
|
|
|
|
+ return ERR_CAST(filename);
|
|
|
|
+ res = filename_create(dfd, filename, path, lookup_flags);
|
|
|
|
+ putname(filename);
|
|
|
|
+ return res;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(kern_path_create);
|
|
EXPORT_SYMBOL(kern_path_create);
|
|
|
|
|