@@ -394,39 +394,53 @@ int may_umount(struct vfsmount *mnt)
394394
395395EXPORT_SYMBOL (may_umount );
396396
397- static void umount_tree (struct vfsmount * mnt )
397+ static void release_mounts (struct list_head * head )
398+ {
399+ struct vfsmount * mnt ;
400+ while (!list_empty (head )) {
401+ mnt = list_entry (head -> next , struct vfsmount , mnt_hash );
402+ list_del_init (& mnt -> mnt_hash );
403+ if (mnt -> mnt_parent != mnt ) {
404+ struct dentry * dentry ;
405+ struct vfsmount * m ;
406+ spin_lock (& vfsmount_lock );
407+ dentry = mnt -> mnt_mountpoint ;
408+ m = mnt -> mnt_parent ;
409+ mnt -> mnt_mountpoint = mnt -> mnt_root ;
410+ mnt -> mnt_parent = mnt ;
411+ spin_unlock (& vfsmount_lock );
412+ dput (dentry );
413+ mntput (m );
414+ }
415+ mntput (mnt );
416+ }
417+ }
418+
419+ static void umount_tree (struct vfsmount * mnt , struct list_head * kill )
398420{
399421 struct vfsmount * p ;
400- LIST_HEAD (kill );
401422
402423 for (p = mnt ; p ; p = next_mnt (p , mnt )) {
403- list_del (& p -> mnt_list );
404- list_add (& p -> mnt_list , & kill );
405- __touch_namespace (p -> mnt_namespace );
406- p -> mnt_namespace = NULL ;
424+ list_del (& p -> mnt_hash );
425+ list_add (& p -> mnt_hash , kill );
407426 }
408427
409- while (!list_empty (& kill )) {
410- mnt = list_entry (kill .next , struct vfsmount , mnt_list );
411- list_del_init (& mnt -> mnt_list );
412- list_del_init (& mnt -> mnt_expire );
413- if (mnt -> mnt_parent == mnt ) {
414- spin_unlock (& vfsmount_lock );
415- } else {
416- struct nameidata old_nd ;
417- detach_mnt (mnt , & old_nd );
418- spin_unlock (& vfsmount_lock );
419- path_release (& old_nd );
420- }
421- mntput (mnt );
422- spin_lock (& vfsmount_lock );
428+ list_for_each_entry (p , kill , mnt_hash ) {
429+ list_del_init (& p -> mnt_expire );
430+ list_del_init (& p -> mnt_list );
431+ __touch_namespace (p -> mnt_namespace );
432+ p -> mnt_namespace = NULL ;
433+ list_del_init (& p -> mnt_child );
434+ if (p -> mnt_parent != p )
435+ mnt -> mnt_mountpoint -> d_mounted -- ;
423436 }
424437}
425438
426439static int do_umount (struct vfsmount * mnt , int flags )
427440{
428441 struct super_block * sb = mnt -> mnt_sb ;
429442 int retval ;
443+ LIST_HEAD (umount_list );
430444
431445 retval = security_sb_umount (mnt , flags );
432446 if (retval )
@@ -497,13 +511,14 @@ static int do_umount(struct vfsmount *mnt, int flags)
497511 retval = - EBUSY ;
498512 if (atomic_read (& mnt -> mnt_count ) == 2 || flags & MNT_DETACH ) {
499513 if (!list_empty (& mnt -> mnt_list ))
500- umount_tree (mnt );
514+ umount_tree (mnt , & umount_list );
501515 retval = 0 ;
502516 }
503517 spin_unlock (& vfsmount_lock );
504518 if (retval )
505519 security_sb_umount_busy (mnt );
506520 up_write (& current -> namespace -> sem );
521+ release_mounts (& umount_list );
507522 return retval ;
508523}
509524
@@ -616,9 +631,11 @@ static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
616631 return res ;
617632Enomem :
618633 if (res ) {
634+ LIST_HEAD (umount_list );
619635 spin_lock (& vfsmount_lock );
620- umount_tree (res );
636+ umount_tree (res , & umount_list );
621637 spin_unlock (& vfsmount_lock );
638+ release_mounts (& umount_list );
622639 }
623640 return NULL ;
624641}
@@ -698,9 +715,11 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
698715
699716 err = graft_tree (mnt , nd );
700717 if (err ) {
718+ LIST_HEAD (umount_list );
701719 spin_lock (& vfsmount_lock );
702- umount_tree (mnt );
720+ umount_tree (mnt , & umount_list );
703721 spin_unlock (& vfsmount_lock );
722+ release_mounts (& umount_list );
704723 }
705724
706725out :
@@ -875,7 +894,8 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
875894
876895EXPORT_SYMBOL_GPL (do_add_mount );
877896
878- static void expire_mount (struct vfsmount * mnt , struct list_head * mounts )
897+ static void expire_mount (struct vfsmount * mnt , struct list_head * mounts ,
898+ struct list_head * umounts )
879899{
880900 spin_lock (& vfsmount_lock );
881901
@@ -893,16 +913,12 @@ static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
893913 * contributed by the vfsmount parent and the mntget above
894914 */
895915 if (atomic_read (& mnt -> mnt_count ) == 2 ) {
896- struct nameidata old_nd ;
897-
898916 /* delete from the namespace */
899917 touch_namespace (mnt -> mnt_namespace );
900918 list_del_init (& mnt -> mnt_list );
901919 mnt -> mnt_namespace = NULL ;
902- detach_mnt (mnt , & old_nd );
920+ umount_tree (mnt , umounts );
903921 spin_unlock (& vfsmount_lock );
904- path_release (& old_nd );
905- mntput (mnt );
906922 } else {
907923 /*
908924 * Someone brought it back to life whilst we didn't have any
@@ -951,6 +967,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
951967 * - dispose of the corpse
952968 */
953969 while (!list_empty (& graveyard )) {
970+ LIST_HEAD (umounts );
954971 mnt = list_entry (graveyard .next , struct vfsmount , mnt_expire );
955972 list_del_init (& mnt -> mnt_expire );
956973
@@ -963,12 +980,11 @@ void mark_mounts_for_expiry(struct list_head *mounts)
963980
964981 spin_unlock (& vfsmount_lock );
965982 down_write (& namespace -> sem );
966- expire_mount (mnt , mounts );
983+ expire_mount (mnt , mounts , & umounts );
967984 up_write (& namespace -> sem );
968-
985+ release_mounts ( & umounts );
969986 mntput (mnt );
970987 put_namespace (namespace );
971-
972988 spin_lock (& vfsmount_lock );
973989 }
974990
@@ -1508,12 +1524,14 @@ void __init mnt_init(unsigned long mempages)
15081524void __put_namespace (struct namespace * namespace )
15091525{
15101526 struct vfsmount * root = namespace -> root ;
1527+ LIST_HEAD (umount_list );
15111528 namespace -> root = NULL ;
15121529 spin_unlock (& vfsmount_lock );
15131530 down_write (& namespace -> sem );
15141531 spin_lock (& vfsmount_lock );
1515- umount_tree (root );
1532+ umount_tree (root , & umount_list );
15161533 spin_unlock (& vfsmount_lock );
15171534 up_write (& namespace -> sem );
1535+ release_mounts (& umount_list );
15181536 kfree (namespace );
15191537}
0 commit comments