diff options
| -rw-r--r-- | fs/namespace.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index d46a951bd541..bd2f4c68506a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -659,12 +659,21 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq) | |||
| 659 | return 0; | 659 | return 0; |
| 660 | mnt = real_mount(bastard); | 660 | mnt = real_mount(bastard); |
| 661 | mnt_add_count(mnt, 1); | 661 | mnt_add_count(mnt, 1); |
| 662 | smp_mb(); // see mntput_no_expire() | ||
| 662 | if (likely(!read_seqretry(&mount_lock, seq))) | 663 | if (likely(!read_seqretry(&mount_lock, seq))) |
| 663 | return 0; | 664 | return 0; |
| 664 | if (bastard->mnt_flags & MNT_SYNC_UMOUNT) { | 665 | if (bastard->mnt_flags & MNT_SYNC_UMOUNT) { |
| 665 | mnt_add_count(mnt, -1); | 666 | mnt_add_count(mnt, -1); |
| 666 | return 1; | 667 | return 1; |
| 667 | } | 668 | } |
| 669 | lock_mount_hash(); | ||
| 670 | if (unlikely(bastard->mnt_flags & MNT_DOOMED)) { | ||
| 671 | mnt_add_count(mnt, -1); | ||
| 672 | unlock_mount_hash(); | ||
| 673 | return 1; | ||
| 674 | } | ||
| 675 | unlock_mount_hash(); | ||
| 676 | /* caller will mntput() */ | ||
| 668 | return -1; | 677 | return -1; |
| 669 | } | 678 | } |
| 670 | 679 | ||
| @@ -1210,6 +1219,11 @@ static void mntput_no_expire(struct mount *mnt) | |||
| 1210 | return; | 1219 | return; |
| 1211 | } | 1220 | } |
| 1212 | lock_mount_hash(); | 1221 | lock_mount_hash(); |
| 1222 | /* | ||
| 1223 | * make sure that if __legitimize_mnt() has not seen us grab | ||
| 1224 | * mount_lock, we'll see their refcount increment here. | ||
| 1225 | */ | ||
| 1226 | smp_mb(); | ||
| 1213 | mnt_add_count(mnt, -1); | 1227 | mnt_add_count(mnt, -1); |
| 1214 | if (mnt_get_count(mnt)) { | 1228 | if (mnt_get_count(mnt)) { |
| 1215 | rcu_read_unlock(); | 1229 | rcu_read_unlock(); |
