diff options
author | Jonathan Corbet <corbet@lwn.net> | 2009-01-08 15:50:07 -0700 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2009-01-15 15:28:21 -0700 |
commit | 7232c910b7bcf86e8985f7029bba2f0a80d31df3 (patch) | |
tree | 29d4f074efcf3ba21fab16231558fde21e046372 /drivers/char | |
parent | c59765042f53a79a7a65585042ff463b69cb248c (diff) |
Protect f_flags against races and eliminate fasync() BKL usage
Accesses to the f_flags member of struct file involve read-modify-write
cycles; they have traditionally been done in a racy way. This patch
introduces a global spinlock to protect f_flags against concurrent
modifications.
Additionally, changes to the FASYNC flag and resulting calls to
f_op->fasync() need to be done in an atomic manner. Here, the BKL is
removed and FASYNC modifications are protected with a mutex.
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tty_io.c | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index d33e5ab06177..84503163a143 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2160,13 +2160,12 @@ static int fionbio(struct file *file, int __user *p) if (get_user(nonblock, p)) return -EFAULT; - /* file->f_flags is still BKL protected in the fs layer - vomit */ - lock_kernel(); + lock_file_flags(); if (nonblock) file->f_flags |= O_NONBLOCK; else file->f_flags &= ~O_NONBLOCK; - unlock_kernel(); + unlock_file_flags(); return 0; } |