fix: proc: decouple proc from VFS with "struct proc_ops" (v5.6)
authorMichael Jeanson <mjeanson@efficios.com>
Tue, 11 Feb 2020 16:20:41 +0000 (11:20 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 25 Feb 2020 15:26:39 +0000 (10:26 -0500)
See upstream commit :

  commit d56c0d45f0e27f814e87a1676b6bdccccbc252e9
  Author: Alexey Dobriyan <adobriyan@gmail.com>
  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 <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lttng-abi.c
probes/lttng.c
tests/probes/lttng-test.c

index 7cf6b0f4aeafdb88a769142e7213256e07874685..811becf6fe023d487e95f67cd0db77fedac22cc4 100644 (file)
  */
 
 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;
@@ -364,13 +370,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,
@@ -1726,7 +1741,7 @@ int __init lttng_abi_init(void)
        }
 
        lttng_proc_dentry = proc_create_data("lttng", S_IRUSR | S_IWUSR, NULL,
-                                       &lttng_fops, NULL);
+                                       &lttng_proc_ops, NULL);
 
        if (!lttng_proc_dentry) {
                printk(KERN_ERR "Error creating LTTng control file\n");
index 09045fac18529702ad2ceac0ce7319c8cf2f549b..b63ffdf3e6fc9b2ecd12690652dd000099ea4b89 100644 (file)
@@ -105,6 +105,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
+
 int __init lttng_logger_init(void)
 {
        int ret = 0;
@@ -112,7 +124,7 @@ int __init lttng_logger_init(void)
        wrapper_vmalloc_sync_all();
        lttng_logger_dentry = proc_create_data(LTTNG_LOGGER_FILE,
                                S_IRUGO | S_IWUGO, NULL,
-                               &lttng_logger_operations, NULL);
+                               &lttng_logger_proc_ops, NULL);
        if (!lttng_logger_dentry) {
                printk(KERN_ERR "Error creating LTTng logger file\n");
                ret = -ENOMEM;
index 54be4c7c90a4c89cdfab81fa38c873b451057e80..7d7982b3cc2782f75716ef7637555952de1be3d8 100644 (file)
@@ -90,9 +90,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)
@@ -104,7 +110,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,
-                               &lttng_test_filter_event_operations, NULL);
+                               &lttng_test_filter_event_proc_ops, NULL);
        if (!lttng_test_filter_event_dentry) {
                printk(KERN_ERR "Error creating LTTng test filter file\n");
                ret = -ENOMEM;
This page took 0.027583 seconds and 4 git commands to generate.