diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-18 12:35:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-18 12:35:08 -0400 |
commit | 145c3ae46b37993b0debb0b3da6256daea4a6ec5 (patch) | |
tree | 0dbff382ce36b23b3d2dbff87d3eaab73a07a2a4 /drivers | |
parent | 81ca03a0e2ea0207b2df80e0edcf4c775c07a505 (diff) | |
parent | 99b7db7b8ffd6bb755eb0a175596421a0b581cb2 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
fs: brlock vfsmount_lock
fs: scale files_lock
lglock: introduce special lglock and brlock spin locks
tty: fix fu_list abuse
fs: cleanup files_lock locking
fs: remove extra lookup in __lookup_hash
fs: fs_struct rwlock to spinlock
apparmor: use task path helpers
fs: dentry allocation consolidation
fs: fix do_lookup false negative
mbcache: Limit the maximum number of cache entries
hostfs ->follow_link() braino
hostfs: dumb (and usually harmless) tpyo - strncpy instead of strlcpy
remove SWRITE* I/O types
kill BH_Ordered flag
vfs: update ctime when changing the file's permission by setfacl
cramfs: only unlock new inodes
fix reiserfs_evict_inode end_writeback second call
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/pty.c | 4 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 92 | ||||
-rw-r--r-- | drivers/staging/pohmelfs/path_entry.c | 8 |
3 files changed, 69 insertions, 35 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index ad46eae1f9bb..c350d01716bd 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -675,8 +675,8 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
678 | filp->private_data = tty; | 678 | |
679 | file_move(filp, &tty->tty_files); | 679 | tty_add_file(tty, filp); |
680 | 680 | ||
681 | retval = devpts_pty_new(inode, tty->link); | 681 | retval = devpts_pty_new(inode, tty->link); |
682 | if (retval) | 682 | if (retval) |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 0350c42375a2..949067a0bd47 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 */ | |||
136 | DEFINE_MUTEX(tty_mutex); | 136 | DEFINE_MUTEX(tty_mutex); |
137 | EXPORT_SYMBOL(tty_mutex); | 137 | EXPORT_SYMBOL(tty_mutex); |
138 | 138 | ||
139 | /* Spinlock to protect the tty->tty_files list */ | ||
140 | DEFINE_SPINLOCK(tty_files_lock); | ||
141 | |||
139 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 142 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
140 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 143 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
141 | ssize_t redirected_tty_write(struct file *, const char __user *, | 144 | ssize_t redirected_tty_write(struct file *, const char __user *, |
@@ -185,6 +188,41 @@ void free_tty_struct(struct tty_struct *tty) | |||
185 | kfree(tty); | 188 | kfree(tty); |
186 | } | 189 | } |
187 | 190 | ||
191 | static inline struct tty_struct *file_tty(struct file *file) | ||
192 | { | ||
193 | return ((struct tty_file_private *)file->private_data)->tty; | ||
194 | } | ||
195 | |||
196 | /* Associate a new file with the tty structure */ | ||
197 | void tty_add_file(struct tty_struct *tty, struct file *file) | ||
198 | { | ||
199 | struct tty_file_private *priv; | ||
200 | |||
201 | /* XXX: must implement proper error handling in callers */ | ||
202 | priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL); | ||
203 | |||
204 | priv->tty = tty; | ||
205 | priv->file = file; | ||
206 | file->private_data = priv; | ||
207 | |||
208 | spin_lock(&tty_files_lock); | ||
209 | list_add(&priv->list, &tty->tty_files); | ||
210 | spin_unlock(&tty_files_lock); | ||
211 | } | ||
212 | |||
213 | /* Delete file from its tty */ | ||
214 | void tty_del_file(struct file *file) | ||
215 | { | ||
216 | struct tty_file_private *priv = file->private_data; | ||
217 | |||
218 | spin_lock(&tty_files_lock); | ||
219 | list_del(&priv->list); | ||
220 | spin_unlock(&tty_files_lock); | ||
221 | file->private_data = NULL; | ||
222 | kfree(priv); | ||
223 | } | ||
224 | |||
225 | |||
188 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) | 226 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) |
189 | 227 | ||
190 | /** | 228 | /** |
@@ -235,11 +273,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
235 | struct list_head *p; | 273 | struct list_head *p; |
236 | int count = 0; | 274 | int count = 0; |
237 | 275 | ||
238 | file_list_lock(); | 276 | spin_lock(&tty_files_lock); |
239 | list_for_each(p, &tty->tty_files) { | 277 | list_for_each(p, &tty->tty_files) { |
240 | count++; | 278 | count++; |
241 | } | 279 | } |
242 | file_list_unlock(); | 280 | spin_unlock(&tty_files_lock); |
243 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 281 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
244 | tty->driver->subtype == PTY_TYPE_SLAVE && | 282 | tty->driver->subtype == PTY_TYPE_SLAVE && |
245 | tty->link && tty->link->count) | 283 | tty->link && tty->link->count) |
@@ -497,6 +535,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
497 | struct file *cons_filp = NULL; | 535 | struct file *cons_filp = NULL; |
498 | struct file *filp, *f = NULL; | 536 | struct file *filp, *f = NULL; |
499 | struct task_struct *p; | 537 | struct task_struct *p; |
538 | struct tty_file_private *priv; | ||
500 | int closecount = 0, n; | 539 | int closecount = 0, n; |
501 | unsigned long flags; | 540 | unsigned long flags; |
502 | int refs = 0; | 541 | int refs = 0; |
@@ -506,7 +545,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
506 | 545 | ||
507 | 546 | ||
508 | spin_lock(&redirect_lock); | 547 | spin_lock(&redirect_lock); |
509 | if (redirect && redirect->private_data == tty) { | 548 | if (redirect && file_tty(redirect) == tty) { |
510 | f = redirect; | 549 | f = redirect; |
511 | redirect = NULL; | 550 | redirect = NULL; |
512 | } | 551 | } |
@@ -519,9 +558,10 @@ void __tty_hangup(struct tty_struct *tty) | |||
519 | workqueue with the lock held */ | 558 | workqueue with the lock held */ |
520 | check_tty_count(tty, "tty_hangup"); | 559 | check_tty_count(tty, "tty_hangup"); |
521 | 560 | ||
522 | file_list_lock(); | 561 | spin_lock(&tty_files_lock); |
523 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 562 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
524 | list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { | 563 | list_for_each_entry(priv, &tty->tty_files, list) { |
564 | filp = priv->file; | ||
525 | if (filp->f_op->write == redirected_tty_write) | 565 | if (filp->f_op->write == redirected_tty_write) |
526 | cons_filp = filp; | 566 | cons_filp = filp; |
527 | if (filp->f_op->write != tty_write) | 567 | if (filp->f_op->write != tty_write) |
@@ -530,7 +570,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
530 | __tty_fasync(-1, filp, 0); /* can't block */ | 570 | __tty_fasync(-1, filp, 0); /* can't block */ |
531 | filp->f_op = &hung_up_tty_fops; | 571 | filp->f_op = &hung_up_tty_fops; |
532 | } | 572 | } |
533 | file_list_unlock(); | 573 | spin_unlock(&tty_files_lock); |
534 | 574 | ||
535 | tty_ldisc_hangup(tty); | 575 | tty_ldisc_hangup(tty); |
536 | 576 | ||
@@ -889,12 +929,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
889 | loff_t *ppos) | 929 | loff_t *ppos) |
890 | { | 930 | { |
891 | int i; | 931 | int i; |
892 | struct tty_struct *tty; | 932 | struct inode *inode = file->f_path.dentry->d_inode; |
893 | struct inode *inode; | 933 | struct tty_struct *tty = file_tty(file); |
894 | struct tty_ldisc *ld; | 934 | struct tty_ldisc *ld; |
895 | 935 | ||
896 | tty = file->private_data; | ||
897 | inode = file->f_path.dentry->d_inode; | ||
898 | if (tty_paranoia_check(tty, inode, "tty_read")) | 936 | if (tty_paranoia_check(tty, inode, "tty_read")) |
899 | return -EIO; | 937 | return -EIO; |
900 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) | 938 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) |
@@ -1065,12 +1103,11 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1065 | static ssize_t tty_write(struct file *file, const char __user *buf, | 1103 | static ssize_t tty_write(struct file *file, const char __user *buf, |
1066 | size_t count, loff_t *ppos) | 1104 | size_t count, loff_t *ppos) |
1067 | { | 1105 | { |
1068 | struct tty_struct *tty; | ||
1069 | struct inode *inode = file->f_path.dentry->d_inode; | 1106 | struct inode *inode = file->f_path.dentry->d_inode; |
1107 | struct tty_struct *tty = file_tty(file); | ||
1108 | struct tty_ldisc *ld; | ||
1070 | ssize_t ret; | 1109 | ssize_t ret; |
1071 | struct tty_ldisc *ld; | ||
1072 | 1110 | ||
1073 | tty = file->private_data; | ||
1074 | if (tty_paranoia_check(tty, inode, "tty_write")) | 1111 | if (tty_paranoia_check(tty, inode, "tty_write")) |
1075 | return -EIO; | 1112 | return -EIO; |
1076 | if (!tty || !tty->ops->write || | 1113 | if (!tty || !tty->ops->write || |
@@ -1424,9 +1461,9 @@ static void release_one_tty(struct work_struct *work) | |||
1424 | tty_driver_kref_put(driver); | 1461 | tty_driver_kref_put(driver); |
1425 | module_put(driver->owner); | 1462 | module_put(driver->owner); |
1426 | 1463 | ||
1427 | file_list_lock(); | 1464 | spin_lock(&tty_files_lock); |
1428 | list_del_init(&tty->tty_files); | 1465 | list_del_init(&tty->tty_files); |
1429 | file_list_unlock(); | 1466 | spin_unlock(&tty_files_lock); |
1430 | 1467 | ||
1431 | put_pid(tty->pgrp); | 1468 | put_pid(tty->pgrp); |
1432 | put_pid(tty->session); | 1469 | put_pid(tty->session); |
@@ -1507,13 +1544,13 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1507 | 1544 | ||
1508 | int tty_release(struct inode *inode, struct file *filp) | 1545 | int tty_release(struct inode *inode, struct file *filp) |
1509 | { | 1546 | { |
1510 | struct tty_struct *tty, *o_tty; | 1547 | struct tty_struct *tty = file_tty(filp); |
1548 | struct tty_struct *o_tty; | ||
1511 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1549 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1512 | int devpts; | 1550 | int devpts; |
1513 | int idx; | 1551 | int idx; |
1514 | char buf[64]; | 1552 | char buf[64]; |
1515 | 1553 | ||
1516 | tty = filp->private_data; | ||
1517 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1554 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1518 | return 0; | 1555 | return 0; |
1519 | 1556 | ||
@@ -1671,8 +1708,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1671 | * - do_tty_hangup no longer sees this file descriptor as | 1708 | * - do_tty_hangup no longer sees this file descriptor as |
1672 | * something that needs to be handled for hangups. | 1709 | * something that needs to be handled for hangups. |
1673 | */ | 1710 | */ |
1674 | file_kill(filp); | 1711 | tty_del_file(filp); |
1675 | filp->private_data = NULL; | ||
1676 | 1712 | ||
1677 | /* | 1713 | /* |
1678 | * Perform some housekeeping before deciding whether to return. | 1714 | * Perform some housekeeping before deciding whether to return. |
@@ -1839,8 +1875,8 @@ got_driver: | |||
1839 | return PTR_ERR(tty); | 1875 | return PTR_ERR(tty); |
1840 | } | 1876 | } |
1841 | 1877 | ||
1842 | filp->private_data = tty; | 1878 | tty_add_file(tty, filp); |
1843 | file_move(filp, &tty->tty_files); | 1879 | |
1844 | check_tty_count(tty, "tty_open"); | 1880 | check_tty_count(tty, "tty_open"); |
1845 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1881 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1846 | tty->driver->subtype == PTY_TYPE_MASTER) | 1882 | tty->driver->subtype == PTY_TYPE_MASTER) |
@@ -1916,11 +1952,10 @@ got_driver: | |||
1916 | 1952 | ||
1917 | static unsigned int tty_poll(struct file *filp, poll_table *wait) | 1953 | static unsigned int tty_poll(struct file *filp, poll_table *wait) |
1918 | { | 1954 | { |
1919 | struct tty_struct *tty; | 1955 | struct tty_struct *tty = file_tty(filp); |
1920 | struct tty_ldisc *ld; | 1956 | struct tty_ldisc *ld; |
1921 | int ret = 0; | 1957 | int ret = 0; |
1922 | 1958 | ||
1923 | tty = filp->private_data; | ||
1924 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) | 1959 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) |
1925 | return 0; | 1960 | return 0; |
1926 | 1961 | ||
@@ -1933,11 +1968,10 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
1933 | 1968 | ||
1934 | static int __tty_fasync(int fd, struct file *filp, int on) | 1969 | static int __tty_fasync(int fd, struct file *filp, int on) |
1935 | { | 1970 | { |
1936 | struct tty_struct *tty; | 1971 | struct tty_struct *tty = file_tty(filp); |
1937 | unsigned long flags; | 1972 | unsigned long flags; |
1938 | int retval = 0; | 1973 | int retval = 0; |
1939 | 1974 | ||
1940 | tty = filp->private_data; | ||
1941 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) | 1975 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
1942 | goto out; | 1976 | goto out; |
1943 | 1977 | ||
@@ -2491,13 +2525,13 @@ EXPORT_SYMBOL(tty_pair_get_pty); | |||
2491 | */ | 2525 | */ |
2492 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 2526 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2493 | { | 2527 | { |
2494 | struct tty_struct *tty, *real_tty; | 2528 | struct tty_struct *tty = file_tty(file); |
2529 | struct tty_struct *real_tty; | ||
2495 | void __user *p = (void __user *)arg; | 2530 | void __user *p = (void __user *)arg; |
2496 | int retval; | 2531 | int retval; |
2497 | struct tty_ldisc *ld; | 2532 | struct tty_ldisc *ld; |
2498 | struct inode *inode = file->f_dentry->d_inode; | 2533 | struct inode *inode = file->f_dentry->d_inode; |
2499 | 2534 | ||
2500 | tty = file->private_data; | ||
2501 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) | 2535 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) |
2502 | return -EINVAL; | 2536 | return -EINVAL; |
2503 | 2537 | ||
@@ -2619,7 +2653,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
2619 | unsigned long arg) | 2653 | unsigned long arg) |
2620 | { | 2654 | { |
2621 | struct inode *inode = file->f_dentry->d_inode; | 2655 | struct inode *inode = file->f_dentry->d_inode; |
2622 | struct tty_struct *tty = file->private_data; | 2656 | struct tty_struct *tty = file_tty(file); |
2623 | struct tty_ldisc *ld; | 2657 | struct tty_ldisc *ld; |
2624 | int retval = -ENOIOCTLCMD; | 2658 | int retval = -ENOIOCTLCMD; |
2625 | 2659 | ||
@@ -2711,7 +2745,7 @@ void __do_SAK(struct tty_struct *tty) | |||
2711 | if (!filp) | 2745 | if (!filp) |
2712 | continue; | 2746 | continue; |
2713 | if (filp->f_op->read == tty_read && | 2747 | if (filp->f_op->read == tty_read && |
2714 | filp->private_data == tty) { | 2748 | file_tty(filp) == tty) { |
2715 | printk(KERN_NOTICE "SAK: killed process %d" | 2749 | printk(KERN_NOTICE "SAK: killed process %d" |
2716 | " (%s): fd#%d opened to the tty\n", | 2750 | " (%s): fd#%d opened to the tty\n", |
2717 | task_pid_nr(p), p->comm, i); | 2751 | task_pid_nr(p), p->comm, i); |
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c index cdc4dd50d638..8ec83d2dffb7 100644 --- a/drivers/staging/pohmelfs/path_entry.c +++ b/drivers/staging/pohmelfs/path_entry.c | |||
@@ -44,9 +44,9 @@ int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int le | |||
44 | return -ENOENT; | 44 | return -ENOENT; |
45 | } | 45 | } |
46 | 46 | ||
47 | read_lock(¤t->fs->lock); | 47 | spin_lock(¤t->fs->lock); |
48 | path.mnt = mntget(current->fs->root.mnt); | 48 | path.mnt = mntget(current->fs->root.mnt); |
49 | read_unlock(¤t->fs->lock); | 49 | spin_unlock(¤t->fs->lock); |
50 | 50 | ||
51 | path.dentry = d; | 51 | path.dentry = d; |
52 | 52 | ||
@@ -91,9 +91,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi) | |||
91 | return -ENOENT; | 91 | return -ENOENT; |
92 | } | 92 | } |
93 | 93 | ||
94 | read_lock(¤t->fs->lock); | 94 | spin_lock(¤t->fs->lock); |
95 | root = dget(current->fs->root.dentry); | 95 | root = dget(current->fs->root.dentry); |
96 | read_unlock(¤t->fs->lock); | 96 | spin_unlock(¤t->fs->lock); |
97 | 97 | ||
98 | spin_lock(&dcache_lock); | 98 | spin_lock(&dcache_lock); |
99 | 99 | ||