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:23:34 +0000 (10:23 -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 4df3d673b18c0d84e4d80047fdf096ed52a81350..9d610e9346f53c3669b5ca2b5c7de46475eed6d0 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;
@@ -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,
-                                       &lttng_fops, NULL);
+                                       &lttng_proc_ops, NULL);
 
        if (!lttng_proc_dentry) {
                printk(KERN_ERR "Error creating LTTng control file\n");
index c883429fa2e3401b83fb87181557213c008bdb40..383202c68efd8f4f46c6dd30302de5e935f6c54f 100644 (file)
@@ -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,
-                               &lttng_logger_operations, NULL);
+                               &lttng_logger_proc_ops, NULL);
        if (!lttng_logger_dentry) {
                printk(KERN_ERR "Error creating LTTng logger proc file\n");
                ret = -ENOMEM;
index d1278183ab417538b7fb654df49a009cf93db712..e3476393fe2753d541a9015b049d6a32ef690acf 100644 (file)
@@ -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,
-                               &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.028656 seconds and 4 git commands to generate.