aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJohn Stultz <johnstul@us.ibm.com>2010-03-22 20:18:36 -0400
committerThomas Gleixner <tglx@linutronix.de>2010-04-27 11:32:26 -0400
commit6f91ea55dfbe1b571542723bf8423e897f68b2c1 (patch)
tree13dc3d9752f81af60c214a8d62ad26ab7fdd749b /drivers/char
parente48c15434b82de9a3f597f02ea2257ca22d44d9f (diff)
fs-files_list-improve
Lock tty_files with a new spinlock, tty_files_lock; provide helpers to manipulate the per-sb files list; unexport the files_lock spinlock. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: John Stultz <johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/pty.c6
-rw-r--r--drivers/char/tty_io.c27
2 files changed, 23 insertions, 10 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 385c44b3034f..8fa273e76bb3 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -649,7 +649,11 @@ static int __ptmx_open(struct inode *inode, struct file *filp)
649 649
650 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ 650 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
651 filp->private_data = tty; 651 filp->private_data = tty;
652 file_move(filp, &tty->tty_files); 652
653 file_sb_list_del(filp); /* __dentry_open has put it on the sb list */
654 spin_lock(&tty_files_lock);
655 list_add(&filp->f_u.fu_list, &tty->tty_files);
656 spin_unlock(&tty_files_lock);
653 657
654 retval = devpts_pty_new(inode, tty->link); 658 retval = devpts_pty_new(inode, tty->link);
655 if (retval) 659 if (retval)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 76253cf27028..38ddfa404fb1 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -136,6 +136,9 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
136DEFINE_MUTEX(tty_mutex); 136DEFINE_MUTEX(tty_mutex);
137EXPORT_SYMBOL(tty_mutex); 137EXPORT_SYMBOL(tty_mutex);
138 138
139/* Spinlock to protect the tty->tty_files list */
140DEFINE_SPINLOCK(tty_files_lock);
141
139static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); 142static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
140static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); 143static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
141ssize_t redirected_tty_write(struct file *, const char __user *, 144ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -234,11 +237,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
234 struct list_head *p; 237 struct list_head *p;
235 int count = 0; 238 int count = 0;
236 239
237 file_list_lock(); 240 spin_lock(&tty_files_lock);
238 list_for_each(p, &tty->tty_files) { 241 list_for_each(p, &tty->tty_files) {
239 count++; 242 count++;
240 } 243 }
241 file_list_unlock(); 244 spin_unlock(&tty_files_lock);
242 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 245 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
243 tty->driver->subtype == PTY_TYPE_SLAVE && 246 tty->driver->subtype == PTY_TYPE_SLAVE &&
244 tty->link && tty->link->count) 247 tty->link && tty->link->count)
@@ -516,8 +519,7 @@ static void do_tty_hangup(struct work_struct *work)
516 /* inuse_filps is protected by the single kernel lock */ 519 /* inuse_filps is protected by the single kernel lock */
517 lock_kernel(); 520 lock_kernel();
518 check_tty_count(tty, "do_tty_hangup"); 521 check_tty_count(tty, "do_tty_hangup");
519 522 spin_lock(&tty_files_lock);
520 file_list_lock();
521 /* This breaks for file handles being sent over AF_UNIX sockets ? */ 523 /* This breaks for file handles being sent over AF_UNIX sockets ? */
522 list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { 524 list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
523 if (filp->f_op->write == redirected_tty_write) 525 if (filp->f_op->write == redirected_tty_write)
@@ -528,7 +530,7 @@ static void do_tty_hangup(struct work_struct *work)
528 tty_fasync(-1, filp, 0); /* can't block */ 530 tty_fasync(-1, filp, 0); /* can't block */
529 filp->f_op = &hung_up_tty_fops; 531 filp->f_op = &hung_up_tty_fops;
530 } 532 }
531 file_list_unlock(); 533 spin_unlock(&tty_files_lock);
532 534
533 tty_ldisc_hangup(tty); 535 tty_ldisc_hangup(tty);
534 536
@@ -1419,9 +1421,9 @@ static void release_one_tty(struct work_struct *work)
1419 tty_driver_kref_put(driver); 1421 tty_driver_kref_put(driver);
1420 module_put(driver->owner); 1422 module_put(driver->owner);
1421 1423
1422 file_list_lock(); 1424 spin_lock(&tty_files_lock);
1423 list_del_init(&tty->tty_files); 1425 list_del_init(&tty->tty_files);
1424 file_list_unlock(); 1426 spin_unlock(&tty_files_lock);
1425 1427
1426 put_pid(tty->pgrp); 1428 put_pid(tty->pgrp);
1427 put_pid(tty->session); 1429 put_pid(tty->session);
@@ -1666,7 +1668,10 @@ int tty_release(struct inode *inode, struct file *filp)
1666 * - do_tty_hangup no longer sees this file descriptor as 1668 * - do_tty_hangup no longer sees this file descriptor as
1667 * something that needs to be handled for hangups. 1669 * something that needs to be handled for hangups.
1668 */ 1670 */
1669 file_kill(filp); 1671 spin_lock(&tty_files_lock);
1672 BUG_ON(list_empty(&filp->f_u.fu_list));
1673 list_del_init(&filp->f_u.fu_list);
1674 spin_unlock(&tty_files_lock);
1670 filp->private_data = NULL; 1675 filp->private_data = NULL;
1671 1676
1672 /* 1677 /*
@@ -1835,7 +1840,11 @@ got_driver:
1835 } 1840 }
1836 1841
1837 filp->private_data = tty; 1842 filp->private_data = tty;
1838 file_move(filp, &tty->tty_files); 1843 BUG_ON(list_empty(&filp->f_u.fu_list));
1844 file_sb_list_del(filp); /* __dentry_open has put it on the sb list */
1845 spin_lock(&tty_files_lock);
1846 list_add(&filp->f_u.fu_list, &tty->tty_files);
1847 spin_unlock(&tty_files_lock);
1839 check_tty_count(tty, "tty_open"); 1848 check_tty_count(tty, "tty_open");
1840 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1849 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1841 tty->driver->subtype == PTY_TYPE_MASTER) 1850 tty->driver->subtype == PTY_TYPE_MASTER)