diff options
Diffstat (limited to 'fs/namespace.c')
| -rw-r--r-- | fs/namespace.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index a7bea8c8bd46..277c28a63ead 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
| 23 | #include <linux/mnt_namespace.h> | 23 | #include <linux/mnt_namespace.h> |
| 24 | #include <linux/namei.h> | 24 | #include <linux/namei.h> |
| 25 | #include <linux/nsproxy.h> | ||
| 25 | #include <linux/security.h> | 26 | #include <linux/security.h> |
| 26 | #include <linux/mount.h> | 27 | #include <linux/mount.h> |
| 27 | #include <linux/ramfs.h> | 28 | #include <linux/ramfs.h> |
| @@ -42,6 +43,8 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); | |||
| 42 | static int event; | 43 | static int event; |
| 43 | static DEFINE_IDA(mnt_id_ida); | 44 | static DEFINE_IDA(mnt_id_ida); |
| 44 | static DEFINE_IDA(mnt_group_ida); | 45 | static DEFINE_IDA(mnt_group_ida); |
| 46 | static int mnt_id_start = 0; | ||
| 47 | static int mnt_group_start = 1; | ||
| 45 | 48 | ||
| 46 | static struct list_head *mount_hashtable __read_mostly; | 49 | static struct list_head *mount_hashtable __read_mostly; |
| 47 | static struct kmem_cache *mnt_cache __read_mostly; | 50 | static struct kmem_cache *mnt_cache __read_mostly; |
| @@ -69,7 +72,9 @@ static int mnt_alloc_id(struct vfsmount *mnt) | |||
| 69 | retry: | 72 | retry: |
| 70 | ida_pre_get(&mnt_id_ida, GFP_KERNEL); | 73 | ida_pre_get(&mnt_id_ida, GFP_KERNEL); |
| 71 | spin_lock(&vfsmount_lock); | 74 | spin_lock(&vfsmount_lock); |
| 72 | res = ida_get_new(&mnt_id_ida, &mnt->mnt_id); | 75 | res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id); |
| 76 | if (!res) | ||
| 77 | mnt_id_start = mnt->mnt_id + 1; | ||
| 73 | spin_unlock(&vfsmount_lock); | 78 | spin_unlock(&vfsmount_lock); |
| 74 | if (res == -EAGAIN) | 79 | if (res == -EAGAIN) |
| 75 | goto retry; | 80 | goto retry; |
| @@ -79,8 +84,11 @@ retry: | |||
| 79 | 84 | ||
| 80 | static void mnt_free_id(struct vfsmount *mnt) | 85 | static void mnt_free_id(struct vfsmount *mnt) |
| 81 | { | 86 | { |
| 87 | int id = mnt->mnt_id; | ||
| 82 | spin_lock(&vfsmount_lock); | 88 | spin_lock(&vfsmount_lock); |
| 83 | ida_remove(&mnt_id_ida, mnt->mnt_id); | 89 | ida_remove(&mnt_id_ida, id); |
| 90 | if (mnt_id_start > id) | ||
| 91 | mnt_id_start = id; | ||
| 84 | spin_unlock(&vfsmount_lock); | 92 | spin_unlock(&vfsmount_lock); |
| 85 | } | 93 | } |
| 86 | 94 | ||
| @@ -91,10 +99,18 @@ static void mnt_free_id(struct vfsmount *mnt) | |||
| 91 | */ | 99 | */ |
| 92 | static int mnt_alloc_group_id(struct vfsmount *mnt) | 100 | static int mnt_alloc_group_id(struct vfsmount *mnt) |
| 93 | { | 101 | { |
| 102 | int res; | ||
| 103 | |||
| 94 | if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) | 104 | if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) |
| 95 | return -ENOMEM; | 105 | return -ENOMEM; |
| 96 | 106 | ||
| 97 | return ida_get_new_above(&mnt_group_ida, 1, &mnt->mnt_group_id); | 107 | res = ida_get_new_above(&mnt_group_ida, |
| 108 | mnt_group_start, | ||
| 109 | &mnt->mnt_group_id); | ||
| 110 | if (!res) | ||
| 111 | mnt_group_start = mnt->mnt_group_id + 1; | ||
| 112 | |||
| 113 | return res; | ||
| 98 | } | 114 | } |
| 99 | 115 | ||
| 100 | /* | 116 | /* |
| @@ -102,7 +118,10 @@ static int mnt_alloc_group_id(struct vfsmount *mnt) | |||
| 102 | */ | 118 | */ |
| 103 | void mnt_release_group_id(struct vfsmount *mnt) | 119 | void mnt_release_group_id(struct vfsmount *mnt) |
| 104 | { | 120 | { |
| 105 | ida_remove(&mnt_group_ida, mnt->mnt_group_id); | 121 | int id = mnt->mnt_group_id; |
| 122 | ida_remove(&mnt_group_ida, id); | ||
| 123 | if (mnt_group_start > id) | ||
| 124 | mnt_group_start = id; | ||
| 106 | mnt->mnt_group_id = 0; | 125 | mnt->mnt_group_id = 0; |
| 107 | } | 126 | } |
| 108 | 127 | ||
| @@ -2222,16 +2241,9 @@ static void __init init_mount_tree(void) | |||
| 2222 | mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); | 2241 | mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); |
| 2223 | if (IS_ERR(mnt)) | 2242 | if (IS_ERR(mnt)) |
| 2224 | panic("Can't create rootfs"); | 2243 | panic("Can't create rootfs"); |
| 2225 | ns = kmalloc(sizeof(*ns), GFP_KERNEL); | 2244 | ns = create_mnt_ns(mnt); |
| 2226 | if (!ns) | 2245 | if (IS_ERR(ns)) |
| 2227 | panic("Can't allocate initial namespace"); | 2246 | panic("Can't allocate initial namespace"); |
| 2228 | atomic_set(&ns->count, 1); | ||
| 2229 | INIT_LIST_HEAD(&ns->list); | ||
| 2230 | init_waitqueue_head(&ns->poll); | ||
| 2231 | ns->event = 0; | ||
| 2232 | list_add(&mnt->mnt_list, &ns->list); | ||
| 2233 | ns->root = mnt; | ||
| 2234 | mnt->mnt_ns = ns; | ||
| 2235 | 2247 | ||
| 2236 | init_task.nsproxy->mnt_ns = ns; | 2248 | init_task.nsproxy->mnt_ns = ns; |
| 2237 | get_mnt_ns(ns); | 2249 | get_mnt_ns(ns); |
