diff --git a/drivers/char/misc.c b/drivers/char/misc.c index cba19bfdc44d..292c86c090b9 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -139,6 +139,10 @@ static int misc_open(struct inode *inode, struct file *file) err = 0; replace_fops(file, new_fops); + if (iter->unlocked_open && file->f_op->open) { + mutex_unlock(&misc_mtx); + return file->f_op->open(inode, file); + } if (file->f_op->open) err = file->f_op->open(inode, file); fail: diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 0676f18093f9..e112ef9e3b7b 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -86,6 +86,7 @@ struct miscdevice { const struct attribute_group **groups; const char *nodename; umode_t mode; + bool unlocked_open; }; extern int misc_register(struct miscdevice *misc); diff --git a/kernel/power/user.c b/kernel/power/user.c index ad241b4ff64c..69a269c4fb46 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -441,6 +441,7 @@ static struct miscdevice snapshot_device = { .minor = SNAPSHOT_MINOR, .name = "snapshot", .fops = &snapshot_fops, + .unlocked_open = true, }; static int __init snapshot_device_init(void)