aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 4a86b8595164..3dc283fd4716 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -42,6 +42,8 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
42static int event; 42static int event;
43static DEFINE_IDA(mnt_id_ida); 43static DEFINE_IDA(mnt_id_ida);
44static DEFINE_IDA(mnt_group_ida); 44static DEFINE_IDA(mnt_group_ida);
45static int mnt_id_start = 0;
46static int mnt_group_start = 1;
45 47
46static struct list_head *mount_hashtable __read_mostly; 48static struct list_head *mount_hashtable __read_mostly;
47static struct kmem_cache *mnt_cache __read_mostly; 49static struct kmem_cache *mnt_cache __read_mostly;
@@ -69,7 +71,9 @@ static int mnt_alloc_id(struct vfsmount *mnt)
69retry: 71retry:
70 ida_pre_get(&mnt_id_ida, GFP_KERNEL); 72 ida_pre_get(&mnt_id_ida, GFP_KERNEL);
71 spin_lock(&vfsmount_lock); 73 spin_lock(&vfsmount_lock);
72 res = ida_get_new(&mnt_id_ida, &mnt->mnt_id); 74 res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
75 if (!res)
76 mnt_id_start = mnt->mnt_id + 1;
73 spin_unlock(&vfsmount_lock); 77 spin_unlock(&vfsmount_lock);
74 if (res == -EAGAIN) 78 if (res == -EAGAIN)
75 goto retry; 79 goto retry;
@@ -79,8 +83,11 @@ retry:
79 83
80static void mnt_free_id(struct vfsmount *mnt) 84static void mnt_free_id(struct vfsmount *mnt)
81{ 85{
86 int id = mnt->mnt_id;
82 spin_lock(&vfsmount_lock); 87 spin_lock(&vfsmount_lock);
83 ida_remove(&mnt_id_ida, mnt->mnt_id); 88 ida_remove(&mnt_id_ida, id);
89 if (mnt_id_start > id)
90 mnt_id_start = id;
84 spin_unlock(&vfsmount_lock); 91 spin_unlock(&vfsmount_lock);
85} 92}
86 93
@@ -91,10 +98,18 @@ static void mnt_free_id(struct vfsmount *mnt)
91 */ 98 */
92static int mnt_alloc_group_id(struct vfsmount *mnt) 99static int mnt_alloc_group_id(struct vfsmount *mnt)
93{ 100{
101 int res;
102
94 if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) 103 if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL))
95 return -ENOMEM; 104 return -ENOMEM;
96 105
97 return ida_get_new_above(&mnt_group_ida, 1, &mnt->mnt_group_id); 106 res = ida_get_new_above(&mnt_group_ida,
107 mnt_group_start,
108 &mnt->mnt_group_id);
109 if (!res)
110 mnt_group_start = mnt->mnt_group_id + 1;
111
112 return res;
98} 113}
99 114
100/* 115/*
@@ -102,7 +117,10 @@ static int mnt_alloc_group_id(struct vfsmount *mnt)
102 */ 117 */
103void mnt_release_group_id(struct vfsmount *mnt) 118void mnt_release_group_id(struct vfsmount *mnt)
104{ 119{
105 ida_remove(&mnt_group_ida, mnt->mnt_group_id); 120 int id = mnt->mnt_group_id;
121 ida_remove(&mnt_group_ida, id);
122 if (mnt_group_start > id)
123 mnt_group_start = id;
106 mnt->mnt_group_id = 0; 124 mnt->mnt_group_id = 0;
107} 125}
108 126