aboutsummaryrefslogtreecommitdiffstats
path: root/fs/devpts/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/devpts/inode.c')
-rw-r--r--fs/devpts/inode.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 14afbabe6546..472e6befc54d 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -545,37 +545,38 @@ 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
548int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) 548/**
549 * devpts_pty_new -- create a new inode in /dev/pts/
550 * @ptmx_inode: inode of the master
551 * @device: major+minor of the node to be created
552 * @index: used as a name of the node
553 * @priv: what's given back by devpts_get_priv
554 *
555 * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill.
556 */
557struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
558 void *priv)
549{ 559{
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; 560 struct dentry *dentry;
555 struct super_block *sb = pts_sb_from_inode(ptmx_inode); 561 struct super_block *sb = pts_sb_from_inode(ptmx_inode);
556 struct inode *inode = new_inode(sb); 562 struct inode *inode;
557 struct dentry *root = sb->s_root; 563 struct dentry *root = sb->s_root;
558 struct pts_fs_info *fsi = DEVPTS_SB(sb); 564 struct pts_fs_info *fsi = DEVPTS_SB(sb);
559 struct pts_mount_opts *opts = &fsi->mount_opts; 565 struct pts_mount_opts *opts = &fsi->mount_opts;
560 int ret = 0;
561 char s[12]; 566 char s[12];
562 567
563 /* We're supposed to be given the slave end of a pty */ 568 inode = new_inode(sb);
564 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
565 BUG_ON(driver->subtype != PTY_TYPE_SLAVE);
566
567 if (!inode) 569 if (!inode)
568 return -ENOMEM; 570 return ERR_PTR(-ENOMEM);
569 571
570 inode->i_ino = number + 3; 572 inode->i_ino = index + 3;
571 inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); 573 inode->i_uid = opts->setuid ? opts->uid : current_fsuid();
572 inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); 574 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
573 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 575 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
574 init_special_inode(inode, S_IFCHR|opts->mode, device); 576 init_special_inode(inode, S_IFCHR|opts->mode, device);
575 inode->i_private = tty; 577 inode->i_private = priv;
576 tty->driver_data = inode;
577 578
578 sprintf(s, "%d", number); 579 sprintf(s, "%d", index);
579 580
580 mutex_lock(&root->d_inode->i_mutex); 581 mutex_lock(&root->d_inode->i_mutex);
581 582
@@ -585,18 +586,24 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
585 fsnotify_create(root->d_inode, dentry); 586 fsnotify_create(root->d_inode, dentry);
586 } else { 587 } else {
587 iput(inode); 588 iput(inode);
588 ret = -ENOMEM; 589 inode = ERR_PTR(-ENOMEM);
589 } 590 }
590 591
591 mutex_unlock(&root->d_inode->i_mutex); 592 mutex_unlock(&root->d_inode->i_mutex);
592 593
593 return ret; 594 return inode;
594} 595}
595 596
596struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) 597/**
598 * devpts_get_priv -- get private data for a slave
599 * @pts_inode: inode of the slave
600 *
601 * Returns whatever was passed as priv in devpts_pty_new for a given inode.
602 */
603void *devpts_get_priv(struct inode *pts_inode)
597{ 604{
598 struct dentry *dentry; 605 struct dentry *dentry;
599 struct tty_struct *tty; 606 void *priv = NULL;
600 607
601 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); 608 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
602 609
@@ -605,18 +612,22 @@ struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
605 if (!dentry) 612 if (!dentry)
606 return NULL; 613 return NULL;
607 614
608 tty = NULL;
609 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) 615 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
610 tty = (struct tty_struct *)pts_inode->i_private; 616 priv = pts_inode->i_private;
611 617
612 dput(dentry); 618 dput(dentry);
613 619
614 return tty; 620 return priv;
615} 621}
616 622
617void devpts_pty_kill(struct tty_struct *tty) 623/**
624 * devpts_pty_kill -- remove inode form /dev/pts/
625 * @inode: inode of the slave to be removed
626 *
627 * This is an inverse operation of devpts_pty_new.
628 */
629void devpts_pty_kill(struct inode *inode)
618{ 630{
619 struct inode *inode = tty->driver_data;
620 struct super_block *sb = pts_sb_from_inode(inode); 631 struct super_block *sb = pts_sb_from_inode(inode);
621 struct dentry *root = sb->s_root; 632 struct dentry *root = sb->s_root;
622 struct dentry *dentry; 633 struct dentry *dentry;