aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c142
1 files changed, 74 insertions, 68 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 208c079e9fdb..2fa9fdf7d6f5 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -40,7 +40,7 @@ static inline int sysfs_init(void)
40 __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); 40 __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
41 41
42static struct list_head *mount_hashtable; 42static struct list_head *mount_hashtable;
43static int hash_mask, hash_bits; 43static int hash_mask __read_mostly, hash_bits __read_mostly;
44static kmem_cache_t *mnt_cache; 44static kmem_cache_t *mnt_cache;
45 45
46static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) 46static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
@@ -61,7 +61,7 @@ struct vfsmount *alloc_vfsmnt(const char *name)
61 INIT_LIST_HEAD(&mnt->mnt_child); 61 INIT_LIST_HEAD(&mnt->mnt_child);
62 INIT_LIST_HEAD(&mnt->mnt_mounts); 62 INIT_LIST_HEAD(&mnt->mnt_mounts);
63 INIT_LIST_HEAD(&mnt->mnt_list); 63 INIT_LIST_HEAD(&mnt->mnt_list);
64 INIT_LIST_HEAD(&mnt->mnt_fslink); 64 INIT_LIST_HEAD(&mnt->mnt_expire);
65 if (name) { 65 if (name) {
66 int size = strlen(name)+1; 66 int size = strlen(name)+1;
67 char *newname = kmalloc(size, GFP_KERNEL); 67 char *newname = kmalloc(size, GFP_KERNEL);
@@ -160,13 +160,13 @@ clone_mnt(struct vfsmount *old, struct dentry *root)
160 mnt->mnt_root = dget(root); 160 mnt->mnt_root = dget(root);
161 mnt->mnt_mountpoint = mnt->mnt_root; 161 mnt->mnt_mountpoint = mnt->mnt_root;
162 mnt->mnt_parent = mnt; 162 mnt->mnt_parent = mnt;
163 mnt->mnt_namespace = old->mnt_namespace; 163 mnt->mnt_namespace = current->namespace;
164 164
165 /* stick the duplicate mount on the same expiry list 165 /* stick the duplicate mount on the same expiry list
166 * as the original if that was on one */ 166 * as the original if that was on one */
167 spin_lock(&vfsmount_lock); 167 spin_lock(&vfsmount_lock);
168 if (!list_empty(&old->mnt_fslink)) 168 if (!list_empty(&old->mnt_expire))
169 list_add(&mnt->mnt_fslink, &old->mnt_fslink); 169 list_add(&mnt->mnt_expire, &old->mnt_expire);
170 spin_unlock(&vfsmount_lock); 170 spin_unlock(&vfsmount_lock);
171 } 171 }
172 return mnt; 172 return mnt;
@@ -345,12 +345,13 @@ static void umount_tree(struct vfsmount *mnt)
345 for (p = mnt; p; p = next_mnt(p, mnt)) { 345 for (p = mnt; p; p = next_mnt(p, mnt)) {
346 list_del(&p->mnt_list); 346 list_del(&p->mnt_list);
347 list_add(&p->mnt_list, &kill); 347 list_add(&p->mnt_list, &kill);
348 p->mnt_namespace = NULL;
348 } 349 }
349 350
350 while (!list_empty(&kill)) { 351 while (!list_empty(&kill)) {
351 mnt = list_entry(kill.next, struct vfsmount, mnt_list); 352 mnt = list_entry(kill.next, struct vfsmount, mnt_list);
352 list_del_init(&mnt->mnt_list); 353 list_del_init(&mnt->mnt_list);
353 list_del_init(&mnt->mnt_fslink); 354 list_del_init(&mnt->mnt_expire);
354 if (mnt->mnt_parent == mnt) { 355 if (mnt->mnt_parent == mnt) {
355 spin_unlock(&vfsmount_lock); 356 spin_unlock(&vfsmount_lock);
356 } else { 357 } else {
@@ -536,7 +537,6 @@ lives_below_in_same_fs(struct dentry *d, struct dentry *dentry)
536static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry) 537static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
537{ 538{
538 struct vfsmount *res, *p, *q, *r, *s; 539 struct vfsmount *res, *p, *q, *r, *s;
539 struct list_head *h;
540 struct nameidata nd; 540 struct nameidata nd;
541 541
542 res = q = clone_mnt(mnt, dentry); 542 res = q = clone_mnt(mnt, dentry);
@@ -545,8 +545,7 @@ static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
545 q->mnt_mountpoint = mnt->mnt_mountpoint; 545 q->mnt_mountpoint = mnt->mnt_mountpoint;
546 546
547 p = mnt; 547 p = mnt;
548 for (h = mnt->mnt_mounts.next; h != &mnt->mnt_mounts; h = h->next) { 548 list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
549 r = list_entry(h, struct vfsmount, mnt_child);
550 if (!lives_below_in_same_fs(r->mnt_mountpoint, dentry)) 549 if (!lives_below_in_same_fs(r->mnt_mountpoint, dentry))
551 continue; 550 continue;
552 551
@@ -644,7 +643,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
644 if (mnt) { 643 if (mnt) {
645 /* stop bind mounts from expiring */ 644 /* stop bind mounts from expiring */
646 spin_lock(&vfsmount_lock); 645 spin_lock(&vfsmount_lock);
647 list_del_init(&mnt->mnt_fslink); 646 list_del_init(&mnt->mnt_expire);
648 spin_unlock(&vfsmount_lock); 647 spin_unlock(&vfsmount_lock);
649 648
650 err = graft_tree(mnt, nd); 649 err = graft_tree(mnt, nd);
@@ -743,7 +742,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
743 742
744 /* if the mount is moved, it should no longer be expire 743 /* if the mount is moved, it should no longer be expire
745 * automatically */ 744 * automatically */
746 list_del_init(&old_nd.mnt->mnt_fslink); 745 list_del_init(&old_nd.mnt->mnt_expire);
747out2: 746out2:
748 spin_unlock(&vfsmount_lock); 747 spin_unlock(&vfsmount_lock);
749out1: 748out1:
@@ -807,12 +806,13 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
807 goto unlock; 806 goto unlock;
808 807
809 newmnt->mnt_flags = mnt_flags; 808 newmnt->mnt_flags = mnt_flags;
809 newmnt->mnt_namespace = current->namespace;
810 err = graft_tree(newmnt, nd); 810 err = graft_tree(newmnt, nd);
811 811
812 if (err == 0 && fslist) { 812 if (err == 0 && fslist) {
813 /* add to the specified expiration list */ 813 /* add to the specified expiration list */
814 spin_lock(&vfsmount_lock); 814 spin_lock(&vfsmount_lock);
815 list_add_tail(&newmnt->mnt_fslink, fslist); 815 list_add_tail(&newmnt->mnt_expire, fslist);
816 spin_unlock(&vfsmount_lock); 816 spin_unlock(&vfsmount_lock);
817 } 817 }
818 818
@@ -824,6 +824,54 @@ unlock:
824 824
825EXPORT_SYMBOL_GPL(do_add_mount); 825EXPORT_SYMBOL_GPL(do_add_mount);
826 826
827static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
828{
829 spin_lock(&vfsmount_lock);
830
831 /*
832 * Check if mount is still attached, if not, let whoever holds it deal
833 * with the sucker
834 */
835 if (mnt->mnt_parent == mnt) {
836 spin_unlock(&vfsmount_lock);
837 return;
838 }
839
840 /*
841 * Check that it is still dead: the count should now be 2 - as
842 * contributed by the vfsmount parent and the mntget above
843 */
844 if (atomic_read(&mnt->mnt_count) == 2) {
845 struct nameidata old_nd;
846
847 /* delete from the namespace */
848 list_del_init(&mnt->mnt_list);
849 mnt->mnt_namespace = NULL;
850 detach_mnt(mnt, &old_nd);
851 spin_unlock(&vfsmount_lock);
852 path_release(&old_nd);
853
854 /*
855 * Now lay it to rest if this was the last ref on the superblock
856 */
857 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
858 /* last instance - try to be smart */
859 lock_kernel();
860 DQUOT_OFF(mnt->mnt_sb);
861 acct_auto_close(mnt->mnt_sb);
862 unlock_kernel();
863 }
864 mntput(mnt);
865 } else {
866 /*
867 * Someone brought it back to life whilst we didn't have any
868 * locks held so return it to the expiration list
869 */
870 list_add_tail(&mnt->mnt_expire, mounts);
871 spin_unlock(&vfsmount_lock);
872 }
873}
874
827/* 875/*
828 * process a list of expirable mountpoints with the intent of discarding any 876 * process a list of expirable mountpoints with the intent of discarding any
829 * mountpoints that aren't in use and haven't been touched since last we came 877 * mountpoints that aren't in use and haven't been touched since last we came
@@ -846,13 +894,13 @@ void mark_mounts_for_expiry(struct list_head *mounts)
846 * - still marked for expiry (marked on the last call here; marks are 894 * - still marked for expiry (marked on the last call here; marks are
847 * cleared by mntput()) 895 * cleared by mntput())
848 */ 896 */
849 list_for_each_entry_safe(mnt, next, mounts, mnt_fslink) { 897 list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
850 if (!xchg(&mnt->mnt_expiry_mark, 1) || 898 if (!xchg(&mnt->mnt_expiry_mark, 1) ||
851 atomic_read(&mnt->mnt_count) != 1) 899 atomic_read(&mnt->mnt_count) != 1)
852 continue; 900 continue;
853 901
854 mntget(mnt); 902 mntget(mnt);
855 list_move(&mnt->mnt_fslink, &graveyard); 903 list_move(&mnt->mnt_expire, &graveyard);
856 } 904 }
857 905
858 /* 906 /*
@@ -862,61 +910,19 @@ void mark_mounts_for_expiry(struct list_head *mounts)
862 * - dispose of the corpse 910 * - dispose of the corpse
863 */ 911 */
864 while (!list_empty(&graveyard)) { 912 while (!list_empty(&graveyard)) {
865 mnt = list_entry(graveyard.next, struct vfsmount, mnt_fslink); 913 mnt = list_entry(graveyard.next, struct vfsmount, mnt_expire);
866 list_del_init(&mnt->mnt_fslink); 914 list_del_init(&mnt->mnt_expire);
867 915
868 /* don't do anything if the namespace is dead - all the 916 /* don't do anything if the namespace is dead - all the
869 * vfsmounts from it are going away anyway */ 917 * vfsmounts from it are going away anyway */
870 namespace = mnt->mnt_namespace; 918 namespace = mnt->mnt_namespace;
871 if (!namespace || atomic_read(&namespace->count) <= 0) 919 if (!namespace || !namespace->root)
872 continue; 920 continue;
873 get_namespace(namespace); 921 get_namespace(namespace);
874 922
875 spin_unlock(&vfsmount_lock); 923 spin_unlock(&vfsmount_lock);
876 down_write(&namespace->sem); 924 down_write(&namespace->sem);
877 spin_lock(&vfsmount_lock); 925 expire_mount(mnt, mounts);
878
879 /* check that it is still dead: the count should now be 2 - as
880 * contributed by the vfsmount parent and the mntget above */
881 if (atomic_read(&mnt->mnt_count) == 2) {
882 struct vfsmount *xdmnt;
883 struct dentry *xdentry;
884
885 /* delete from the namespace */
886 list_del_init(&mnt->mnt_list);
887 list_del_init(&mnt->mnt_child);
888 list_del_init(&mnt->mnt_hash);
889 mnt->mnt_mountpoint->d_mounted--;
890
891 xdentry = mnt->mnt_mountpoint;
892 mnt->mnt_mountpoint = mnt->mnt_root;
893 xdmnt = mnt->mnt_parent;
894 mnt->mnt_parent = mnt;
895
896 spin_unlock(&vfsmount_lock);
897
898 mntput(xdmnt);
899 dput(xdentry);
900
901 /* now lay it to rest if this was the last ref on the
902 * superblock */
903 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
904 /* last instance - try to be smart */
905 lock_kernel();
906 DQUOT_OFF(mnt->mnt_sb);
907 acct_auto_close(mnt->mnt_sb);
908 unlock_kernel();
909 }
910
911 mntput(mnt);
912 } else {
913 /* someone brought it back to life whilst we didn't
914 * have any locks held so return it to the expiration
915 * list */
916 list_add_tail(&mnt->mnt_fslink, mounts);
917 spin_unlock(&vfsmount_lock);
918 }
919
920 up_write(&namespace->sem); 926 up_write(&namespace->sem);
921 927
922 mntput(mnt); 928 mntput(mnt);
@@ -1326,8 +1332,12 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
1326 error = -EINVAL; 1332 error = -EINVAL;
1327 if (user_nd.mnt->mnt_root != user_nd.dentry) 1333 if (user_nd.mnt->mnt_root != user_nd.dentry)
1328 goto out2; /* not a mountpoint */ 1334 goto out2; /* not a mountpoint */
1335 if (user_nd.mnt->mnt_parent == user_nd.mnt)
1336 goto out2; /* not attached */
1329 if (new_nd.mnt->mnt_root != new_nd.dentry) 1337 if (new_nd.mnt->mnt_root != new_nd.dentry)
1330 goto out2; /* not a mountpoint */ 1338 goto out2; /* not a mountpoint */
1339 if (new_nd.mnt->mnt_parent == new_nd.mnt)
1340 goto out2; /* not attached */
1331 tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */ 1341 tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
1332 spin_lock(&vfsmount_lock); 1342 spin_lock(&vfsmount_lock);
1333 if (tmp != new_nd.mnt) { 1343 if (tmp != new_nd.mnt) {
@@ -1449,16 +1459,12 @@ void __init mnt_init(unsigned long mempages)
1449 1459
1450void __put_namespace(struct namespace *namespace) 1460void __put_namespace(struct namespace *namespace)
1451{ 1461{
1452 struct vfsmount *mnt; 1462 struct vfsmount *root = namespace->root;
1453 1463 namespace->root = NULL;
1464 spin_unlock(&vfsmount_lock);
1454 down_write(&namespace->sem); 1465 down_write(&namespace->sem);
1455 spin_lock(&vfsmount_lock); 1466 spin_lock(&vfsmount_lock);
1456 1467 umount_tree(root);
1457 list_for_each_entry(mnt, &namespace->list, mnt_list) {
1458 mnt->mnt_namespace = NULL;
1459 }
1460
1461 umount_tree(namespace->root);
1462 spin_unlock(&vfsmount_lock); 1468 spin_unlock(&vfsmount_lock);
1463 up_write(&namespace->sem); 1469 up_write(&namespace->sem);
1464 kfree(namespace); 1470 kfree(namespace);