diff options
author | Tom Van Braeckel <tomvanbraeckel@gmail.com> | 2015-03-31 10:39:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-03 10:15:30 -0400 |
commit | 0b509d8d336eef6d622d66b3ae2a1fc3a072bf92 (patch) | |
tree | 581850695df4a3fb3ee009513ee5afed7317593c /drivers/char/misc.c | |
parent | 16c9c8e1ae228e89b66cbc03ec6c753ee44d39bc (diff) |
misc: pass miscdevice through file's private_data
Make the miscdevice accessible through the file's private_data.
Previously, this was done only when an open() file operation had been
registered. If no custom open() file operation was defined,
private_data was set to NULL.
This subtle quirk was confusing, to the point where kernel code
registered *empty* file open operations to have private_data point to
the misc device structure and avoid duplicating that logic.
And it could easily lead to bugs, where the addition or removal of a
custom open() file operation surprisingly changes the initial value of
a file's private_data structure.
To resolve this, we now place the miscdevice in the file's private_data
member unconditionally when open() is called.
Signed-off-by: Tom Van Braeckel <tomvanbraeckel@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/char/misc.c')
-rw-r--r-- | drivers/char/misc.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 5bb3a2109ab7..9fd5a91e0d81 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -140,12 +140,17 @@ static int misc_open(struct inode * inode, struct file * file) | |||
140 | goto fail; | 140 | goto fail; |
141 | } | 141 | } |
142 | 142 | ||
143 | /* | ||
144 | * Place the miscdevice in the file's | ||
145 | * private_data so it can be used by the | ||
146 | * file operations, including f_op->open below | ||
147 | */ | ||
148 | file->private_data = c; | ||
149 | |||
143 | err = 0; | 150 | err = 0; |
144 | replace_fops(file, new_fops); | 151 | replace_fops(file, new_fops); |
145 | if (file->f_op->open) { | 152 | if (file->f_op->open) |
146 | file->private_data = c; | ||
147 | err = file->f_op->open(inode,file); | 153 | err = file->f_op->open(inode,file); |
148 | } | ||
149 | fail: | 154 | fail: |
150 | mutex_unlock(&misc_mtx); | 155 | mutex_unlock(&misc_mtx); |
151 | return err; | 156 | return err; |