Use struct path in fs_struct

* 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>
This commit is contained in:
Jan Blunck 2008-02-14 19:34:38 -08:00 committed by Linus Torvalds
parent 5dd784d049
commit 6ac08c39a1
9 changed files with 87 additions and 111 deletions

View File

@ -1849,8 +1849,7 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
char *buf, int buflen) char *buf, int buflen)
{ {
char *res; char *res;
struct vfsmount *rootmnt; struct path root;
struct dentry *root;
/* /*
* We have various synthetic filesystems that never get mounted. On * We have various synthetic filesystems that never get mounted. On
@ -1863,14 +1862,13 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
return dentry->d_op->d_dname(dentry, buf, buflen); return dentry->d_op->d_dname(dentry, buf, buflen);
read_lock(&current->fs->lock); read_lock(&current->fs->lock);
rootmnt = mntget(current->fs->rootmnt); root = current->fs->root;
root = dget(current->fs->root); path_get(&current->fs->root);
read_unlock(&current->fs->lock); read_unlock(&current->fs->lock);
spin_lock(&dcache_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); spin_unlock(&dcache_lock);
dput(root); path_put(&root);
mntput(rootmnt);
return res; return res;
} }
@ -1916,28 +1914,28 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
asmlinkage long sys_getcwd(char __user *buf, unsigned long size) asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
{ {
int error; int error;
struct vfsmount *pwdmnt, *rootmnt; struct path pwd, root;
struct dentry *pwd, *root;
char *page = (char *) __get_free_page(GFP_USER); char *page = (char *) __get_free_page(GFP_USER);
if (!page) if (!page)
return -ENOMEM; return -ENOMEM;
read_lock(&current->fs->lock); read_lock(&current->fs->lock);
pwdmnt = mntget(current->fs->pwdmnt); pwd = current->fs->pwd;
pwd = dget(current->fs->pwd); path_get(&current->fs->pwd);
rootmnt = mntget(current->fs->rootmnt); root = current->fs->root;
root = dget(current->fs->root); path_get(&current->fs->root);
read_unlock(&current->fs->lock); read_unlock(&current->fs->lock);
error = -ENOENT; error = -ENOENT;
/* Has the current directory has been unlinked? */ /* Has the current directory has been unlinked? */
spin_lock(&dcache_lock); 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; unsigned long len;
char * cwd; 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); spin_unlock(&dcache_lock);
error = PTR_ERR(cwd); error = PTR_ERR(cwd);
@ -1955,10 +1953,8 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
out: out:
dput(pwd); path_put(&pwd);
mntput(pwdmnt); path_put(&root);
dput(root);
mntput(rootmnt);
free_page((unsigned long) page); free_page((unsigned long) page);
return error; return error;
} }

View File

