* Use struct path in fs_struct.
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Signed-off-by: Jan Blunck <jblunck@suse.de>
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
char *buf, int buflen)
{
char *res;
- struct vfsmount *rootmnt;
- struct dentry *root;
+ struct path root;
/*
* We have various synthetic filesystems that never get mounted. On
return dentry->d_op->d_dname(dentry, buf, buflen);
read_lock(¤t->fs->lock);
- rootmnt = mntget(current->fs->rootmnt);
- root = dget(current->fs->root);
+ root = current->fs->root;
+ path_get(¤t->fs->root);
read_unlock(¤t->fs->lock);
spin_lock(&dcache_lock);
- res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
+ res = __d_path(dentry, vfsmnt, root.dentry, root.mnt, buf, buflen);
spin_unlock(&dcache_lock);
- dput(root);
- mntput(rootmnt);
+ path_put(&root);
return res;
}
asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
{
int error;
- struct vfsmount *pwdmnt, *rootmnt;
- struct dentry *pwd, *root;
+ struct path pwd, root;
char *page = (char *) __get_free_page(GFP_USER);
if (!page)
return -ENOMEM;
read_lock(¤t->fs->lock);
- pwdmnt = mntget(current->fs->pwdmnt);
- pwd = dget(current->fs->pwd);
- rootmnt = mntget(current->fs->rootmnt);
- root = dget(current->fs->root);
+ pwd = current->fs->pwd;
+ path_get(¤t->fs->pwd);
+ root = current->fs->root;
+ path_get(¤t->fs->root);
read_unlock(¤t->fs->lock);
error = -ENOENT;
/* Has the current directory has been unlinked? */
spin_lock(&dcache_lock);
- if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
+ if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
unsigned long len;
char * cwd;
- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
+ cwd = __d_path(pwd.dentry, pwd.mnt, root.dentry, root.mnt,
+ page, PAGE_SIZE);
spin_unlock(&dcache_lock);
error = PTR_ERR(cwd);
spin_unlock(&dcache_lock);
out:
- dput(pwd);
- mntput(pwdmnt);
- dput(root);
- mntput(rootmnt);
+ path_put(&pwd);
+ path_put(&root);
free_page((unsigned long) page);
return error;
}
struct fs_struct *fs = current->fs;
read_lock(&fs->lock);
- if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
- nd->path.mnt = mntget(fs->altrootmnt);
- nd->path.dentry = dget(fs->altroot);
+ if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
+ nd->path = fs->altroot;
+ path_get(&fs->altroot);
read_unlock(&fs->lock);
if (__emul_lookup_dentry(name,nd))
return 0;
read_lock(&fs->lock);
}
- nd->path.mnt = mntget(fs->rootmnt);
- nd->path.dentry = dget(fs->root);
+ nd->path = fs->root;
+ path_get(&fs->root);
read_unlock(&fs->lock);
return 1;
}
struct dentry *old = nd->path.dentry;
read_lock(&fs->lock);
- if (nd->path.dentry == fs->root &&
- nd->path.mnt == fs->rootmnt) {
+ if (nd->path.dentry == fs->root.dentry &&
+ nd->path.mnt == fs->root.mnt) {
read_unlock(&fs->lock);
break;
}
*/
nd->last_type = LAST_ROOT;
read_lock(&fs->lock);
- nd->path.mnt = mntget(fs->rootmnt);
- nd->path.dentry = dget(fs->root);
+ nd->path = fs->root;
+ path_get(&fs->root);
read_unlock(&fs->lock);
if (path_walk(name, nd) == 0) {
if (nd->path.dentry->d_inode) {
{
char *emul = __emul_prefix();
struct nameidata nd;
- struct vfsmount *mnt = NULL, *oldmnt;
- struct dentry *dentry = NULL, *olddentry;
+ struct path path = {}, old_path;
int err;
struct fs_struct *fs = current->fs;
if (!emul)
goto set_it;
err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
- if (!err) {
- mnt = nd.path.mnt;
- dentry = nd.path.dentry;
- }
+ if (!err)
+ path = nd.path;
set_it:
write_lock(&fs->lock);
- oldmnt = fs->altrootmnt;
- olddentry = fs->altroot;
- fs->altrootmnt = mnt;
- fs->altroot = dentry;
+ old_path = fs->altroot;
+ fs->altroot = path;
write_unlock(&fs->lock);
- if (olddentry) {
- dput(olddentry);
- mntput(oldmnt);
- }
+ if (old_path.dentry)
+ path_put(&old_path);
}
/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
if (*name=='/') {
read_lock(&fs->lock);
- if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
- nd->path.mnt = mntget(fs->altrootmnt);
- nd->path.dentry = dget(fs->altroot);
+ if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
+ nd->path = fs->altroot;
+ path_get(&fs->altroot);
read_unlock(&fs->lock);
if (__emul_lookup_dentry(name,nd))
goto out; /* found in altroot */
read_lock(&fs->lock);
}
- nd->path.mnt = mntget(fs->rootmnt);
- nd->path.dentry = dget(fs->root);
+ nd->path = fs->root;
+ path_get(&fs->root);
read_unlock(&fs->lock);
} else if (dfd == AT_FDCWD) {
read_lock(&fs->lock);
- nd->path.mnt = mntget(fs->pwdmnt);
- nd->path.dentry = dget(fs->pwd);
+ nd->path = fs->pwd;
+ path_get(&fs->pwd);
read_unlock(&fs->lock);
} else {
struct dentry *dentry;
* (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
*/
if (flags & MNT_EXPIRE) {
- if (mnt == current->fs->rootmnt ||
+ if (mnt == current->fs->root.mnt ||
flags & (MNT_FORCE | MNT_DETACH))
return -EINVAL;
* /reboot - static binary that would close all descriptors and
* call reboot(9). Then init(8) could umount root and exec /reboot.
*/
- if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
+ if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
/*
* Special case for "unmounting" root ...
* we just try to remount it readonly.
while (p) {
q->mnt_ns = new_ns;
if (fs) {
- if (p == fs->rootmnt) {
+ if (p == fs->root.mnt) {
rootmnt = p;
- fs->rootmnt = mntget(q);
+ fs->root.mnt = mntget(q);
}
- if (p == fs->pwdmnt) {
+ if (p == fs->pwd.mnt) {
pwdmnt = p;
- fs->pwdmnt = mntget(q);
+ fs->pwd.mnt = mntget(q);
}
- if (p == fs->altrootmnt) {
+ if (p == fs->altroot.mnt) {
altrootmnt = p;
- fs->altrootmnt = mntget(q);
+ fs->altroot.mnt = mntget(q);
}
}
p = next_mnt(p, mnt_ns->root);
void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
struct dentry *dentry)
{
- struct dentry *old_root;
- struct vfsmount *old_rootmnt;
+ struct path old_root;
+
write_lock(&fs->lock);
old_root = fs->root;
- old_rootmnt = fs->rootmnt;
- fs->rootmnt = mntget(mnt);
- fs->root = dget(dentry);
+ fs->root.mnt = mntget(mnt);
+ fs->root.dentry = dget(dentry);
write_unlock(&fs->lock);
- if (old_root) {
- dput(old_root);
- mntput(old_rootmnt);
- }
+ if (old_root.dentry)
+ path_put(&old_root);
}
/*
void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
struct dentry *dentry)
{
- struct dentry *old_pwd;
- struct vfsmount *old_pwdmnt;
+ struct path old_pwd;
write_lock(&fs->lock);
old_pwd = fs->pwd;
- old_pwdmnt = fs->pwdmnt;
- fs->pwdmnt = mntget(mnt);
- fs->pwd = dget(dentry);
+ fs->pwd.mnt = mntget(mnt);
+ fs->pwd.dentry = dget(dentry);
write_unlock(&fs->lock);
- if (old_pwd) {
- dput(old_pwd);
- mntput(old_pwdmnt);
- }
+ if (old_pwd.dentry)
+ path_put(&old_pwd);
}
static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
if (fs) {
atomic_inc(&fs->count);
task_unlock(p);
- if (fs->root == old_nd->path.dentry
- && fs->rootmnt == old_nd->path.mnt)
+ if (fs->root.dentry == old_nd->path.dentry
+ && fs->root.mnt == old_nd->path.mnt)
set_fs_root(fs, new_nd->path.mnt,
new_nd->path.dentry);
- if (fs->pwd == old_nd->path.dentry
- && fs->pwdmnt == old_nd->path.mnt)
+ if (fs->pwd.dentry == old_nd->path.dentry
+ && fs->pwd.mnt == old_nd->path.mnt)
set_fs_pwd(fs, new_nd->path.mnt,
new_nd->path.dentry);
put_fs_struct(fs);
}
read_lock(¤t->fs->lock);
- user_nd.path.mnt = mntget(current->fs->rootmnt);
- user_nd.path.dentry = dget(current->fs->root);
+ user_nd.path = current->fs->root;
+ path_get(¤t->fs->root);
read_unlock(¤t->fs->lock);
down_write(&namespace_sem);
mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);
}
if (fs) {
read_lock(&fs->lock);
- *mnt = mntget(fs->pwdmnt);
- *dentry = dget(fs->pwd);
+ *mnt = mntget(fs->pwd.mnt);
+ *dentry = dget(fs->pwd.dentry);
read_unlock(&fs->lock);
result = 0;
put_fs_struct(fs);
}
if (fs) {
read_lock(&fs->lock);
- *mnt = mntget(fs->rootmnt);
- *dentry = dget(fs->root);
+ *mnt = mntget(fs->root.mnt);
+ *dentry = dget(fs->root.dentry);
read_unlock(&fs->lock);
result = 0;
put_fs_struct(fs);
#ifndef _LINUX_FS_STRUCT_H
#define _LINUX_FS_STRUCT_H
-struct dentry;
-struct vfsmount;
+#include <linux/path.h>
struct fs_struct {
atomic_t count;
rwlock_t lock;
int umask;
- struct dentry * root, * pwd, * altroot;
- struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
+ struct path root, pwd, altroot;
};
#define INIT_FS { \
return err;
sys_chdir("/root");
- ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+ ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
printk("VFS: Mounted root (%s filesystem)%s.\n",
- current->fs->pwdmnt->mnt_sb->s_type->name,
- current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ?
+ current->fs->pwd.mnt->mnt_sb->s_type->name,
+ current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ?
" readonly" : "");
return 0;
}
++context->name_count;
if (!context->pwd) {
read_lock(¤t->fs->lock);
- context->pwd = dget(current->fs->pwd);
- context->pwdmnt = mntget(current->fs->pwdmnt);
+ context->pwd = dget(current->fs->pwd.dentry);
+ context->pwdmnt = mntget(current->fs->pwd.mnt);
read_unlock(¤t->fs->lock);
}
{
/* No need to hold fs->lock if we are killing it */
if (atomic_dec_and_test(&fs->count)) {
- dput(fs->root);
- mntput(fs->rootmnt);
- dput(fs->pwd);
- mntput(fs->pwdmnt);
- if (fs->altroot) {
- dput(fs->altroot);
- mntput(fs->altrootmnt);
- }
+ path_put(&fs->root);
+ path_put(&fs->pwd);
+ if (fs->altroot.dentry)
+ path_put(&fs->altroot);
kmem_cache_free(fs_cachep, fs);
}
}
rwlock_init(&fs->lock);
fs->umask = old->umask;
read_lock(&old->lock);
- fs->rootmnt = mntget(old->rootmnt);
- fs->root = dget(old->root);
- fs->pwdmnt = mntget(old->pwdmnt);
- fs->pwd = dget(old->pwd);
- if (old->altroot) {
- fs->altrootmnt = mntget(old->altrootmnt);
- fs->altroot = dget(old->altroot);
+ fs->root = old->root;
+ path_get(&old->root);
+ fs->pwd = old->pwd;
+ path_get(&old->pwd);
+ if (old->altroot.dentry) {
+ fs->altroot = old->altroot;
+ path_get(&old->altroot);
} else {
- fs->altrootmnt = NULL;
- fs->altroot = NULL;
+ fs->altroot.mnt = NULL;
+ fs->altroot.dentry = NULL;
}
read_unlock(&old->lock);
}