Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ac08c39 authored by Jan Blunck's avatar Jan Blunck Committed by Linus Torvalds
Browse files

Use struct path in fs_struct



* Use struct path in fs_struct.

Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
Signed-off-by: default avatarJan Blunck <jblunck@suse.de>
Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5dd784d0
Loading
Loading
Loading
Loading
+15 −19
Original line number Diff line number Diff line
@@ -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(&current->fs->lock);
	rootmnt = mntget(current->fs->rootmnt);
	root = dget(current->fs->root);
	root = current->fs->root;
	path_get(&current->fs->root);
	read_unlock(&current->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(&current->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(&current->fs->pwd);
	root = current->fs->root;
	path_get(&current->fs->root);
	read_unlock(&current->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;
}
+23 −30
Original line number Diff line number Diff line
@@ -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;
+25 −32
Original line number Diff line number Diff line
@@ -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 @@ asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
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(&current->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(&current->fs->root);
	read_unlock(&current->fs->lock);
	down_write(&namespace_sem);
	mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);
+4 −4
Original line number Diff line number Diff line
@@ -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);
+2 −4
Original line number Diff line number Diff line
#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 {				\
Loading