aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 3dbfc072ec70..39a7d507fba0 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -492,6 +492,27 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
492} 492}
493 493
494/* 494/*
495 * Clear dentry's mounted state if it has no remaining mounts.
496 * vfsmount_lock must be held for write.
497 */
498static void dentry_reset_mounted(struct vfsmount *mnt, struct dentry *dentry)
499{
500 unsigned u;
501
502 for (u = 0; u < HASH_SIZE; u++) {
503 struct vfsmount *p;
504
505 list_for_each_entry(p, &mount_hashtable[u], mnt_hash) {
506 if (p->mnt_mountpoint == dentry)
507 return;
508 }
509 }
510 spin_lock(&dentry->d_lock);
511 dentry->d_flags &= ~DCACHE_MOUNTED;
512 spin_unlock(&dentry->d_lock);
513}
514
515/*
495 * vfsmount lock must be held for write 516 * vfsmount lock must be held for write
496 */ 517 */
497static void detach_mnt(struct vfsmount *mnt, struct path *old_path) 518static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
@@ -502,7 +523,7 @@ static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
502 mnt->mnt_mountpoint = mnt->mnt_root; 523 mnt->mnt_mountpoint = mnt->mnt_root;
503 list_del_init(&mnt->mnt_child); 524 list_del_init(&mnt->mnt_child);
504 list_del_init(&mnt->mnt_hash); 525 list_del_init(&mnt->mnt_hash);
505 old_path->dentry->d_mounted--; 526 dentry_reset_mounted(old_path->mnt, old_path->dentry);
506} 527}
507 528
508/* 529/*
@@ -513,7 +534,9 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
513{ 534{
514 child_mnt->mnt_parent = mntget(mnt); 535 child_mnt->mnt_parent = mntget(mnt);
515 child_mnt->mnt_mountpoint = dget(dentry); 536 child_mnt->mnt_mountpoint = dget(dentry);
516 dentry->d_mounted++; 537 spin_lock(&dentry->d_lock);
538 dentry->d_flags |= DCACHE_MOUNTED;
539 spin_unlock(&dentry->d_lock);
517} 540}
518 541
519/* 542/*
@@ -1073,7 +1096,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
1073 list_del_init(&p->mnt_child); 1096 list_del_init(&p->mnt_child);
1074 if (p->mnt_parent != p) { 1097 if (p->mnt_parent != p) {
1075 p->mnt_parent->mnt_ghosts++; 1098 p->mnt_parent->mnt_ghosts++;
1076 p->mnt_mountpoint->d_mounted--; 1099 dentry_reset_mounted(p->mnt_parent, p->mnt_mountpoint);
1077 } 1100 }
1078 change_mnt_propagation(p, MS_PRIVATE); 1101 change_mnt_propagation(p, MS_PRIVATE);
1079 } 1102 }