aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index ea555a36c314..d82cf18a1a94 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -825,6 +825,44 @@ unlock:
825 825
826EXPORT_SYMBOL_GPL(do_add_mount); 826EXPORT_SYMBOL_GPL(do_add_mount);
827 827
828static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
829{
830 spin_lock(&vfsmount_lock);
831
832 /*
833 * Check that it is still dead: the count should now be 2 - as
834 * contributed by the vfsmount parent and the mntget above
835 */
836 if (atomic_read(&mnt->mnt_count) == 2) {
837 struct nameidata old_nd;
838
839 /* delete from the namespace */
840 list_del_init(&mnt->mnt_list);
841 detach_mnt(mnt, &old_nd);
842 spin_unlock(&vfsmount_lock);
843 path_release(&old_nd);
844
845 /*
846 * Now lay it to rest if this was the last ref on the superblock
847 */
848 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
849 /* last instance - try to be smart */
850 lock_kernel();
851 DQUOT_OFF(mnt->mnt_sb);
852 acct_auto_close(mnt->mnt_sb);
853 unlock_kernel();
854 }
855 mntput(mnt);
856 } else {
857 /*
858 * Someone brought it back to life whilst we didn't have any
859 * locks held so return it to the expiration list
860 */
861 list_add_tail(&mnt->mnt_fslink, mounts);
862 spin_unlock(&vfsmount_lock);
863 }
864}
865
828/* 866/*
829 * process a list of expirable mountpoints with the intent of discarding any 867 * process a list of expirable mountpoints with the intent of discarding any
830 * mountpoints that aren't in use and haven't been touched since last we came 868 * mountpoints that aren't in use and haven't been touched since last we came
@@ -875,38 +913,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
875 913
876 spin_unlock(&vfsmount_lock); 914 spin_unlock(&vfsmount_lock);
877 down_write(&namespace->sem); 915 down_write(&namespace->sem);
878 spin_lock(&vfsmount_lock); 916 expire_mount(mnt, mounts);
879
880 /* check that it is still dead: the count should now be 2 - as
881 * contributed by the vfsmount parent and the mntget above */
882 if (atomic_read(&mnt->mnt_count) == 2) {
883 struct nameidata old_nd;
884
885 /* delete from the namespace */
886 list_del_init(&mnt->mnt_list);
887 detach_mnt(mnt, &old_nd);
888 spin_unlock(&vfsmount_lock);
889 path_release(&old_nd);
890
891 /* now lay it to rest if this was the last ref on the
892 * superblock */
893 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
894 /* last instance - try to be smart */
895 lock_kernel();
896 DQUOT_OFF(mnt->mnt_sb);
897 acct_auto_close(mnt->mnt_sb);
898 unlock_kernel();
899 }
900
901 mntput(mnt);
902 } else {
903 /* someone brought it back to life whilst we didn't
904 * have any locks held so return it to the expiration
905 * list */
906 list_add_tail(&mnt->mnt_fslink, mounts);
907 spin_unlock(&vfsmount_lock);
908 }
909
910 up_write(&namespace->sem); 917 up_write(&namespace->sem);
911 918
912 mntput(mnt); 919 mntput(mnt);