|
@@ -1109,7 +1109,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
|
|
|
return false;
|
|
|
|
|
|
if (!d_mountpoint(path->dentry))
|
|
|
- break;
|
|
|
+ return true;
|
|
|
|
|
|
mounted = __lookup_mnt(path->mnt, path->dentry);
|
|
|
if (!mounted)
|
|
@@ -1125,20 +1125,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
|
|
|
*/
|
|
|
*inode = path->dentry->d_inode;
|
|
|
}
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-static void follow_mount_rcu(struct nameidata *nd)
|
|
|
-{
|
|
|
- while (d_mountpoint(nd->path.dentry)) {
|
|
|
- struct mount *mounted;
|
|
|
- mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
|
|
|
- if (!mounted)
|
|
|
- break;
|
|
|
- nd->path.mnt = &mounted->mnt;
|
|
|
- nd->path.dentry = mounted->mnt.mnt_root;
|
|
|
- nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
|
|
|
- }
|
|
|
+ return read_seqretry(&mount_lock, nd->m_seq);
|
|
|
}
|
|
|
|
|
|
static int follow_dotdot_rcu(struct nameidata *nd)
|
|
@@ -1166,7 +1153,17 @@ static int follow_dotdot_rcu(struct nameidata *nd)
|
|
|
break;
|
|
|
nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
|
|
|
}
|
|
|
- follow_mount_rcu(nd);
|
|
|
+ while (d_mountpoint(nd->path.dentry)) {
|
|
|
+ struct mount *mounted;
|
|
|
+ mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
|
|
|
+ if (!mounted)
|
|
|
+ break;
|
|
|
+ nd->path.mnt = &mounted->mnt;
|
|
|
+ nd->path.dentry = mounted->mnt.mnt_root;
|
|
|
+ nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
|
|
|
+ if (!read_seqretry(&mount_lock, nd->m_seq))
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
nd->inode = nd->path.dentry->d_inode;
|
|
|
return 0;
|
|
|
|