diff options
| -rw-r--r-- | fs/dcache.c | 34 | ||||
| -rw-r--r-- | fs/namei.c | 53 | ||||
| -rw-r--r-- | fs/namespace.c | 57 | ||||
| -rw-r--r-- | fs/proc/base.c | 8 | ||||
| -rw-r--r-- | include/linux/fs_struct.h | 6 | ||||
| -rw-r--r-- | init/do_mounts.c | 6 | ||||
| -rw-r--r-- | kernel/auditsc.c | 4 | ||||
| -rw-r--r-- | kernel/exit.c | 12 | ||||
| -rw-r--r-- | kernel/fork.c | 18 | 
9 files changed, 87 insertions, 111 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 44f6cf23b70..66aaf52199e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1849,8 +1849,7 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,  				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 @@ -1863,14 +1862,13 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,  		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;  } @@ -1916,28 +1914,28 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,  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); @@ -1955,10 +1953,8 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)  		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;  } diff --git a/fs/namei.c b/fs/namei.c index a6575ca9f9d..941c8e8228c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -549,16 +549,16 @@ walk_init_root(const char *name, struct nameidata *nd)  	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;  } @@ -755,8 +755,8 @@ static __always_inline void follow_dotdot(struct nameidata *nd)  		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;  		} @@ -1078,8 +1078,8 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)  		 */  		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) { @@ -1099,29 +1099,22 @@ void set_fs_altroot(void)  {  	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. */ @@ -1139,21 +1132,21 @@ static int do_path_lookup(int dfd, const char *name,  	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; diff --git a/fs/namespace.c b/fs/namespace.c index c77eedd2ac6..ac19212c9bc 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -593,7 +593,7 @@ static int do_umount(struct vfsmount *mnt, int flags)  	 *  (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; @@ -628,7 +628,7 @@ static int do_umount(struct vfsmount *mnt, int flags)  	 * /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. @@ -1559,17 +1559,17 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,  	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); @@ -1653,18 +1653,15 @@ out1:  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);  }  /* @@ -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,  		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) @@ -1702,12 +1695,12 @@ 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); @@ -1773,8 +1766,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root,  	}  	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); diff --git a/fs/proc/base.c b/fs/proc/base.c index c742be48348..080f1f6eda6 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs  	}  	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); @@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf  	}  	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); diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 11a36ceddf7..e3e7254412d 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -1,15 +1,13 @@  #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 {				\ diff --git a/init/do_mounts.c b/init/do_mounts.c index f86573126f8..3885e70e775 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -193,10 +193,10 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data)  		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;  } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 1c06ecf38d7..741291a1de0 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1697,8 +1697,8 @@ void __audit_getname(const char *name)  	++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);  	} diff --git a/kernel/exit.c b/kernel/exit.c index 3b893e78ce6..506a957b665 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -512,14 +512,10 @@ static void __put_fs_struct(struct fs_struct *fs)  {  	/* 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);  	}  } diff --git a/kernel/fork.c b/kernel/fork.c index 4363a4eb84e..dd249c37b3a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -600,16 +600,16 @@ static struct fs_struct *__copy_fs_struct(struct fs_struct *old)  		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);  	}  |