|
@@ -659,12 +659,21 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
|
|
|
return 0;
|
|
|
mnt = real_mount(bastard);
|
|
|
mnt_add_count(mnt, 1);
|
|
|
+ smp_mb(); // see mntput_no_expire()
|
|
|
if (likely(!read_seqretry(&mount_lock, seq)))
|
|
|
return 0;
|
|
|
if (bastard->mnt_flags & MNT_SYNC_UMOUNT) {
|
|
|
mnt_add_count(mnt, -1);
|
|
|
return 1;
|
|
|
}
|
|
|
+ lock_mount_hash();
|
|
|
+ if (unlikely(bastard->mnt_flags & MNT_DOOMED)) {
|
|
|
+ mnt_add_count(mnt, -1);
|
|
|
+ unlock_mount_hash();
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ unlock_mount_hash();
|
|
|
+ /* caller will mntput() */
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -1210,6 +1219,11 @@ static void mntput_no_expire(struct mount *mnt)
|
|
|
return;
|
|
|
}
|
|
|
lock_mount_hash();
|
|
|
+ /*
|
|
|
+ * make sure that if __legitimize_mnt() has not seen us grab
|
|
|
+ * mount_lock, we'll see their refcount increment here.
|
|
|
+ */
|
|
|
+ smp_mb();
|
|
|
mnt_add_count(mnt, -1);
|
|
|
if (mnt_get_count(mnt)) {
|
|
|
rcu_read_unlock();
|