aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2010-08-17 14:37:35 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-18 08:35:47 -0400
commitee2ffa0dfdd2db19705f2ba1c6a4c0bfe8122dd8 (patch)
treee48400d1a33f8d2e68589ccfd61637aa64462f08 /drivers/char/tty_io.c
parentb04f784e5d19ed58892833dae845738972cea260 (diff)
fs: cleanup files_lock locking
fs: cleanup files_lock locking Lock tty_files with a new spinlock, tty_files_lock; provide helpers to manipulate the per-sb files list; unexport the files_lock spinlock. Cc: linux-kernel@vger.kernel.org Cc: Christoph Hellwig <hch@infradead.org> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Acked-by: Andi Kleen <ak@linux.intel.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Nick Piggin <npiggin@kernel.dk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 0350c42375a2..cd5b829634ea 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 *,
@@ -235,11 +238,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
235 struct list_head *p; 238 struct list_head *p;
236 int count = 0; 239 int count = 0;
237 240
238 file_list_lock(); 241 spin_lock(&tty_files_lock);
239 list_for_each(p, &tty->tty_files) { 242 list_for_each(p, &tty->tty_files) {
240 count++; 243 count++;
241 } 244 }
242 file_list_unlock(); 245 spin_unlock(&tty_files_lock);
243 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 246 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
244 tty->driver->subtype == PTY_TYPE_SLAVE && 247 tty->driver->subtype == PTY_TYPE_SLAVE &&
245 tty->link && tty->link->count) 248 tty->link && tty->link->count)
@@ -519,7 +522,7 @@ void __tty_hangup(struct tty_struct *tty)
519 workqueue with the lock held */ 522 workqueue with the lock held */
520 check_tty_count(tty, "tty_hangup"); 523 check_tty_count(tty, "tty_hangup");
521 524
522 file_list_lock(); 525 spin_lock(&tty_files_lock);
523 /* This breaks for file handles being sent over AF_UNIX sockets ? */ 526 /* This breaks for file handles being sent over AF_UNIX sockets ? */
524 list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { 527 list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
525 if (filp->f_op->write == redirected_tty_write) 528 if (filp->f_op->write == redirected_tty_write)
@@ -530,7 +533,7 @@ void __tty_hangup(struct tty_struct *tty)
530 __tty_fasync(-1, filp, 0); /* can't block */ 533 __tty_fasync(-1, filp, 0); /* can't block */
531 filp->f_op = &hung_up_tty_fops; 534 filp->f_op = &hung_up_tty_fops;
532 } 535 }
533 file_list_unlock(); 536 spin_unlock(&tty_files_lock);
534 537
535 tty_ldisc_hangup(tty); 538 tty_ldisc_hangup(tty);
536 539
@@ -1424,9 +1427,9 @@ static void release_one_tty(struct work_struct *work)
1424 tty_driver_kref_put(driver); 1427 tty_driver_kref_put(driver);
1425 module_put(driver->owner); 1428 module_put(driver->owner);
1426 1429
1427 file_list_lock(); 1430 spin_lock(&tty_files_lock);
1428 list_del_init(&tty->tty_files); 1431 list_del_init(&tty->tty_files);
1429 file_list_unlock(); 1432 spin_unlock(&tty_files_lock);
1430 1433
1431 put_pid(tty->pgrp); 1434 put_pid(tty->pgrp);
1432 put_pid(tty->session); 1435 put_pid(tty->session);
@@ -1671,7 +1674,10 @@ int tty_release(struct inode *inode, struct file *filp)
1671 * - do_tty_hangup no longer sees this file descriptor as 1674 * - do_tty_hangup no longer sees this file descriptor as
1672 * something that needs to be handled for hangups. 1675 * something that needs to be handled for hangups.
1673 */ 1676 */
1674 file_kill(filp); 1677 spin_lock(&tty_files_lock);
1678 BUG_ON(list_empty(&filp->f_u.fu_list));
1679 list_del_init(&filp->f_u.fu_list);
1680 spin_unlock(&tty_files_lock);
1675 filp->private_data = NULL; 1681 filp->private_data = NULL;
1676 1682
1677 /* 1683 /*
@@ -1840,7 +1846,11 @@ got_driver:
1840 } 1846 }
1841 1847
1842 filp->private_data = tty; 1848 filp->private_data = tty;
1843 file_move(filp, &tty->tty_files); 1849 BUG_ON(list_empty(&filp->f_u.fu_list));
1850 file_sb_list_del(filp); /* __dentry_open has put it on the sb list */
1851 spin_lock(&tty_files_lock);
1852 list_add(&filp->f_u.fu_list, &tty->tty_files);
1853 spin_unlock(&tty_files_lock);
1844 check_tty_count(tty, "tty_open"); 1854 check_tty_count(tty, "tty_open");
1845 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1855 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1846 tty->driver->subtype == PTY_TYPE_MASTER) 1856 tty->driver->subtype == PTY_TYPE_MASTER)