]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Linux 6.5 compat: spl: properly unregister sysctl entries
authorAndrea Righi <andrea.righi@canonical.com>
Thu, 7 Sep 2023 21:36:32 +0000 (23:36 +0200)
committerGitHub <noreply@github.com>
Thu, 7 Sep 2023 21:36:32 +0000 (14:36 -0700)
When register_sysctl_table() is unavailable we fail to properly
unregister sysctl entries under "kernel/spl".

This leads to errors like the following when spl is unloaded/reloaded,
making impossible to properly reload the spl module:

[  746.995704] sysctl duplicate entry: /kernel/spl/kmem/slab_kvmem_total

Fix by cleaning up all the sub-entries inside "kernel/spl" when the
spl module is unloaded.

Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Brian Atkinson <batkinson@lanl.gov>
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
Closes #15239

module/os/linux/spl/spl-proc.c

index 5cb5a6dadb05bca8f8ff9d192807fcbe54115bc8..f0f929d3ce90e4052268903365cde3c68041d4e1 100644 (file)
@@ -47,6 +47,10 @@ static unsigned long table_min = 0;
 static unsigned long table_max = ~0;
 
 static struct ctl_table_header *spl_header = NULL;
+#ifndef HAVE_REGISTER_SYSCTL_TABLE
+static struct ctl_table_header *spl_kmem = NULL;
+static struct ctl_table_header *spl_kstat = NULL;
+#endif
 static struct proc_dir_entry *proc_spl = NULL;
 static struct proc_dir_entry *proc_spl_kmem = NULL;
 static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
@@ -668,6 +672,16 @@ static void spl_proc_cleanup(void)
        remove_proc_entry("taskq", proc_spl);
        remove_proc_entry("spl", NULL);
 
+#ifndef HAVE_REGISTER_SYSCTL_TABLE
+       if (spl_kstat) {
+               unregister_sysctl_table(spl_kstat);
+               spl_kstat = NULL;
+       }
+       if (spl_kmem) {
+               unregister_sysctl_table(spl_kmem);
+               spl_kmem = NULL;
+       }
+#endif
        if (spl_header) {
                unregister_sysctl_table(spl_header);
                spl_header = NULL;
@@ -688,12 +702,13 @@ spl_proc_init(void)
        if (spl_header == NULL)
                return (-EUNATCH);
 
-       if (register_sysctl("kernel/spl/kmem", spl_kmem_table) == NULL) {
+       spl_kmem = register_sysctl("kernel/spl/kmem", spl_kmem_table);
+       if (spl_kmem == NULL) {
                rc = -EUNATCH;
                goto out;
        }
-
-       if (register_sysctl("kernel/spl/kstat", spl_kstat_table) == NULL) {
+       spl_kstat = register_sysctl("kernel/spl/kstat", spl_kstat_table);
+       if (spl_kstat == NULL) {
                rc = -EUNATCH;
                goto out;
        }