diff options
-rw-r--r-- | drivers/tty/pty.c | 10 | ||||
-rw-r--r-- | fs/devpts/inode.c | 21 | ||||
-rw-r--r-- | include/linux/devpts_fs.h | 9 |
3 files changed, 16 insertions, 24 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 9985b451e937..559e5b27941a 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -4,9 +4,6 @@ | |||
4 | * Added support for a Unix98-style ptmx device. | 4 | * Added support for a Unix98-style ptmx device. |
5 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 | 5 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 |
6 | * | 6 | * |
7 | * When reading this code see also fs/devpts. In particular note that the | ||
8 | * driver_data field is used by the devpts side as a binding to the devpts | ||
9 | * inode. | ||
10 | */ | 7 | */ |
11 | 8 | ||
12 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -59,7 +56,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
59 | #ifdef CONFIG_UNIX98_PTYS | 56 | #ifdef CONFIG_UNIX98_PTYS |
60 | if (tty->driver == ptm_driver) { | 57 | if (tty->driver == ptm_driver) { |
61 | mutex_lock(&devpts_mutex); | 58 | mutex_lock(&devpts_mutex); |
62 | devpts_pty_kill(tty->link); | 59 | devpts_pty_kill(tty->link->driver_data); |
63 | mutex_unlock(&devpts_mutex); | 60 | mutex_unlock(&devpts_mutex); |
64 | } | 61 | } |
65 | #endif | 62 | #endif |
@@ -651,7 +648,9 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
651 | 648 | ||
652 | tty_add_file(tty, filp); | 649 | tty_add_file(tty, filp); |
653 | 650 | ||
654 | slave_inode = devpts_pty_new(inode, tty->link); | 651 | slave_inode = devpts_pty_new(inode, |
652 | MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index, | ||
653 | tty->link); | ||
655 | if (IS_ERR(slave_inode)) { | 654 | if (IS_ERR(slave_inode)) { |
656 | retval = PTR_ERR(slave_inode); | 655 | retval = PTR_ERR(slave_inode); |
657 | goto err_release; | 656 | goto err_release; |
@@ -662,6 +661,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
662 | goto err_release; | 661 | goto err_release; |
663 | 662 | ||
664 | tty_unlock(tty); | 663 | tty_unlock(tty); |
664 | tty->link->driver_data = slave_inode; | ||
665 | return 0; | 665 | return 0; |
666 | err_release: | 666 | err_release: |
667 | tty_unlock(tty); | 667 | tty_unlock(tty); |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index ec3bab716c05..7a20d673bb8a 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -545,12 +545,9 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) | |||
545 | mutex_unlock(&allocated_ptys_lock); | 545 | mutex_unlock(&allocated_ptys_lock); |
546 | } | 546 | } |
547 | 547 | ||
548 | struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) | 548 | struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, |
549 | void *priv) | ||
549 | { | 550 | { |
550 | /* tty layer puts index from devpts_new_index() in here */ | ||
551 | int number = tty->index; | ||
552 | struct tty_driver *driver = tty->driver; | ||
553 | dev_t device = MKDEV(driver->major, driver->minor_start+number); | ||
554 | struct dentry *dentry; | 551 | struct dentry *dentry; |
555 | struct super_block *sb = pts_sb_from_inode(ptmx_inode); | 552 | struct super_block *sb = pts_sb_from_inode(ptmx_inode); |
556 | struct inode *inode; | 553 | struct inode *inode; |
@@ -559,23 +556,18 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) | |||
559 | struct pts_mount_opts *opts = &fsi->mount_opts; | 556 | struct pts_mount_opts *opts = &fsi->mount_opts; |
560 | char s[12]; | 557 | char s[12]; |
561 | 558 | ||
562 | /* We're supposed to be given the slave end of a pty */ | ||
563 | BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); | ||
564 | BUG_ON(driver->subtype != PTY_TYPE_SLAVE); | ||
565 | |||
566 | inode = new_inode(sb); | 559 | inode = new_inode(sb); |
567 | if (!inode) | 560 | if (!inode) |
568 | return ERR_PTR(-ENOMEM); | 561 | return ERR_PTR(-ENOMEM); |
569 | 562 | ||
570 | inode->i_ino = number + 3; | 563 | inode->i_ino = index + 3; |
571 | inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); | 564 | inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); |
572 | inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); | 565 | inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); |
573 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 566 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
574 | init_special_inode(inode, S_IFCHR|opts->mode, device); | 567 | init_special_inode(inode, S_IFCHR|opts->mode, device); |
575 | inode->i_private = tty; | 568 | inode->i_private = priv; |
576 | tty->driver_data = inode; | ||
577 | 569 | ||
578 | sprintf(s, "%d", number); | 570 | sprintf(s, "%d", index); |
579 | 571 | ||
580 | mutex_lock(&root->d_inode->i_mutex); | 572 | mutex_lock(&root->d_inode->i_mutex); |
581 | 573 | ||
@@ -613,9 +605,8 @@ void *devpts_get_priv(struct inode *pts_inode) | |||
613 | return priv; | 605 | return priv; |
614 | } | 606 | } |
615 | 607 | ||
616 | void devpts_pty_kill(struct tty_struct *tty) | 608 | void devpts_pty_kill(struct inode *inode) |
617 | { | 609 | { |
618 | struct inode *inode = tty->driver_data; | ||
619 | struct super_block *sb = pts_sb_from_inode(inode); | 610 | struct super_block *sb = pts_sb_from_inode(inode); |
620 | struct dentry *root = sb->s_root; | 611 | struct dentry *root = sb->s_root; |
621 | struct dentry *dentry; | 612 | struct dentry *dentry; |
diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index 4ca846f16fe5..251a2090a554 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h | |||
@@ -20,11 +20,12 @@ | |||
20 | int devpts_new_index(struct inode *ptmx_inode); | 20 | int devpts_new_index(struct inode *ptmx_inode); |
21 | void devpts_kill_index(struct inode *ptmx_inode, int idx); | 21 | void devpts_kill_index(struct inode *ptmx_inode, int idx); |
22 | /* mknod in devpts */ | 22 | /* mknod in devpts */ |
23 | struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty); | 23 | struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, |
24 | void *priv); | ||
24 | /* get private structure */ | 25 | /* get private structure */ |
25 | void *devpts_get_priv(struct inode *pts_inode); | 26 | void *devpts_get_priv(struct inode *pts_inode); |
26 | /* unlink */ | 27 | /* unlink */ |
27 | void devpts_pty_kill(struct tty_struct *tty); | 28 | void devpts_pty_kill(struct inode *inode); |
28 | 29 | ||
29 | #else | 30 | #else |
30 | 31 | ||
@@ -32,7 +33,7 @@ void devpts_pty_kill(struct tty_struct *tty); | |||
32 | static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } | 33 | static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } |
33 | static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } | 34 | static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } |
34 | static inline struct inode *devpts_pty_new(struct inode *ptmx_inode, | 35 | static inline struct inode *devpts_pty_new(struct inode *ptmx_inode, |
35 | struct tty_struct *tty) | 36 | dev_t device, int index, void *priv) |
36 | { | 37 | { |
37 | return ERR_PTR(-EINVAL); | 38 | return ERR_PTR(-EINVAL); |
38 | } | 39 | } |
@@ -40,7 +41,7 @@ static inline void *devpts_get_priv(struct inode *pts_inode) | |||
40 | { | 41 | { |
41 | return NULL; | 42 | return NULL; |
42 | } | 43 | } |
43 | static inline void devpts_pty_kill(struct tty_struct *tty) { } | 44 | static inline void devpts_pty_kill(struct inode *inode) { } |
44 | 45 | ||
45 | #endif | 46 | #endif |
46 | 47 | ||