Leverage revocable fops replacement if the driver requests.
The "resource" in the context means presence of the miscdevice. It prevents file operations (except .release()) in drivers to be called if the miscdevice no longer exists.
Signed-off-by: Tzung-Bi Shih tzungbi@kernel.org --- v6: - Call fs_revocable_replace() after f_op->open() and modify the API usage accordingly. - Use presence of miscdevice as a virtual resource.
v5: https://lore.kernel.org/chrome-platform/20251016054204.1523139-7-tzungbi@ker... - No primary changes but modify the API usage accordingly to support multiple revocable providers.
v4: https://lore.kernel.org/chrome-platform/20250923075302.591026-7-tzungbi@kern... - New in the series.
drivers/char/misc.c | 18 ++++++++++++++++-- include/linux/miscdevice.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 726516fb0a3b..e0106270c188 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -50,6 +50,8 @@ #include <linux/tty.h> #include <linux/kmod.h> #include <linux/gfp.h> +#include <linux/fs_revocable.h> +#include <linux/revocable.h>
/* * Head entry for the doubly linked miscdevice list @@ -157,10 +159,16 @@ static int misc_open(struct inode *inode, struct file *file) */ file->private_data = c;
- err = 0; replace_fops(file, new_fops); - if (file->f_op->open) + + if (file->f_op->open) { err = file->f_op->open(inode, file); + if (err) + goto fail; + } + + if (c->revocable) + err = fs_revocable_replace(c->rp, file); fail: mutex_unlock(&misc_mtx); return err; @@ -218,6 +226,10 @@ int misc_register(struct miscdevice *misc) return -EINVAL; }
+ misc->rp = revocable_provider_alloc(misc); + if (!misc->rp) + return -ENOMEM; + INIT_LIST_HEAD(&misc->list);
mutex_lock(&misc_mtx); @@ -290,6 +302,8 @@ void misc_deregister(struct miscdevice *misc) if (misc->minor > MISC_DYNAMIC_MINOR) misc->minor = MISC_DYNAMIC_MINOR; mutex_unlock(&misc_mtx); + + revocable_provider_revoke(misc->rp); } EXPORT_SYMBOL(misc_deregister);
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 7d0aa718499c..85fac108e485 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -92,6 +92,8 @@ struct miscdevice { const struct attribute_group **groups; const char *nodename; umode_t mode; + bool revocable; + struct revocable_provider *rp; };
extern int misc_register(struct miscdevice *misc);