From 059de1478e398b662aaf1f5e71f07e0c78600545 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 11 Feb 2020 11:20:41 -0500 Subject: [PATCH] fix: proc: decouple proc from VFS with "struct proc_ops" (v5.6) See upstream commit : commit d56c0d45f0e27f814e87a1676b6bdccccbc252e9 Author: Alexey Dobriyan Date: Mon Feb 3 17:37:14 2020 -0800 proc: decouple proc from VFS with "struct proc_ops" Currently core /proc code uses "struct file_operations" for custom hooks, however, VFS doesn't directly call them. Every time VFS expands file_operations hook set, /proc code bloats for no reason. Introduce "struct proc_ops" which contains only those hooks which /proc allows to call into (open, release, read, write, ioctl, mmap, poll). It doesn't contain module pointer as well. Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- lttng-abi.c | 23 +++++++++++++++++++---- probes/lttng.c | 14 +++++++++++++- tests/probes/lttng-test.c | 10 ++++++++-- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lttng-abi.c b/lttng-abi.c index 4df3d673..9d610e93 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -51,7 +51,13 @@ */ static struct proc_dir_entry *lttng_proc_dentry; -static const struct file_operations lttng_fops; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +static const struct proc_ops lttng_proc_ops; +#else +static const struct file_operations lttng_proc_ops; +#endif + static const struct file_operations lttng_session_fops; static const struct file_operations lttng_channel_fops; static const struct file_operations lttng_metadata_fops; @@ -391,13 +397,22 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } } -static const struct file_operations lttng_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +static const struct proc_ops lttng_proc_ops = { + .proc_ioctl = lttng_ioctl, +#ifdef CONFIG_COMPAT + .proc_compat_ioctl = lttng_ioctl, +#endif /* CONFIG_COMPAT */ +}; +#else +static const struct file_operations lttng_proc_ops = { .owner = THIS_MODULE, .unlocked_ioctl = lttng_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = lttng_ioctl, -#endif +#endif /* CONFIG_COMPAT */ }; +#endif static int lttng_abi_create_channel(struct file *session_file, @@ -1932,7 +1947,7 @@ int __init lttng_abi_init(void) } lttng_proc_dentry = proc_create_data("lttng", S_IRUSR | S_IWUSR, NULL, - <tng_fops, NULL); + <tng_proc_ops, NULL); if (!lttng_proc_dentry) { printk(KERN_ERR "Error creating LTTng control file\n"); diff --git a/probes/lttng.c b/probes/lttng.c index c883429f..383202c6 100644 --- a/probes/lttng.c +++ b/probes/lttng.c @@ -93,6 +93,18 @@ static const struct file_operations lttng_logger_operations = { .write = lttng_logger_write, }; +/* + * Linux 5.6 introduced a separate proc_ops struct for /proc operations + * to decouple it from the vfs. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +static const struct proc_ops lttng_logger_proc_ops = { + .proc_write = lttng_logger_write, +}; +#else +#define lttng_logger_proc_ops lttng_logger_operations +#endif + static struct miscdevice logger_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "lttng-logger", @@ -116,7 +128,7 @@ int __init lttng_logger_init(void) /* /proc/lttng-logger */ lttng_logger_dentry = proc_create_data(LTTNG_LOGGER_FILE, S_IRUGO | S_IWUGO, NULL, - <tng_logger_operations, NULL); + <tng_logger_proc_ops, NULL); if (!lttng_logger_dentry) { printk(KERN_ERR "Error creating LTTng logger proc file\n"); ret = -ENOMEM; diff --git a/tests/probes/lttng-test.c b/tests/probes/lttng-test.c index d1278183..e3476393 100644 --- a/tests/probes/lttng-test.c +++ b/tests/probes/lttng-test.c @@ -81,9 +81,15 @@ end: return written; } -static const struct file_operations lttng_test_filter_event_operations = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +static const struct proc_ops lttng_test_filter_event_proc_ops = { + .proc_write = lttng_test_filter_event_write, +}; +#else +static const struct file_operations lttng_test_filter_event_proc_ops = { .write = lttng_test_filter_event_write, }; +#endif static int __init lttng_test_init(void) @@ -95,7 +101,7 @@ int __init lttng_test_init(void) lttng_test_filter_event_dentry = proc_create_data(LTTNG_TEST_FILTER_EVENT_FILE, S_IRUGO | S_IWUGO, NULL, - <tng_test_filter_event_operations, NULL); + <tng_test_filter_event_proc_ops, NULL); if (!lttng_test_filter_event_dentry) { printk(KERN_ERR "Error creating LTTng test filter file\n"); ret = -ENOMEM; -- 2.34.1