summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorTom Van Braeckel <tomvanbraeckel@gmail.com>2015-03-31 16:39:21 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-04-03 16:15:30 +0200
commit0b509d8d336eef6d622d66b3ae2a1fc3a072bf92 (patch)
tree581850695df4a3fb3ee009513ee5afed7317593c /drivers/char
parent16c9c8e1ae228e89b66cbc03ec6c753ee44d39bc (diff)
downloadlinux-0b509d8d336eef6d622d66b3ae2a1fc3a072bf92.tar.bz2
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')
-rw-r--r--drivers/char/misc.c11
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)
goto fail;
}
+ /*
+ * Place the miscdevice in the file's
+ * private_data so it can be used by the
+ * file operations, including f_op->open below
+ */
+ file->private_data = c;
+
err = 0;
replace_fops(file, new_fops);
- if (file->f_op->open) {
- file->private_data = c;
+ if (file->f_op->open)
err = file->f_op->open(inode,file);
- }
fail:
mutex_unlock(&misc_mtx);
return err;