|
@@ -518,18 +518,20 @@ static int __emul_lookup_dentry(const char *, struct nameidata *);
|
|
static __always_inline int
|
|
static __always_inline int
|
|
walk_init_root(const char *name, struct nameidata *nd)
|
|
walk_init_root(const char *name, struct nameidata *nd)
|
|
{
|
|
{
|
|
- read_lock(¤t->fs->lock);
|
|
|
|
- if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
|
|
|
|
- nd->mnt = mntget(current->fs->altrootmnt);
|
|
|
|
- nd->dentry = dget(current->fs->altroot);
|
|
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ struct fs_struct *fs = current->fs;
|
|
|
|
+
|
|
|
|
+ read_lock(&fs->lock);
|
|
|
|
+ if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
|
|
|
|
+ nd->mnt = mntget(fs->altrootmnt);
|
|
|
|
+ nd->dentry = dget(fs->altroot);
|
|
|
|
+ read_unlock(&fs->lock);
|
|
if (__emul_lookup_dentry(name,nd))
|
|
if (__emul_lookup_dentry(name,nd))
|
|
return 0;
|
|
return 0;
|
|
- read_lock(¤t->fs->lock);
|
|
|
|
|
|
+ read_lock(&fs->lock);
|
|
}
|
|
}
|
|
- nd->mnt = mntget(current->fs->rootmnt);
|
|
|
|
- nd->dentry = dget(current->fs->root);
|
|
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ nd->mnt = mntget(fs->rootmnt);
|
|
|
|
+ nd->dentry = dget(fs->root);
|
|
|
|
+ read_unlock(&fs->lock);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -724,17 +726,19 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry)
|
|
|
|
|
|
static __always_inline void follow_dotdot(struct nameidata *nd)
|
|
static __always_inline void follow_dotdot(struct nameidata *nd)
|
|
{
|
|
{
|
|
|
|
+ struct fs_struct *fs = current->fs;
|
|
|
|
+
|
|
while(1) {
|
|
while(1) {
|
|
struct vfsmount *parent;
|
|
struct vfsmount *parent;
|
|
struct dentry *old = nd->dentry;
|
|
struct dentry *old = nd->dentry;
|
|
|
|
|
|
- read_lock(¤t->fs->lock);
|
|
|
|
- if (nd->dentry == current->fs->root &&
|
|
|
|
- nd->mnt == current->fs->rootmnt) {
|
|
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ read_lock(&fs->lock);
|
|
|
|
+ if (nd->dentry == fs->root &&
|
|
|
|
+ nd->mnt == fs->rootmnt) {
|
|
|
|
+ read_unlock(&fs->lock);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ read_unlock(&fs->lock);
|
|
spin_lock(&dcache_lock);
|
|
spin_lock(&dcache_lock);
|
|
if (nd->dentry != nd->mnt->mnt_root) {
|
|
if (nd->dentry != nd->mnt->mnt_root) {
|
|
nd->dentry = dget(nd->dentry->d_parent);
|
|
nd->dentry = dget(nd->dentry->d_parent);
|
|
@@ -1042,15 +1046,17 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
|
|
struct vfsmount *old_mnt = nd->mnt;
|
|
struct vfsmount *old_mnt = nd->mnt;
|
|
struct qstr last = nd->last;
|
|
struct qstr last = nd->last;
|
|
int last_type = nd->last_type;
|
|
int last_type = nd->last_type;
|
|
|
|
+ struct fs_struct *fs = current->fs;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
- * NAME was not found in alternate root or it's a directory. Try to find
|
|
|
|
- * it in the normal root:
|
|
|
|
|
|
+ * NAME was not found in alternate root or it's a directory.
|
|
|
|
+ * Try to find it in the normal root:
|
|
*/
|
|
*/
|
|
nd->last_type = LAST_ROOT;
|
|
nd->last_type = LAST_ROOT;
|
|
- read_lock(¤t->fs->lock);
|
|
|
|
- nd->mnt = mntget(current->fs->rootmnt);
|
|
|
|
- nd->dentry = dget(current->fs->root);
|
|
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ read_lock(&fs->lock);
|
|
|
|
+ nd->mnt = mntget(fs->rootmnt);
|
|
|
|
+ nd->dentry = dget(fs->root);
|
|
|
|
+ read_unlock(&fs->lock);
|
|
if (path_walk(name, nd) == 0) {
|
|
if (path_walk(name, nd) == 0) {
|
|
if (nd->dentry->d_inode) {
|
|
if (nd->dentry->d_inode) {
|
|
dput(old_dentry);
|
|
dput(old_dentry);
|
|
@@ -1074,6 +1080,7 @@ void set_fs_altroot(void)
|
|
struct vfsmount *mnt = NULL, *oldmnt;
|
|
struct vfsmount *mnt = NULL, *oldmnt;
|
|
struct dentry *dentry = NULL, *olddentry;
|
|
struct dentry *dentry = NULL, *olddentry;
|
|
int err;
|
|
int err;
|
|
|
|
+ struct fs_struct *fs = current->fs;
|
|
|
|
|
|
if (!emul)
|
|
if (!emul)
|
|
goto set_it;
|
|
goto set_it;
|
|
@@ -1083,12 +1090,12 @@ void set_fs_altroot(void)
|
|
dentry = nd.dentry;
|
|
dentry = nd.dentry;
|
|
}
|
|
}
|
|
set_it:
|
|
set_it:
|
|
- write_lock(¤t->fs->lock);
|
|
|
|
- oldmnt = current->fs->altrootmnt;
|
|
|
|
- olddentry = current->fs->altroot;
|
|
|
|
- current->fs->altrootmnt = mnt;
|
|
|
|
- current->fs->altroot = dentry;
|
|
|
|
- write_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ write_lock(&fs->lock);
|
|
|
|
+ oldmnt = fs->altrootmnt;
|
|
|
|
+ olddentry = fs->altroot;
|
|
|
|
+ fs->altrootmnt = mnt;
|
|
|
|
+ fs->altroot = dentry;
|
|
|
|
+ write_unlock(&fs->lock);
|
|
if (olddentry) {
|
|
if (olddentry) {
|
|
dput(olddentry);
|
|
dput(olddentry);
|
|
mntput(oldmnt);
|
|
mntput(oldmnt);
|
|
@@ -1102,29 +1109,30 @@ static int fastcall do_path_lookup(int dfd, const char *name,
|
|
int retval = 0;
|
|
int retval = 0;
|
|
int fput_needed;
|
|
int fput_needed;
|
|
struct file *file;
|
|
struct file *file;
|
|
|
|
+ struct fs_struct *fs = current->fs;
|
|
|
|
|
|
nd->last_type = LAST_ROOT; /* if there are only slashes... */
|
|
nd->last_type = LAST_ROOT; /* if there are only slashes... */
|
|
nd->flags = flags;
|
|
nd->flags = flags;
|
|
nd->depth = 0;
|
|
nd->depth = 0;
|
|
|
|
|
|
if (*name=='/') {
|
|
if (*name=='/') {
|
|
- read_lock(¤t->fs->lock);
|
|
|
|
- if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
|
|
|
|
- nd->mnt = mntget(current->fs->altrootmnt);
|
|
|
|
- nd->dentry = dget(current->fs->altroot);
|
|
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ read_lock(&fs->lock);
|
|
|
|
+ if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
|
|
|
|
+ nd->mnt = mntget(fs->altrootmnt);
|
|
|
|
+ nd->dentry = dget(fs->altroot);
|
|
|
|
+ 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(¤t->fs->lock);
|
|
|
|
|
|
+ read_lock(&fs->lock);
|
|
}
|
|
}
|
|
- nd->mnt = mntget(current->fs->rootmnt);
|
|
|
|
- nd->dentry = dget(current->fs->root);
|
|
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ nd->mnt = mntget(fs->rootmnt);
|
|
|
|
+ nd->dentry = dget(fs->root);
|
|
|
|
+ read_unlock(&fs->lock);
|
|
} else if (dfd == AT_FDCWD) {
|
|
} else if (dfd == AT_FDCWD) {
|
|
- read_lock(¤t->fs->lock);
|
|
|
|
- nd->mnt = mntget(current->fs->pwdmnt);
|
|
|
|
- nd->dentry = dget(current->fs->pwd);
|
|
|
|
- read_unlock(¤t->fs->lock);
|
|
|
|
|
|
+ read_lock(&fs->lock);
|
|
|
|
+ nd->mnt = mntget(fs->pwdmnt);
|
|
|
|
+ nd->dentry = dget(fs->pwd);
|
|
|
|
+ read_unlock(&fs->lock);
|
|
} else {
|
|
} else {
|
|
struct dentry *dentry;
|
|
struct dentry *dentry;
|
|
|
|
|