mirror of https://gitee.com/openkylin/linux.git
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:
parent
5dd784d049
commit
6ac08c39a1
34
fs/dcache.c
34
fs/dcache.c
|
@ -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(¤t->fs->lock);
|
read_lock(¤t->fs->lock);
|
||||||
rootmnt = mntget(current->fs->rootmnt);
|
root = current->fs->root;
|
||||||
root = dget(current->fs->root);
|
path_get(¤t->fs->root);
|
||||||
read_unlock(¤t->fs->lock);
|
read_unlock(¤t->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(¤t->fs->lock);
|
read_lock(¤t->fs->lock);
|
||||||
pwdmnt = mntget(current->fs->pwdmnt);
|
pwd = current->fs->pwd;
|
||||||
pwd = dget(current->fs->pwd);
|
path_get(¤t->fs->pwd);
|
||||||
rootmnt = mntget(current->fs->rootmnt);
|
root = current->fs->root;
|
||||||
root = dget(current->fs->root);
|
path_get(¤t->fs->root);
|
||||||
read_unlock(¤t->fs->lock);
|
read_unlock(¤t->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;
|
||||||
}
|
}
|
||||||
|
|
53
fs/namei.c
53
fs/namei.c
|
@ -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;
|
||||||
|
|
|
@ -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 @@ asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
|
||||||
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(¤t->fs->lock);
|
read_lock(¤t->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(¤t->fs->root);
|
||||||
read_unlock(¤t->fs->lock);
|
read_unlock(¤t->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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 { \
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1697,8 +1697,8 @@ void __audit_getname(const char *name)
|
||||||
++context->name_count;
|
++context->name_count;
|
||||||
if (!context->pwd) {
|
if (!context->pwd) {
|
||||||
read_lock(¤t->fs->lock);
|
read_lock(¤t->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(¤t->fs->lock);
|
read_unlock(¤t->fs->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue