@@ -37,7 +37,9 @@ static inline int sysfs_init(void)
3737#endif
3838
3939/* spinlock for vfsmount related operations, inplace of dcache_lock */
40- __cacheline_aligned_in_smp DEFINE_SPINLOCK (vfsmount_lock );
40+ __cacheline_aligned_in_smp DEFINE_SPINLOCK (vfsmount_lock );
41+
42+ static int event ;
4143
4244static struct list_head * mount_hashtable ;
4345static int hash_mask __read_mostly , hash_bits __read_mostly ;
@@ -111,6 +113,22 @@ static inline int check_mnt(struct vfsmount *mnt)
111113 return mnt -> mnt_namespace == current -> namespace ;
112114}
113115
116+ static void touch_namespace (struct namespace * ns )
117+ {
118+ if (ns ) {
119+ ns -> event = ++ event ;
120+ wake_up_interruptible (& ns -> poll );
121+ }
122+ }
123+
124+ static void __touch_namespace (struct namespace * ns )
125+ {
126+ if (ns && ns -> event != event ) {
127+ ns -> event = event ;
128+ wake_up_interruptible (& ns -> poll );
129+ }
130+ }
131+
114132static void detach_mnt (struct vfsmount * mnt , struct nameidata * old_nd )
115133{
116134 old_nd -> dentry = mnt -> mnt_mountpoint ;
@@ -384,6 +402,7 @@ static void umount_tree(struct vfsmount *mnt)
384402 for (p = mnt ; p ; p = next_mnt (p , mnt )) {
385403 list_del (& p -> mnt_list );
386404 list_add (& p -> mnt_list , & kill );
405+ __touch_namespace (p -> mnt_namespace );
387406 p -> mnt_namespace = NULL ;
388407 }
389408
@@ -473,6 +492,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
473492
474493 down_write (& current -> namespace -> sem );
475494 spin_lock (& vfsmount_lock );
495+ event ++ ;
476496
477497 retval = - EBUSY ;
478498 if (atomic_read (& mnt -> mnt_count ) == 2 || flags & MNT_DETACH ) {
@@ -634,6 +654,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
634654 list_splice (& head , current -> namespace -> list .prev );
635655 mntget (mnt );
636656 err = 0 ;
657+ touch_namespace (current -> namespace );
637658 }
638659 spin_unlock (& vfsmount_lock );
639660out_unlock :
@@ -771,6 +792,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
771792
772793 detach_mnt (old_nd .mnt , & parent_nd );
773794 attach_mnt (old_nd .mnt , nd );
795+ touch_namespace (current -> namespace );
774796
775797 /* if the mount is moved, it should no longer be expire
776798 * automatically */
@@ -877,6 +899,7 @@ static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
877899 struct nameidata old_nd ;
878900
879901 /* delete from the namespace */
902+ touch_namespace (mnt -> mnt_namespace );
880903 list_del_init (& mnt -> mnt_list );
881904 mnt -> mnt_namespace = NULL ;
882905 detach_mnt (mnt , & old_nd );
@@ -1114,6 +1137,8 @@ int copy_namespace(int flags, struct task_struct *tsk)
11141137 atomic_set (& new_ns -> count , 1 );
11151138 init_rwsem (& new_ns -> sem );
11161139 INIT_LIST_HEAD (& new_ns -> list );
1140+ init_waitqueue_head (& new_ns -> poll );
1141+ new_ns -> event = 0 ;
11171142
11181143 down_write (& tsk -> namespace -> sem );
11191144 /* First pass: copy the tree topology */
@@ -1377,6 +1402,7 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
13771402 detach_mnt (user_nd .mnt , & root_parent );
13781403 attach_mnt (user_nd .mnt , & old_nd ); /* mount old root on put_old */
13791404 attach_mnt (new_nd .mnt , & root_parent ); /* mount new_root on / */
1405+ touch_namespace (current -> namespace );
13801406 spin_unlock (& vfsmount_lock );
13811407 chroot_fs_refs (& user_nd , & new_nd );
13821408 security_sb_post_pivotroot (& user_nd , & new_nd );
@@ -1413,6 +1439,8 @@ static void __init init_mount_tree(void)
14131439 atomic_set (& namespace -> count , 1 );
14141440 INIT_LIST_HEAD (& namespace -> list );
14151441 init_rwsem (& namespace -> sem );
1442+ init_waitqueue_head (& namespace -> poll );
1443+ namespace -> event = 0 ;
14161444 list_add (& mnt -> mnt_list , & namespace -> list );
14171445 namespace -> root = mnt ;
14181446 mnt -> mnt_namespace = namespace ;
0 commit comments