Commit a3806a80 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] path_lookup()

	New helper:
path_lookup(name, flags, nd)
{
	int err = 0;
	if (path_init(name, flags, nd))
		err = path_walk(name, nd);
	return err;
}

Places doing that by hand converted to calling it.

Actually, quite a few of them were doing equivalent of __user_walk()
(getname() and if it was successful - call path_lookup() and putname()).
Converted to calling __user_walk().
parent 2dee55cd
...@@ -343,15 +343,11 @@ int setup_arg_pages(struct linux_binprm *bprm) ...@@ -343,15 +343,11 @@ int setup_arg_pages(struct linux_binprm *bprm)
struct file *open_exec(const char *name) struct file *open_exec(const char *name)
{ {
struct nameidata nd; struct nameidata nd;
struct inode *inode; int err = path_lookup(name, LOOKUP_FOLLOW, &nd);
struct file *file; struct file *file = ERR_PTR(err);
int err = 0;
if (path_init(name, LOOKUP_FOLLOW, &nd))
err = path_walk(name, &nd);
file = ERR_PTR(err);
if (!err) { if (!err) {
inode = nd.dentry->d_inode; struct inode *inode = nd.dentry->d_inode;
file = ERR_PTR(-EACCES); file = ERR_PTR(-EACCES);
if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
S_ISREG(inode->i_mode)) { S_ISREG(inode->i_mode)) {
......
...@@ -360,8 +360,7 @@ static int set_system_mtpt (char *mtpt, struct dentry **old_root) ...@@ -360,8 +360,7 @@ static int set_system_mtpt (char *mtpt, struct dentry **old_root)
struct dentry *dentry; struct dentry *dentry;
int error; int error;
if (path_init(pathname, LOOKUP_PARENT, &nd)) error = path_lookup(pathname, LOOKUP_PARENT, &nd);
error = path_walk(mtpt, &nd);
if (error) { if (error) {
CDEBUG (D_KML, "Yean!!!!::Can't find mtpt::%s\n", mtpt); CDEBUG (D_KML, "Yean!!!!::Can't find mtpt::%s\n", mtpt);
return error; return error;
......
...@@ -32,7 +32,6 @@ extern int presto_init_kml_file(struct presto_file_set *); ...@@ -32,7 +32,6 @@ extern int presto_init_kml_file(struct presto_file_set *);
int presto_walk(const char *name, struct nameidata *nd) int presto_walk(const char *name, struct nameidata *nd)
{ {
int err;
/* we do not follow symlinks to support symlink operations /* we do not follow symlinks to support symlink operations
correctly. The vfs should always hand us resolved dentries correctly. The vfs should always hand us resolved dentries
so we should not be required to use LOOKUP_FOLLOW. At the so we should not be required to use LOOKUP_FOLLOW. At the
...@@ -41,12 +40,7 @@ int presto_walk(const char *name, struct nameidata *nd) ...@@ -41,12 +40,7 @@ int presto_walk(const char *name, struct nameidata *nd)
XXX: This code implies that direct symlinks do not work. SHP XXX: This code implies that direct symlinks do not work. SHP
*/ */
unsigned int flags = 0; unsigned int flags = 0;
return path_lookup(name, flags, nd);
ENTRY;
err = 0;
if (path_init(name, flags, nd))
err = path_walk(name, nd);
return err;
} }
inline struct presto_dentry_data *presto_d2d(struct dentry *dentry) inline struct presto_dentry_data *presto_d2d(struct dentry *dentry)
......
...@@ -525,22 +525,12 @@ int lento_create(const char *name, int mode, struct lento_vfs_context *info) ...@@ -525,22 +525,12 @@ int lento_create(const char *name, int mode, struct lento_vfs_context *info)
{ {
int error; int error;
struct nameidata nd; struct nameidata nd;
char * pathname;
struct dentry *dentry; struct dentry *dentry;
struct presto_file_set *fset; struct presto_file_set *fset;
ENTRY; ENTRY;
pathname = getname(name);
error = PTR_ERR(pathname);
if (IS_ERR(pathname)) {
EXIT;
goto exit;
}
/* this looks up the parent */ /* this looks up the parent */
// if (path_init(pathname, LOOKUP_FOLLOW, &nd)) error = __user_walk(name, LOOKUP_PARENT, &nd);
if (path_init(pathname, LOOKUP_PARENT, &nd))
error = path_walk(pathname, &nd);
if (error) { if (error) {
EXIT; EXIT;
goto exit; goto exit;
...@@ -568,7 +558,6 @@ int lento_create(const char *name, int mode, struct lento_vfs_context *info) ...@@ -568,7 +558,6 @@ int lento_create(const char *name, int mode, struct lento_vfs_context *info)
path_release (&nd); path_release (&nd);
dput(dentry); dput(dentry);
up(&dentry->d_parent->d_inode->i_sem); up(&dentry->d_parent->d_inode->i_sem);
putname(pathname);
exit: exit:
return error; return error;
} }
...@@ -673,57 +662,41 @@ int lento_link(const char * oldname, const char * newname, ...@@ -673,57 +662,41 @@ int lento_link(const char * oldname, const char * newname,
struct lento_vfs_context *info) struct lento_vfs_context *info)
{ {
int error; int error;
char * from;
char * to;
struct presto_file_set *fset; struct presto_file_set *fset;
struct dentry *new_dentry;
from = getname(oldname); struct nameidata nd, old_nd;
if(IS_ERR(from))
return PTR_ERR(from); error = __user_walk(from, 0, &old_nd);
to = getname(newname); if (error)
error = PTR_ERR(to); goto exit;
if (!IS_ERR(to)) { error = __user_walk(newname, LOOKUP_PARENT, &nd);
struct dentry *new_dentry; if (error)
struct nameidata nd, old_nd; goto out;
error = -EXDEV;
error = 0; if (old_nd.mnt != nd.mnt)
if (path_init(from, 0, &old_nd)) goto out;
error = path_walk(from, &old_nd); new_dentry = lookup_create(&nd, 0);
if (error) error = PTR_ERR(new_dentry);
goto exit;
if (path_init(to, LOOKUP_PARENT, &nd)) if (!IS_ERR(new_dentry)) {
error = path_walk(to, &nd); fset = presto_fset(new_dentry);
if (error) error = -EINVAL;
goto out; if ( !fset ) {
error = -EXDEV; printk("No fileset!\n");
if (old_nd.mnt != nd.mnt) EXIT;
goto out; goto out2;
new_dentry = lookup_create(&nd, 0); }
error = PTR_ERR(new_dentry); error = presto_do_link(fset, old_nd.dentry,
nd.dentry,
if (!IS_ERR(new_dentry)) { new_dentry, info);
fset = presto_fset(new_dentry); dput(new_dentry);
error = -EINVAL; }
if ( !fset ) { out2:
printk("No fileset!\n"); up(&nd.dentry->d_inode->i_sem);
EXIT; path_release(&nd);
goto out2; out:
} path_release(&old_nd);
error = presto_do_link(fset, old_nd.dentry, exit:
nd.dentry,
new_dentry, info);
dput(new_dentry);
}
out2:
up(&nd.dentry->d_inode->i_sem);
path_release(&nd);
out:
path_release(&old_nd);
exit:
putname(to);
}
putname(from);
return error; return error;
} }
...@@ -832,19 +805,13 @@ int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir, ...@@ -832,19 +805,13 @@ int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,
int lento_unlink(const char *pathname, struct lento_vfs_context *info) int lento_unlink(const char *pathname, struct lento_vfs_context *info)
{ {
int error = 0; int error = 0;
char * name;
struct dentry *dentry; struct dentry *dentry;
struct nameidata nd; struct nameidata nd;
struct presto_file_set *fset; struct presto_file_set *fset;
ENTRY; ENTRY;
name = getname(pathname); error = __user_walk(pathname, LOOKUP_PARENT, &nd);
if(IS_ERR(name))
return PTR_ERR(name);
if (path_init(name, LOOKUP_PARENT, &nd))
error = path_walk(name, &nd);
if (error) if (error)
goto exit; goto exit;
error = -EISDIR; error = -EISDIR;
...@@ -873,8 +840,6 @@ int lento_unlink(const char *pathname, struct lento_vfs_context *info) ...@@ -873,8 +840,6 @@ int lento_unlink(const char *pathname, struct lento_vfs_context *info)
exit1: exit1:
path_release(&nd); path_release(&nd);
exit: exit:
putname(name);
return error; return error;
slashes: slashes:
...@@ -986,7 +951,6 @@ int lento_symlink(const char *oldname, const char *newname, ...@@ -986,7 +951,6 @@ int lento_symlink(const char *oldname, const char *newname,
{ {
int error; int error;
char *from; char *from;
char *to;
struct dentry *dentry; struct dentry *dentry;
struct presto_file_set *fset; struct presto_file_set *fset;
struct nameidata nd; struct nameidata nd;
...@@ -1000,15 +964,7 @@ int lento_symlink(const char *oldname, const char *newname, ...@@ -1000,15 +964,7 @@ int lento_symlink(const char *oldname, const char *newname,
goto exit; goto exit;
} }
to = getname(newname); error = __user_walk(newname, LOOKUP_PARENT, &nd);
error = PTR_ERR(to);
if (IS_ERR(to)) {
EXIT;
goto exit_from;
}
if (path_init(to, LOOKUP_PARENT, &nd))
error = path_walk(to, &nd);
if (error) { if (error) {
EXIT; EXIT;
goto exit_to; goto exit_to;
...@@ -1031,14 +987,13 @@ int lento_symlink(const char *oldname, const char *newname, ...@@ -1031,14 +987,13 @@ int lento_symlink(const char *oldname, const char *newname,
goto exit_lock; goto exit_lock;
} }
error = presto_do_symlink(fset, nd.dentry, error = presto_do_symlink(fset, nd.dentry,
dentry, oldname, info); dentry, from, info);
path_release(&nd); path_release(&nd);
EXIT; EXIT;
exit_lock: exit_lock:
up(&nd.dentry->d_inode->i_sem); up(&nd.dentry->d_inode->i_sem);
dput(dentry); dput(dentry);
exit_to: exit_to:
putname(to);
exit_from: exit_from:
putname(from); putname(from);
exit: exit:
...@@ -1153,7 +1108,6 @@ int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir, ...@@ -1153,7 +1108,6 @@ int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir,
int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info) int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info)
{ {
int error; int error;
char *pathname;
struct dentry *dentry; struct dentry *dentry;
struct presto_file_set *fset; struct presto_file_set *fset;
struct nameidata nd; struct nameidata nd;
...@@ -1161,15 +1115,7 @@ int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info) ...@@ -1161,15 +1115,7 @@ int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info)
ENTRY; ENTRY;
CDEBUG(D_PIOCTL, "name: %s, mode %o, offset %d, recno %d, flags %x\n", CDEBUG(D_PIOCTL, "name: %s, mode %o, offset %d, recno %d, flags %x\n",
name, mode, info->slot_offset, info->recno, info->flags); name, mode, info->slot_offset, info->recno, info->flags);
pathname = getname(name); error = __user_walk(pathname, LOOKUP_PARENT, &nd);
error = PTR_ERR(pathname);
if (IS_ERR(pathname)) {
EXIT;
return error;
}
if (path_init(pathname, LOOKUP_PARENT, &nd))
error = path_walk(pathname, &nd);
if (error) if (error)
goto out_name; goto out_name;
...@@ -1193,7 +1139,6 @@ int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info) ...@@ -1193,7 +1139,6 @@ int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info)
path_release(&nd); path_release(&nd);
out_name: out_name:
EXIT; EXIT;
putname(pathname);
CDEBUG(D_PIOCTL, "error: %d\n", error); CDEBUG(D_PIOCTL, "error: %d\n", error);
return error; return error;
} }
...@@ -1298,18 +1243,12 @@ int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir, ...@@ -1298,18 +1243,12 @@ int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir,
int lento_rmdir(const char *pathname, struct lento_vfs_context *info) int lento_rmdir(const char *pathname, struct lento_vfs_context *info)
{ {
int error = 0; int error = 0;
char * name;
struct dentry *dentry; struct dentry *dentry;
struct presto_file_set *fset; struct presto_file_set *fset;
struct nameidata nd; struct nameidata nd;
ENTRY; ENTRY;
name = getname(pathname); error = __user_walk(pathname, LOOKUP_PARENT, &nd))
if(IS_ERR(name))
return PTR_ERR(name);
if (path_init(name, LOOKUP_PARENT, &nd))
error = path_walk(name, &nd);
if (error) if (error)
goto exit; goto exit;
...@@ -1342,7 +1281,6 @@ int lento_rmdir(const char *pathname, struct lento_vfs_context *info) ...@@ -1342,7 +1281,6 @@ int lento_rmdir(const char *pathname, struct lento_vfs_context *info)
path_release(&nd); path_release(&nd);
exit: exit:
EXIT; EXIT;
putname(name);
return error; return error;
} }
...@@ -1452,7 +1390,6 @@ int lento_mknod(const char *filename, int mode, dev_t dev, ...@@ -1452,7 +1390,6 @@ int lento_mknod(const char *filename, int mode, dev_t dev,
struct lento_vfs_context *info) struct lento_vfs_context *info)
{ {
int error = 0; int error = 0;
char * tmp;
struct dentry * dentry; struct dentry * dentry;
struct nameidata nd; struct nameidata nd;
struct presto_file_set *fset; struct presto_file_set *fset;
...@@ -1461,12 +1398,8 @@ int lento_mknod(const char *filename, int mode, dev_t dev, ...@@ -1461,12 +1398,8 @@ int lento_mknod(const char *filename, int mode, dev_t dev,
if (S_ISDIR(mode)) if (S_ISDIR(mode))
return -EPERM; return -EPERM;
tmp = getname(filename);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
if (path_init(tmp, LOOKUP_PARENT, &nd)) error = __user_walk(filename, LOOKUP_PARENT, &nd);
error = path_walk(tmp, &nd);
if (error) if (error)
goto out; goto out;
dentry = lookup_create(&nd, 0); dentry = lookup_create(&nd, 0);
...@@ -1499,8 +1432,6 @@ int lento_mknod(const char *filename, int mode, dev_t dev, ...@@ -1499,8 +1432,6 @@ int lento_mknod(const char *filename, int mode, dev_t dev,
up(&nd.dentry->d_inode->i_sem); up(&nd.dentry->d_inode->i_sem);
path_release(&nd); path_release(&nd);
out: out:
putname(tmp);
return error; return error;
} }
...@@ -1746,14 +1677,12 @@ int lento_do_rename(const char *oldname, const char *newname, ...@@ -1746,14 +1677,12 @@ int lento_do_rename(const char *oldname, const char *newname,
ENTRY; ENTRY;
if (path_init(oldname, LOOKUP_PARENT, &oldnd)) error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
error = path_walk(oldname, &oldnd);
if (error) if (error)
goto exit; goto exit;
if (path_init(newname, LOOKUP_PARENT, &newnd)) error = path_lookup(newname, LOOKUP_PARENT, &newnd);
error = path_walk(newname, &newnd);
if (error) if (error)
goto exit1; goto exit1;
......
...@@ -681,17 +681,16 @@ void set_fs_altroot(void) ...@@ -681,17 +681,16 @@ void set_fs_altroot(void)
struct nameidata nd; struct nameidata nd;
struct vfsmount *mnt = NULL, *oldmnt; struct vfsmount *mnt = NULL, *oldmnt;
struct dentry *dentry = NULL, *olddentry; struct dentry *dentry = NULL, *olddentry;
if (emul) { int err;
read_lock(&current->fs->lock);
nd.mnt = mntget(current->fs->rootmnt); if (!emul)
nd.dentry = dget(current->fs->root); goto set_it;
read_unlock(&current->fs->lock); err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
nd.flags = LOOKUP_FOLLOW|LOOKUP_DIRECTORY; if (err) {
if (path_walk(emul,&nd) == 0) { mnt = nd.mnt;
mnt = nd.mnt; dentry = nd.dentry;
dentry = nd.dentry;
}
} }
set_it:
write_lock(&current->fs->lock); write_lock(&current->fs->lock);
oldmnt = current->fs->altrootmnt; oldmnt = current->fs->altrootmnt;
olddentry = current->fs->altroot; olddentry = current->fs->altroot;
...@@ -820,15 +819,11 @@ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) ...@@ -820,15 +819,11 @@ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
*/ */
int __user_walk(const char *name, unsigned flags, struct nameidata *nd) int __user_walk(const char *name, unsigned flags, struct nameidata *nd)
{ {
char *tmp; char *tmp = getname(name);
int err; int err = PTR_ERR(tmp);
tmp = getname(name);
err = PTR_ERR(tmp);
if (!IS_ERR(tmp)) { if (!IS_ERR(tmp)) {
err = 0; err = path_lookup(tmp, flags, nd);
if (path_init(tmp, flags, nd))
err = path_walk(tmp, nd);
putname(tmp); putname(tmp);
} }
return err; return err;
...@@ -1019,8 +1014,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) ...@@ -1019,8 +1014,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
* The simplest case - just a plain lookup. * The simplest case - just a plain lookup.
*/ */
if (!(flag & O_CREAT)) { if (!(flag & O_CREAT)) {
if (path_init(pathname, lookup_flags(flag), nd)) error = path_lookup(pathname, lookup_flags(flag), nd);
error = path_walk(pathname, nd);
if (error) if (error)
return error; return error;
dentry = nd->dentry; dentry = nd->dentry;
...@@ -1030,8 +1024,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) ...@@ -1030,8 +1024,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
/* /*
* Create - we need to know the parent. * Create - we need to know the parent.
*/ */
if (path_init(pathname, LOOKUP_PARENT, nd)) error = path_lookup(pathname, LOOKUP_PARENT, nd);
error = path_walk(pathname, nd);
if (error) if (error)
return error; return error;
...@@ -1265,19 +1258,14 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ...@@ -1265,19 +1258,14 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev) asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev)
{ {
int error = 0;
char * tmp;
struct dentry * dentry; struct dentry * dentry;
struct nameidata nd; struct nameidata nd;
int error;
if (S_ISDIR(mode)) if (S_ISDIR(mode))
return -EPERM; return -EPERM;
tmp = getname(filename);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
if (path_init(tmp, LOOKUP_PARENT, &nd)) error = __user_walk(filename, LOOKUP_PARENT, &nd);
error = path_walk(tmp, &nd);
if (error) if (error)
goto out; goto out;
dentry = lookup_create(&nd, 0); dentry = lookup_create(&nd, 0);
...@@ -1303,8 +1291,6 @@ asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev) ...@@ -1303,8 +1291,6 @@ asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev)
up(&nd.dentry->d_inode->i_sem); up(&nd.dentry->d_inode->i_sem);
path_release(&nd); path_release(&nd);
out: out:
putname(tmp);
return error; return error;
} }
...@@ -1328,32 +1314,23 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1328,32 +1314,23 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
asmlinkage long sys_mkdir(const char * pathname, int mode) asmlinkage long sys_mkdir(const char * pathname, int mode)
{ {
int error = 0; struct nameidata nd;
char * tmp; struct dentry *dentry;
int error;
tmp = getname(pathname);
error = PTR_ERR(tmp);
if (!IS_ERR(tmp)) {
struct dentry *dentry;
struct nameidata nd;
if (path_init(tmp, LOOKUP_PARENT, &nd)) error = __user_walk(pathname, LOOKUP_PARENT, &nd);
error = path_walk(tmp, &nd); if (error)
if (error) goto out;
goto out; dentry = lookup_create(&nd, 1);
dentry = lookup_create(&nd, 1); error = PTR_ERR(dentry);
error = PTR_ERR(dentry); if (!IS_ERR(dentry)) {
if (!IS_ERR(dentry)) { error = vfs_mkdir(nd.dentry->d_inode, dentry,
error = vfs_mkdir(nd.dentry->d_inode, dentry, mode & ~current->fs->umask);
mode & ~current->fs->umask); dput(dentry);
dput(dentry);
}
up(&nd.dentry->d_inode->i_sem);
path_release(&nd);
out:
putname(tmp);
} }
up(&nd.dentry->d_inode->i_sem);
path_release(&nd);
out:
return error; return error;
} }
...@@ -1420,17 +1397,11 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -1420,17 +1397,11 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
asmlinkage long sys_rmdir(const char * pathname) asmlinkage long sys_rmdir(const char * pathname)
{ {
int error = 0;
char * name;
struct dentry *dentry; struct dentry *dentry;
struct nameidata nd; struct nameidata nd;
int error;
name = getname(pathname); error = __user_walk(pathname, LOOKUP_PARENT, &nd);
if(IS_ERR(name))
return PTR_ERR(name);
if (path_init(name, LOOKUP_PARENT, &nd))
error = path_walk(name, &nd);
if (error) if (error)
goto exit; goto exit;
...@@ -1456,7 +1427,6 @@ asmlinkage long sys_rmdir(const char * pathname) ...@@ -1456,7 +1427,6 @@ asmlinkage long sys_rmdir(const char * pathname)
exit1: exit1:
path_release(&nd); path_release(&nd);
exit: exit:
putname(name);
return error; return error;
} }
...@@ -1492,17 +1462,11 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -1492,17 +1462,11 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
asmlinkage long sys_unlink(const char * pathname) asmlinkage long sys_unlink(const char * pathname)
{ {
int error = 0;
char * name;
struct dentry *dentry; struct dentry *dentry;
struct nameidata nd; struct nameidata nd;
int error;
name = getname(pathname); error = __user_walk(pathname, LOOKUP_PARENT, &nd);
if(IS_ERR(name))
return PTR_ERR(name);
if (path_init(name, LOOKUP_PARENT, &nd))
error = path_walk(name, &nd);
if (error) if (error)
goto exit; goto exit;
error = -EISDIR; error = -EISDIR;
...@@ -1523,8 +1487,6 @@ asmlinkage long sys_unlink(const char * pathname) ...@@ -1523,8 +1487,6 @@ asmlinkage long sys_unlink(const char * pathname)
exit1: exit1:
path_release(&nd); path_release(&nd);
exit: exit:
putname(name);
return error; return error;
slashes: slashes:
...@@ -1552,34 +1514,26 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) ...@@ -1552,34 +1514,26 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
asmlinkage long sys_symlink(const char * oldname, const char * newname) asmlinkage long sys_symlink(const char * oldname, const char * newname)
{ {
int error = 0; struct dentry *dentry;
char * from; char *from = getname(oldname);
char * to; struct nameidata nd;
int error;
from = getname(oldname); if (IS_ERR(from))
if(IS_ERR(from))
return PTR_ERR(from); return PTR_ERR(from);
to = getname(newname);
error = PTR_ERR(to);
if (!IS_ERR(to)) {
struct dentry *dentry;
struct nameidata nd;
if (path_init(to, LOOKUP_PARENT, &nd)) error = __user_walk(newname, LOOKUP_PARENT, &nd);
error = path_walk(to, &nd); if (error)
if (error) goto out;
goto out; dentry = lookup_create(&nd, 0);
dentry = lookup_create(&nd, 0); error = PTR_ERR(dentry);
error = PTR_ERR(dentry); if (!IS_ERR(dentry)) {
if (!IS_ERR(dentry)) { error = vfs_symlink(nd.dentry->d_inode, dentry, from);
error = vfs_symlink(nd.dentry->d_inode, dentry, from); dput(dentry);
dput(dentry);
}
up(&nd.dentry->d_inode->i_sem);
path_release(&nd);
out:
putname(to);
} }
up(&nd.dentry->d_inode->i_sem);
path_release(&nd);
out:
putname(from); putname(from);
return error; return error;
} }
...@@ -1629,47 +1583,31 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de ...@@ -1629,47 +1583,31 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
*/ */
asmlinkage long sys_link(const char * oldname, const char * newname) asmlinkage long sys_link(const char * oldname, const char * newname)
{ {
struct dentry *new_dentry;
struct nameidata nd, old_nd;
int error; int error;
char * from;
char * to;
from = getname(oldname); error = __user_walk(oldname, 0, &old_nd);
if(IS_ERR(from)) if (error)
return PTR_ERR(from); goto exit;
to = getname(newname); error = __user_walk(newname, LOOKUP_PARENT, &nd);
error = PTR_ERR(to); if (error)
if (!IS_ERR(to)) { goto out;
struct dentry *new_dentry; error = -EXDEV;
struct nameidata nd, old_nd; if (old_nd.mnt != nd.mnt)
goto out_release;
error = 0; new_dentry = lookup_create(&nd, 0);
if (path_init(from, 0, &old_nd)) error = PTR_ERR(new_dentry);
error = path_walk(from, &old_nd); if (!IS_ERR(new_dentry)) {
if (error) error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
goto exit; dput(new_dentry);
if (path_init(to, LOOKUP_PARENT, &nd)) }
error = path_walk(to, &nd); up(&nd.dentry->d_inode->i_sem);
if (error)
goto out;
error = -EXDEV;
if (old_nd.mnt != nd.mnt)
goto out_release;
new_dentry = lookup_create(&nd, 0);
error = PTR_ERR(new_dentry);
if (!IS_ERR(new_dentry)) {
error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
dput(new_dentry);
}
up(&nd.dentry->d_inode->i_sem);
out_release: out_release:
path_release(&nd); path_release(&nd);
out: out:
path_release(&old_nd); path_release(&old_nd);
exit: exit:
putname(to);
}
putname(from);
return error; return error;
} }
...@@ -1817,7 +1755,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1817,7 +1755,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
return error; return error;
} }
static inline int do_rename(const char * oldname, const char * newname) asmlinkage long sys_rename(const char * oldname, const char * newname)
{ {
int error = 0; int error = 0;
struct dentry * old_dir, * new_dir; struct dentry * old_dir, * new_dir;
...@@ -1825,14 +1763,11 @@ static inline int do_rename(const char * oldname, const char * newname) ...@@ -1825,14 +1763,11 @@ static inline int do_rename(const char * oldname, const char * newname)
struct dentry * trap; struct dentry * trap;
struct nameidata oldnd, newnd; struct nameidata oldnd, newnd;
if (path_init(oldname, LOOKUP_PARENT, &oldnd)) error = __user_walk(oldname, LOOKUP_PARENT, &oldnd);
error = path_walk(oldname, &oldnd);
if (error) if (error)
goto exit; goto exit;
if (path_init(newname, LOOKUP_PARENT, &newnd)) error = __user_walk(newname, LOOKUP_PARENT, &newnd);
error = path_walk(newname, &newnd);
if (error) if (error)
goto exit1; goto exit1;
...@@ -1896,25 +1831,6 @@ static inline int do_rename(const char * oldname, const char * newname) ...@@ -1896,25 +1831,6 @@ static inline int do_rename(const char * oldname, const char * newname)
return error; return error;
} }
asmlinkage long sys_rename(const char * oldname, const char * newname)
{
int error;
char * from;
char * to;
from = getname(oldname);
if(IS_ERR(from))
return PTR_ERR(from);
to = getname(newname);
error = PTR_ERR(to);
if (!IS_ERR(to)) {
error = do_rename(from,to);
putname(to);
}
putname(from);
return error;
}
int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link) int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link)
{ {
int len; int len;
......
...@@ -360,17 +360,9 @@ static int do_umount(struct vfsmount *mnt, int flags) ...@@ -360,17 +360,9 @@ static int do_umount(struct vfsmount *mnt, int flags)
asmlinkage long sys_umount(char * name, int flags) asmlinkage long sys_umount(char * name, int flags)
{ {
struct nameidata nd; struct nameidata nd;
char *kname;
int retval; int retval;
kname = getname(name); retval = __user_walk(name, LOOKUP_FOLLOW, &nd);
retval = PTR_ERR(kname);
if (IS_ERR(kname))
goto out;
retval = 0;
if (path_init(kname, LOOKUP_FOLLOW, &nd))
retval = path_walk(kname, &nd);
putname(kname);
if (retval) if (retval)
goto out; goto out;
retval = -EINVAL; retval = -EINVAL;
...@@ -497,8 +489,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse) ...@@ -497,8 +489,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
return err; return err;
if (!old_name || !*old_name) if (!old_name || !*old_name)
return -EINVAL; return -EINVAL;
if (path_init(old_name, LOOKUP_FOLLOW, &old_nd)) err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
err = path_walk(old_name, &old_nd);
if (err) if (err)
return err; return err;
...@@ -564,8 +555,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name) ...@@ -564,8 +555,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
return -EPERM; return -EPERM;
if (!old_name || !*old_name) if (!old_name || !*old_name)
return -EINVAL; return -EINVAL;
if (path_init(old_name, LOOKUP_FOLLOW, &old_nd)) err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
err = path_walk(old_name, &old_nd);
if (err) if (err)
return err; return err;
...@@ -731,8 +721,7 @@ long do_mount(char * dev_name, char * dir_name, char *type_page, ...@@ -731,8 +721,7 @@ long do_mount(char * dev_name, char * dir_name, char *type_page,
flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV); flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
/* ... and get the mountpoint */ /* ... and get the mountpoint */
if (path_init(dir_name, LOOKUP_FOLLOW, &nd)) retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
retval = path_walk(dir_name, &nd);
if (retval) if (retval)
return retval; return retval;
...@@ -911,7 +900,6 @@ asmlinkage long sys_pivot_root(const char *new_root, const char *put_old) ...@@ -911,7 +900,6 @@ asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
{ {
struct vfsmount *tmp; struct vfsmount *tmp;
struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
char *name;
int error; int error;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
...@@ -919,28 +907,14 @@ asmlinkage long sys_pivot_root(const char *new_root, const char *put_old) ...@@ -919,28 +907,14 @@ asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
lock_kernel(); lock_kernel();
name = getname(new_root); error = __user_walk(new_root, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
error = PTR_ERR(name);
if (IS_ERR(name))
goto out0;
error = 0;
if (path_init(name, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
error = path_walk(name, &new_nd);
putname(name);
if (error) if (error)
goto out0; goto out0;
error = -EINVAL; error = -EINVAL;
if (!check_mnt(new_nd.mnt)) if (!check_mnt(new_nd.mnt))
goto out1; goto out1;
name = getname(put_old); error = __user_walk(put_old, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
error = PTR_ERR(name);
if (IS_ERR(name))
goto out1;
error = 0;
if (path_init(name, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
error = path_walk(name, &old_nd);
putname(name);
if (error) if (error)
goto out1; goto out1;
......
...@@ -238,9 +238,7 @@ exp_export(struct nfsctl_export *nxp) ...@@ -238,9 +238,7 @@ exp_export(struct nfsctl_export *nxp)
} }
/* Look up the dentry */ /* Look up the dentry */
err = 0; err = path_lookup(nxp->ex_path, 0, &nd);
if (path_init(nxp->ex_path, 0, &nd))
err = path_walk(nxp->ex_path, &nd);
if (err) if (err)
goto out_unlock; goto out_unlock;
...@@ -408,8 +406,7 @@ exp_rootfh(struct svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) ...@@ -408,8 +406,7 @@ exp_rootfh(struct svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
err = -EPERM; err = -EPERM;
/* NB: we probably ought to check that it's NUL-terminated */ /* NB: we probably ought to check that it's NUL-terminated */
if (path_init(path, 0, &nd) && if (path_lookup(path, 0, &nd)) {
path_walk(path, &nd)) {
printk("nfsd: exp_rootfh path not found %s", path); printk("nfsd: exp_rootfh path not found %s", path);
return err; return err;
} }
......
...@@ -358,19 +358,10 @@ asmlinkage long sys_access(const char * filename, int mode) ...@@ -358,19 +358,10 @@ asmlinkage long sys_access(const char * filename, int mode)
asmlinkage long sys_chdir(const char * filename) asmlinkage long sys_chdir(const char * filename)
{ {
int error;
struct nameidata nd; struct nameidata nd;
char *name; int error;
name = getname(filename);
error = PTR_ERR(name);
if (IS_ERR(name))
goto out;
error = 0; error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
if (path_init(name,LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
error = path_walk(name, &nd);
putname(name);
if (error) if (error)
goto out; goto out;
...@@ -418,18 +409,10 @@ asmlinkage long sys_fchdir(unsigned int fd) ...@@ -418,18 +409,10 @@ asmlinkage long sys_fchdir(unsigned int fd)
asmlinkage long sys_chroot(const char * filename) asmlinkage long sys_chroot(const char * filename)
{ {
int error;
struct nameidata nd; struct nameidata nd;
char *name; int error;
name = getname(filename);
error = PTR_ERR(name);
if (IS_ERR(name))
goto out;
path_init(name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
error = path_walk(name, &nd);
putname(name);
if (error) if (error)
goto out; goto out;
......
...@@ -700,8 +700,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, ...@@ -700,8 +700,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
/* What device it is? */ /* What device it is? */
if (!dev_name || !*dev_name) if (!dev_name || !*dev_name)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if (path_init(dev_name, LOOKUP_FOLLOW, &nd)) error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
error = path_walk(dev_name, &nd);
if (error) if (error)
return ERR_PTR(error); return ERR_PTR(error);
inode = nd.dentry->d_inode; inode = nd.dentry->d_inode;
......
...@@ -1305,6 +1305,13 @@ extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); ...@@ -1305,6 +1305,13 @@ extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
extern int FASTCALL(path_walk(const char *, struct nameidata *)); extern int FASTCALL(path_walk(const char *, struct nameidata *));
extern int FASTCALL(link_path_walk(const char *, struct nameidata *)); extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
static inline int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
{
int error = 0;
if (path_init(path, flags, nd))
error = path_walk(path, nd);
return error;
}
extern void path_release(struct nameidata *); extern void path_release(struct nameidata *);
extern int follow_down(struct vfsmount **, struct dentry **); extern int follow_down(struct vfsmount **, struct dentry **);
extern int follow_up(struct vfsmount **, struct dentry **); extern int follow_up(struct vfsmount **, struct dentry **);
......
...@@ -603,8 +603,7 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len, ...@@ -603,8 +603,7 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
int err = 0; int err = 0;
if (sunname->sun_path[0]) { if (sunname->sun_path[0]) {
if (path_init(sunname->sun_path, LOOKUP_FOLLOW, &nd)) err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
err = path_walk(sunname->sun_path, &nd);
if (err) if (err)
goto fail; goto fail;
err = permission(nd.dentry->d_inode,MAY_WRITE); err = permission(nd.dentry->d_inode,MAY_WRITE);
...@@ -690,8 +689,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ...@@ -690,8 +689,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
* Get the parent directory, calculate the hash for last * Get the parent directory, calculate the hash for last
* component. * component.
*/ */
if (path_init(sunaddr->sun_path, LOOKUP_PARENT, &nd)) err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd);
err = path_walk(sunaddr->sun_path, &nd);
if (err) if (err)
goto out_mknod_parent; goto out_mknod_parent;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment