diff options
Diffstat (limited to 'fs/devpts/inode.c')
-rw-r--r-- | fs/devpts/inode.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index f120e1207874..285b64a8b06e 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
18 | #include <linux/mount.h> | 18 | #include <linux/mount.h> |
19 | #include <linux/tty.h> | 19 | #include <linux/tty.h> |
20 | #include <linux/mutex.h> | ||
21 | #include <linux/idr.h> | ||
20 | #include <linux/devpts_fs.h> | 22 | #include <linux/devpts_fs.h> |
21 | #include <linux/parser.h> | 23 | #include <linux/parser.h> |
22 | #include <linux/fsnotify.h> | 24 | #include <linux/fsnotify.h> |
@@ -26,6 +28,10 @@ | |||
26 | 28 | ||
27 | #define DEVPTS_DEFAULT_MODE 0600 | 29 | #define DEVPTS_DEFAULT_MODE 0600 |
28 | 30 | ||
31 | extern int pty_limit; /* Config limit on Unix98 ptys */ | ||
32 | static DEFINE_IDR(allocated_ptys); | ||
33 | static DEFINE_MUTEX(allocated_ptys_lock); | ||
34 | |||
29 | static struct vfsmount *devpts_mnt; | 35 | static struct vfsmount *devpts_mnt; |
30 | static struct dentry *devpts_root; | 36 | static struct dentry *devpts_root; |
31 | 37 | ||
@@ -171,9 +177,44 @@ static struct dentry *get_node(int num) | |||
171 | return lookup_one_len(s, root, sprintf(s, "%d", num)); | 177 | return lookup_one_len(s, root, sprintf(s, "%d", num)); |
172 | } | 178 | } |
173 | 179 | ||
180 | int devpts_new_index(void) | ||
181 | { | ||
182 | int index; | ||
183 | int idr_ret; | ||
184 | |||
185 | retry: | ||
186 | if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) { | ||
187 | return -ENOMEM; | ||
188 | } | ||
189 | |||
190 | mutex_lock(&allocated_ptys_lock); | ||
191 | idr_ret = idr_get_new(&allocated_ptys, NULL, &index); | ||
192 | if (idr_ret < 0) { | ||
193 | mutex_unlock(&allocated_ptys_lock); | ||
194 | if (idr_ret == -EAGAIN) | ||
195 | goto retry; | ||
196 | return -EIO; | ||
197 | } | ||
198 | |||
199 | if (index >= pty_limit) { | ||
200 | idr_remove(&allocated_ptys, index); | ||
201 | mutex_unlock(&allocated_ptys_lock); | ||
202 | return -EIO; | ||
203 | } | ||
204 | mutex_unlock(&allocated_ptys_lock); | ||
205 | return index; | ||
206 | } | ||
207 | |||
208 | void devpts_kill_index(int idx) | ||
209 | { | ||
210 | mutex_lock(&allocated_ptys_lock); | ||
211 | idr_remove(&allocated_ptys, idx); | ||
212 | mutex_unlock(&allocated_ptys_lock); | ||
213 | } | ||
214 | |||
174 | int devpts_pty_new(struct tty_struct *tty) | 215 | int devpts_pty_new(struct tty_struct *tty) |
175 | { | 216 | { |
176 | int number = tty->index; | 217 | int number = tty->index; /* tty layer puts index from devpts_new_index() in here */ |
177 | struct tty_driver *driver = tty->driver; | 218 | struct tty_driver *driver = tty->driver; |
178 | dev_t device = MKDEV(driver->major, driver->minor_start+number); | 219 | dev_t device = MKDEV(driver->major, driver->minor_start+number); |
179 | struct dentry *dentry; | 220 | struct dentry *dentry; |