···1210121012111211EXPORT_SYMBOL_GPL(do_add_mount);1212121212131213-static void expire_mount(struct vfsmount *mnt, struct list_head *mounts,12141214- struct list_head *umounts)12151215-{12161216- spin_lock(&vfsmount_lock);12171217-12181218- /*12191219- * Check if mount is still attached, if not, let whoever holds it deal12201220- * with the sucker12211221- */12221222- if (mnt->mnt_parent == mnt) {12231223- spin_unlock(&vfsmount_lock);12241224- return;12251225- }12261226-12271227- /*12281228- * Check that it is still dead: the count should now be 2 - as12291229- * contributed by the vfsmount parent and the mntget above12301230- */12311231- if (!propagate_mount_busy(mnt, 2)) {12321232- /* delete from the namespace */12331233- touch_mnt_namespace(mnt->mnt_ns);12341234- list_del_init(&mnt->mnt_list);12351235- mnt->mnt_ns = NULL;12361236- umount_tree(mnt, 1, umounts);12371237- spin_unlock(&vfsmount_lock);12381238- } else {12391239- /*12401240- * Someone brought it back to life whilst we didn't have any12411241- * locks held so return it to the expiration list12421242- */12431243- list_add_tail(&mnt->mnt_expire, mounts);12441244- spin_unlock(&vfsmount_lock);12451245- }12461246-}12471247-12481248-/*12491249- * go through the vfsmounts we've just consigned to the graveyard to12501250- * - check that they're still dead12511251- * - delete the vfsmount from the appropriate namespace under lock12521252- * - dispose of the corpse12531253- */12541254-static void expire_mount_list(struct list_head *graveyard, struct list_head *mounts)12551255-{12561256- struct mnt_namespace *ns;12571257- struct vfsmount *mnt;12581258-12591259- while (!list_empty(graveyard)) {12601260- LIST_HEAD(umounts);12611261- mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire);12621262- list_del_init(&mnt->mnt_expire);12631263-12641264- /* don't do anything if the namespace is dead - all the12651265- * vfsmounts from it are going away anyway */12661266- ns = mnt->mnt_ns;12671267- if (!ns || !ns->root)12681268- continue;12691269- get_mnt_ns(ns);12701270-12711271- spin_unlock(&vfsmount_lock);12721272- down_write(&namespace_sem);12731273- expire_mount(mnt, mounts, &umounts);12741274- up_write(&namespace_sem);12751275- release_mounts(&umounts);12761276- mntput(mnt);12771277- put_mnt_ns(ns);12781278- spin_lock(&vfsmount_lock);12791279- }12801280-}12811281-12821213/*12831214 * process a list of expirable mountpoints with the intent of discarding any12841215 * mountpoints that aren't in use and haven't been touched since last we came···12191288{12201289 struct vfsmount *mnt, *next;12211290 LIST_HEAD(graveyard);12911291+ LIST_HEAD(umounts);1222129212231293 if (list_empty(mounts))12241294 return;1225129512961296+ down_write(&namespace_sem);12261297 spin_lock(&vfsmount_lock);1227129812281299 /* extract from the expiration list every vfsmount that matches the···12351302 */12361303 list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {12371304 if (!xchg(&mnt->mnt_expiry_mark, 1) ||12381238- atomic_read(&mnt->mnt_count) != 1)13051305+ propagate_mount_busy(mnt, 1))12391306 continue;12401240-12411241- mntget(mnt);12421307 list_move(&mnt->mnt_expire, &graveyard);12431308 }12441244-12451245- expire_mount_list(&graveyard, mounts);12461246-13091309+ while (!list_empty(&graveyard)) {13101310+ mnt = list_first_entry(&graveyard, struct vfsmount, mnt_expire);13111311+ touch_mnt_namespace(mnt->mnt_ns);13121312+ umount_tree(mnt, 1, &umounts);13131313+ }12471314 spin_unlock(&vfsmount_lock);13151315+ up_write(&namespace_sem);13161316+13171317+ release_mounts(&umounts);12481318}1249131912501320EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);···12831347 }1284134812851349 if (!propagate_mount_busy(mnt, 1)) {12861286- mntget(mnt);12871350 list_move_tail(&mnt->mnt_expire, graveyard);12881351 found++;12891352 }···13051370void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts)13061371{13071372 LIST_HEAD(graveyard);13081308- int found;13731373+ LIST_HEAD(umounts);13741374+ struct vfsmount *mnt;1309137513761376+ down_write(&namespace_sem);13101377 spin_lock(&vfsmount_lock);13111311-13121378 /* extract submounts of 'mountpoint' from the expiration list */13131313- while ((found = select_submounts(mountpoint, &graveyard)) != 0)13141314- expire_mount_list(&graveyard, mounts);13151315-13791379+ while (select_submounts(mountpoint, &graveyard)) {13801380+ while (!list_empty(&graveyard)) {13811381+ mnt = list_first_entry(&graveyard, struct vfsmount,13821382+ mnt_expire);13831383+ touch_mnt_namespace(mnt->mnt_ns);13841384+ umount_tree(mnt, 1, &umounts);13851385+ }13861386+ }13161387 spin_unlock(&vfsmount_lock);13881388+ up_write(&namespace_sem);13891389+ release_mounts(&umounts);13171390}1318139113191392EXPORT_SYMBOL_GPL(shrink_submounts);