@ -549,16 +549,16 @@ walk_init_root(const char *name, struct nameidata *nd)
struct fs_struct *fs = current->fs; struct fs_struct *fs = current->fs;
read_lock(&fs->lock); read_lock(&fs->lock);
if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
nd->path.mnt = mntget(fs->altrootmnt); nd->path = fs->altroot;
nd->path.dentry = dget(fs->altroot); path_get(&fs->altroot);
read_unlock(&fs->lock); read_unlock(&fs->lock);
if (__emul_lookup_dentry(name,nd)) if (__emul_lookup_dentry(name,nd))
return 0; return 0;
read_lock(&fs->lock); read_lock(&fs->lock);
} }
nd->path.mnt = mntget(fs->rootmnt); nd->path = fs->root;
nd->path.dentry = dget(fs->root); path_get(&fs->root);
read_unlock(&fs->lock); read_unlock(&fs->lock);
return 1; return 1;
} }
@ -755,8 +755,8 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
struct dentry *old = nd->path.dentry; struct dentry *old = nd->path.dentry;
read_lock(&fs->lock); read_lock(&fs->lock);
if (nd->path.dentry == fs->root && if (nd->path.dentry == fs->root.dentry &&
nd->path.mnt == fs->rootmnt) { nd->path.mnt == fs->root.mnt) {
read_unlock(&fs->lock); read_unlock(&fs->lock);
break; break;
} }
@ -1078,8 +1078,8 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
*/ */
nd->last_type = LAST_ROOT; nd->last_type = LAST_ROOT;
read_lock(&fs->lock); read_lock(&fs->lock);
nd->path.mnt = mntget(fs->rootmnt); nd->path = fs->root;
nd->path.dentry = dget(fs->root); path_get(&fs->root);
read_unlock(&fs->lock); read_unlock(&fs->lock);
if (path_walk(name, nd) == 0) { if (path_walk(name, nd) == 0) {
if (nd->path.dentry->d_inode) { if (nd->path.dentry->d_inode) {
@ -1099,29 +1099,22 @@ void set_fs_altroot(void)
{ {
char *emul = __emul_prefix(); char *emul = __emul_prefix();
struct nameidata nd; struct nameidata nd;
struct vfsmount *mnt = NULL, *oldmnt; struct path path = {}, old_path;
struct dentry *dentry = NULL, *olddentry;
int err; int err;
struct fs_struct *fs = current->fs; struct fs_struct *fs = current->fs;
if (!emul) if (!emul)
goto set_it; goto set_it;
err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
if (!err) { if (!err)
mnt = nd.path.mnt; path = nd.path;
dentry = nd.path.dentry;
}
set_it: set_it:
write_lock(&fs->lock); write_lock(&fs->lock);
oldmnt = fs->altrootmnt; old_path = fs->altroot;
olddentry = fs->altroot; fs->altroot = path;
fs->altrootmnt = mnt;
fs->altroot = dentry;
write_unlock(&fs->lock); write_unlock(&fs->lock);
if (olddentry) { if (old_path.dentry)
dput(olddentry); path_put(&old_path);
mntput(oldmnt);
}
} }
/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
@ -1139,21 +1132,21 @@ static int do_path_lookup(int dfd, const char *name,
if (*name=='/') { if (*name=='/') {
read_lock(&fs->lock); read_lock(&fs->lock);
if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
nd->path.mnt = mntget(fs->altrootmnt); nd->path = fs->altroot;
nd->path.dentry = dget(fs->altroot); path_get(&fs->altroot);
read_unlock(&fs->lock); read_unlock(&fs->lock);
if (__emul_lookup_dentry(name,nd)) if (__emul_lookup_dentry(name,nd))
goto out; /* found in altroot */ goto out; /* found in altroot */
read_lock(&fs->lock); read_lock(&fs->lock);
} }
nd->path.mnt = mntget(fs->rootmnt); nd->path = fs->root;
nd->path.dentry = dget(fs->root); path_get(&fs->root);
read_unlock(&fs->lock); read_unlock(&fs->lock);
} else if (dfd == AT_FDCWD) { } else if (dfd == AT_FDCWD) {
read_lock(&fs->lock); read_lock(&fs->lock);
nd->path.mnt = mntget(fs->pwdmnt); nd->path = fs->pwd;
nd->path.dentry = dget(fs->pwd); path_get(&fs->pwd);
read_unlock(&fs->lock); read_unlock(&fs->lock);
} else { } else {
struct dentry *dentry; struct dentry *dentry;

View File

@ -593,7 +593,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
* (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount] * (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
*/ */
if (flags & MNT_EXPIRE) { if (flags & MNT_EXPIRE) {
if (mnt == current->fs->rootmnt || if (mnt == current->fs->root.mnt ||
flags & (MNT_FORCE | MNT_DETACH)) flags & (MNT_FORCE | MNT_DETACH))
return -EINVAL; return -EINVAL;
@ -628,7 +628,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
* /reboot - static binary that would close all descriptors and * /reboot - static binary that would close all descriptors and
* call reboot(9). Then init(8) could umount root and exec /reboot. * 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 ... * Special case for "unmounting" root ...
* we just try to remount it readonly. * we just try to remount it readonly.
@ -1559,17 +1559,17 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
while (p) { while (p) {
q->mnt_ns = new_ns; q->mnt_ns = new_ns;
if (fs) { if (fs) {
if (p == fs->rootmnt) { if (p == fs->root.mnt) {
rootmnt = p; rootmnt = p;
fs->rootmnt = mntget(q); fs->root.mnt = mntget(q);
} }
if (p == fs->pwdmnt) { if (p == fs->pwd.mnt) {
pwdmnt = p; pwdmnt = p;
fs->pwdmnt = mntget(q); fs->pwd.mnt = mntget(q);
} }
if (p == fs->altrootmnt) { if (p == fs->altroot.mnt) {
altrootmnt = p; altrootmnt = p;
fs->altrootmnt = mntget(q); fs->altroot.mnt = mntget(q);
} }
} }
p = next_mnt(p, mnt_ns->root); p = next_mnt(p, mnt_ns->root);
@ -1653,18 +1653,15 @@ out1:
void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
struct dentry *dentry) struct dentry *dentry)
{ {
struct dentry *old_root; struct path old_root;
struct vfsmount *old_rootmnt;
write_lock(&fs->lock); write_lock(&fs->lock);
old_root = fs->root; old_root = fs->root;
old_rootmnt = fs->rootmnt; fs->root.mnt = mntget(mnt);
fs->rootmnt = mntget(mnt); fs->root.dentry = dget(dentry);
fs->root = dget(dentry);
write_unlock(&fs->lock); write_unlock(&fs->lock);
if (old_root) { if (old_root.dentry)
dput(old_root); path_put(&old_root);
mntput(old_rootmnt);
}
} }
/* /*
@ -1674,20 +1671,16 @@ void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
struct dentry *dentry) struct dentry *dentry)
{ {
struct dentry *old_pwd; struct path old_pwd;
struct vfsmount *old_pwdmnt;
write_lock(&fs->lock); write_lock(&fs->lock);
old_pwd = fs->pwd; old_pwd = fs->pwd;
old_pwdmnt = fs->pwdmnt; fs->pwd.mnt = mntget(mnt);
fs->pwdmnt = mntget(mnt); fs->pwd.dentry = dget(dentry);
fs->pwd = dget(dentry);
write_unlock(&fs->lock); write_unlock(&fs->lock);
if (old_pwd) { if (old_pwd.dentry)
dput(old_pwd); path_put(&old_pwd);
mntput(old_pwdmnt);
}
} }
static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
@ -1702,12 +1695,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
if (fs) { if (fs) {
atomic_inc(&fs->count); atomic_inc(&fs->count);
task_unlock(p); task_unlock(p);
if (fs->root == old_nd->path.dentry if (fs->root.dentry == old_nd->path.dentry
&& fs->rootmnt == old_nd->path.mnt) && fs->root.mnt == old_nd->path.mnt)
set_fs_root(fs, new_nd->path.mnt, set_fs_root(fs, new_nd->path.mnt,
new_nd->path.dentry); new_nd->path.dentry);
if (fs->pwd == old_nd->path.dentry if (fs->pwd.dentry == old_nd->path.dentry
&& fs->pwdmnt == old_nd->path.mnt) && fs->pwd.mnt == old_nd->path.mnt)
set_fs_pwd(fs, new_nd->path.mnt, set_fs_pwd(fs, new_nd->path.mnt,
new_nd->path.dentry); new_nd->path.dentry);
put_fs_struct(fs); put_fs_struct(fs);
@ -1773,8 +1766,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
} }
read_lock(&current->fs->lock); read_lock(&current->fs->lock);
user_nd.path.mnt = mntget(current->fs->rootmnt); user_nd.path = current->fs->root;
user_nd.path.dentry = dget(current->fs->root); path_get(&current->fs->root);
read_unlock(&current->fs->lock); read_unlock(&current->fs->lock);
down_write(&namespace_sem); down_write(&namespace_sem);
mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);

View File

@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
} }
if (fs) { if (fs) {
read_lock(&fs->lock); read_lock(&fs->lock);
*mnt = mntget(fs->pwdmnt); *mnt = mntget(fs->pwd.mnt);
*dentry = dget(fs->pwd); *dentry = dget(fs->pwd.dentry);
read_unlock(&fs->lock); read_unlock(&fs->lock);
result = 0; result = 0;
put_fs_struct(fs); put_fs_struct(fs);
@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
} }
if (fs) { if (fs) {
read_lock(&fs->lock); read_lock(&fs->lock);
*mnt = mntget(fs->rootmnt); *mnt = mntget(fs->root.mnt);
*dentry = dget(fs->root); *dentry = dget(fs->root.dentry);
read_unlock(&fs->lock); read_unlock(&fs->lock);
result = 0; result = 0;
put_fs_struct(fs); put_fs_struct(fs);

View File

@ -1,15 +1,13 @@
#ifndef _LINUX_FS_STRUCT_H #ifndef _LINUX_FS_STRUCT_H
#define _LINUX_FS_STRUCT_H #define _LINUX_FS_STRUCT_H
struct dentry; #include <linux/path.h>
struct vfsmount;
struct fs_struct { struct fs_struct {
atomic_t count; atomic_t count;
rwlock_t lock; rwlock_t lock;
int umask; int umask;
struct dentry * root, * pwd, * altroot; struct path root, pwd, altroot;
struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
}; };
#define INIT_FS { \ #define INIT_FS { \

View File

@ -193,10 +193,10 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data)
return err; return err;
sys_chdir("/root"); 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", printk("VFS: Mounted root (%s filesystem)%s.\n",
current->fs->pwdmnt->mnt_sb->s_type->name, current->fs->pwd.mnt->mnt_sb->s_type->name,
current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ?
" readonly" : ""); " readonly" : "");
return 0; return 0;
} }

View File

@ -1697,8 +1697,8 @@ void __audit_getname(const char *name)
++context->name_count; ++context->name_count;
if (!context->pwd) { if (!context->pwd) {
read_lock(&current->fs->lock); read_lock(&current->fs->lock);
context->pwd = dget(current->fs->pwd); context->pwd = dget(current->fs->pwd.dentry);
context->pwdmnt = mntget(current->fs->pwdmnt); context->pwdmnt = mntget(current->fs->pwd.mnt);
read_unlock(&current->fs->lock); read_unlock(&current->fs->lock);
} }

View File

@ -512,14 +512,10 @@ static void __put_fs_struct(struct fs_struct *fs)
{ {
/* No need to hold fs->lock if we are killing it */ /* No need to hold fs->lock if we are killing it */
if (atomic_dec_and_test(&fs->count)) { if (atomic_dec_and_test(&fs->count)) {
dput(fs->root); path_put(&fs->root);
mntput(fs->rootmnt); path_put(&fs->pwd);
dput(fs->pwd); if (fs->altroot.dentry)
mntput(fs->pwdmnt); path_put(&fs->altroot);
if (fs->altroot) {
dput(fs->altroot);
mntput(fs->altrootmnt);
}
kmem_cache_free(fs_cachep, fs); kmem_cache_free(fs_cachep, fs);
} }
} }

View File

@ -600,16 +600,16 @@ static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
rwlock_init(&fs->lock); rwlock_init(&fs->lock);
fs->umask = old->umask; fs->umask = old->umask;
read_lock(&old->lock); read_lock(&old->lock);
fs->rootmnt = mntget(old->rootmnt); fs->root = old->root;
fs->root = dget(old->root); path_get(&old->root);
fs->pwdmnt = mntget(old->pwdmnt); fs->pwd = old->pwd;
fs->pwd = dget(old->pwd); path_get(&old->pwd);
if (old->altroot) { if (old->altroot.dentry) {
fs->altrootmnt = mntget(old->altrootmnt); fs->altroot = old->altroot;
fs->altroot = dget(old->altroot); path_get(&old->altroot);
} else { } else {
fs->altrootmnt = NULL; fs->altroot.mnt = NULL;
fs->altroot = NULL; fs->altroot.dentry = NULL;
} }
read_unlock(&old->lock); read_unlock(&old->lock);
} }