aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 0223c41fb114..14ab8d3f2f0c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -433,6 +433,8 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry)
433 goto err_parent; 433 goto err_parent;
434 BUG_ON(nd->inode != parent->d_inode); 434 BUG_ON(nd->inode != parent->d_inode);
435 } else { 435 } else {
436 if (dentry->d_parent != parent)
437 goto err_parent;
436 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 438 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
437 if (!__d_rcu_to_refcount(dentry, nd->seq)) 439 if (!__d_rcu_to_refcount(dentry, nd->seq))
438 goto err_child; 440 goto err_child;
@@ -940,7 +942,6 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
940 * Don't forget we might have a non-mountpoint managed dentry 942 * Don't forget we might have a non-mountpoint managed dentry
941 * that wants to block transit. 943 * that wants to block transit.
942 */ 944 */
943 *inode = path->dentry->d_inode;
944 if (unlikely(managed_dentry_might_block(path->dentry))) 945 if (unlikely(managed_dentry_might_block(path->dentry)))
945 return false; 946 return false;
946 947
@@ -953,6 +954,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
953 path->mnt = mounted; 954 path->mnt = mounted;
954 path->dentry = mounted->mnt_root; 955 path->dentry = mounted->mnt_root;
955 nd->seq = read_seqcount_begin(&path->dentry->d_seq); 956 nd->seq = read_seqcount_begin(&path->dentry->d_seq);
957 /*
958 * Update the inode too. We don't need to re-check the
959 * dentry sequence number here after this d_inode read,
960 * because a mount-point is always pinned.
961 */
962 *inode = path->dentry->d_inode;
956 } 963 }
957 return true; 964 return true;
958} 965}