aboutsummaryrefslogtreecommitdiffstats
path: root/fs/devpts
diff options
context:
space:
mode:
Diffstat (limited to 'fs/devpts')
-rw-r--r--fs/devpts/inode.c66
1 files changed, 30 insertions, 36 deletions
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 488eb424f662..a70d5d0890c7 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -27,6 +27,7 @@
27#define DEVPTS_SUPER_MAGIC 0x1cd1 27#define DEVPTS_SUPER_MAGIC 0x1cd1
28 28
29#define DEVPTS_DEFAULT_MODE 0600 29#define DEVPTS_DEFAULT_MODE 0600
30#define PTMX_MINOR 2
30 31
31extern int pty_limit; /* Config limit on Unix98 ptys */ 32extern int pty_limit; /* Config limit on Unix98 ptys */
32static DEFINE_IDA(allocated_ptys); 33static DEFINE_IDA(allocated_ptys);
@@ -169,15 +170,7 @@ static struct file_system_type devpts_fs_type = {
169 * to the System V naming convention 170 * to the System V naming convention
170 */ 171 */
171 172
172static struct dentry *get_node(int num) 173int devpts_new_index(struct inode *ptmx_inode)
173{
174 char s[12];
175 struct dentry *root = devpts_root;
176 mutex_lock(&root->d_inode->i_mutex);
177 return lookup_one_len(s, root, sprintf(s, "%d", num));
178}
179
180int devpts_new_index(void)
181{ 174{
182 int index; 175 int index;
183 int ida_ret; 176 int ida_ret;
@@ -205,20 +198,21 @@ retry:
205 return index; 198 return index;
206} 199}
207 200
208void devpts_kill_index(int idx) 201void devpts_kill_index(struct inode *ptmx_inode, int idx)
209{ 202{
210 mutex_lock(&allocated_ptys_lock); 203 mutex_lock(&allocated_ptys_lock);
211 ida_remove(&allocated_ptys, idx); 204 ida_remove(&allocated_ptys, idx);
212 mutex_unlock(&allocated_ptys_lock); 205 mutex_unlock(&allocated_ptys_lock);
213} 206}
214 207
215int devpts_pty_new(struct tty_struct *tty) 208int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
216{ 209{
217 int number = tty->index; /* tty layer puts index from devpts_new_index() in here */ 210 int number = tty->index; /* tty layer puts index from devpts_new_index() in here */
218 struct tty_driver *driver = tty->driver; 211 struct tty_driver *driver = tty->driver;
219 dev_t device = MKDEV(driver->major, driver->minor_start+number); 212 dev_t device = MKDEV(driver->major, driver->minor_start+number);
220 struct dentry *dentry; 213 struct dentry *dentry;
221 struct inode *inode = new_inode(devpts_mnt->mnt_sb); 214 struct inode *inode = new_inode(devpts_mnt->mnt_sb);
215 char s[12];
222 216
223 /* We're supposed to be given the slave end of a pty */ 217 /* We're supposed to be given the slave end of a pty */
224 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); 218 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
@@ -233,10 +227,15 @@ int devpts_pty_new(struct tty_struct *tty)
233 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 227 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
234 init_special_inode(inode, S_IFCHR|config.mode, device); 228 init_special_inode(inode, S_IFCHR|config.mode, device);
235 inode->i_private = tty; 229 inode->i_private = tty;
230 tty->driver_data = inode;
236 231
237 dentry = get_node(number); 232 sprintf(s, "%d", number);
238 if (!IS_ERR(dentry) && !dentry->d_inode) { 233
239 d_instantiate(dentry, inode); 234 mutex_lock(&devpts_root->d_inode->i_mutex);
235
236 dentry = d_alloc_name(devpts_root, s);
237 if (!IS_ERR(dentry)) {
238 d_add(dentry, inode);
240 fsnotify_create(devpts_root->d_inode, dentry); 239 fsnotify_create(devpts_root->d_inode, dentry);
241 } 240 }
242 241
@@ -245,36 +244,31 @@ int devpts_pty_new(struct tty_struct *tty)
245 return 0; 244 return 0;
246} 245}
247 246
248struct tty_struct *devpts_get_tty(int number) 247struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
249{ 248{
250 struct dentry *dentry = get_node(number); 249 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
251 struct tty_struct *tty;
252
253 tty = NULL;
254 if (!IS_ERR(dentry)) {
255 if (dentry->d_inode)
256 tty = dentry->d_inode->i_private;
257 dput(dentry);
258 }
259 250
260 mutex_unlock(&devpts_root->d_inode->i_mutex); 251 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
261 252 return (struct tty_struct *)pts_inode->i_private;
262 return tty; 253 return NULL;
263} 254}
264 255
265void devpts_pty_kill(int number) 256void devpts_pty_kill(struct tty_struct *tty)
266{ 257{
267 struct dentry *dentry = get_node(number); 258 struct inode *inode = tty->driver_data;
259 struct dentry *dentry;
268 260
269 if (!IS_ERR(dentry)) { 261 BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
270 struct inode *inode = dentry->d_inode; 262
271 if (inode) { 263 mutex_lock(&devpts_root->d_inode->i_mutex);
272 inode->i_nlink--; 264
273 d_delete(dentry); 265 dentry = d_find_alias(inode);
274 dput(dentry); 266 if (dentry && !IS_ERR(dentry)) {
275 } 267 inode->i_nlink--;
268 d_delete(dentry);
276 dput(dentry); 269 dput(dentry);
277 } 270 }
271
278 mutex_unlock(&devpts_root->d_inode->i_mutex); 272 mutex_unlock(&devpts_root->d_inode->i_mutex);
279} 273}
280 274