diff options
-rw-r--r-- | fs/namespace.c | 26 | ||||
-rw-r--r-- | fs/super.c | 6 |
2 files changed, 26 insertions, 6 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); | |||
42 | static int event; | 42 | static int event; |
43 | static DEFINE_IDA(mnt_id_ida); | 43 | static DEFINE_IDA(mnt_id_ida); |
44 | static DEFINE_IDA(mnt_group_ida); | 44 | static DEFINE_IDA(mnt_group_ida); |
45 | static int mnt_id_start = 0; | ||
46 | static int mnt_group_start = 1; | ||
45 | 47 | ||
46 | static struct list_head *mount_hashtable __read_mostly; | 48 | static struct list_head *mount_hashtable __read_mostly; |
47 | static struct kmem_cache *mnt_cache __read_mostly; | 49 | static struct kmem_cache *mnt_cache __read_mostly; |
@@ -69,7 +71,9 @@ static int mnt_alloc_id(struct vfsmount *mnt) | |||
69 | retry: | 71 | retry: |
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 | ||
80 | static void mnt_free_id(struct vfsmount *mnt) | 84 | static 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 | */ |
92 | static int mnt_alloc_group_id(struct vfsmount *mnt) | 99 | static 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 | */ |
103 | void mnt_release_group_id(struct vfsmount *mnt) | 118 | void 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 | ||
diff --git a/fs/super.c b/fs/super.c index 808ffd59e01b..2761d3e22ed9 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -620,7 +620,8 @@ int set_anon_super(struct super_block *s, void *data) | |||
620 | return -ENOMEM; | 620 | return -ENOMEM; |
621 | spin_lock(&unnamed_dev_lock); | 621 | spin_lock(&unnamed_dev_lock); |
622 | error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev); | 622 | error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev); |
623 | unnamed_dev_start = dev + 1; | 623 | if (!error) |
624 | unnamed_dev_start = dev + 1; | ||
624 | spin_unlock(&unnamed_dev_lock); | 625 | spin_unlock(&unnamed_dev_lock); |
625 | if (error == -EAGAIN) | 626 | if (error == -EAGAIN) |
626 | /* We raced and lost with another CPU. */ | 627 | /* We raced and lost with another CPU. */ |
@@ -631,7 +632,8 @@ int set_anon_super(struct super_block *s, void *data) | |||
631 | if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) { | 632 | if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) { |
632 | spin_lock(&unnamed_dev_lock); | 633 | spin_lock(&unnamed_dev_lock); |
633 | ida_remove(&unnamed_dev_ida, dev); | 634 | ida_remove(&unnamed_dev_ida, dev); |
634 | unnamed_dev_start = dev; | 635 | if (unnamed_dev_start > dev) |
636 | unnamed_dev_start = dev; | ||
635 | spin_unlock(&unnamed_dev_lock); | 637 | spin_unlock(&unnamed_dev_lock); |
636 | return -EMFILE; | 638 | return -EMFILE; |
637 | } | 639 | } |