diff --git a/gnu/packages/file-systems.scm b/gnu/packages/file-systems.scm
index fa7da35898..78121c1ec2 100644
--- a/gnu/packages/file-systems.scm
+++ b/gnu/packages/file-systems.scm
@@ -1444,7 +1444,6 @@ (define-public zfs
   (package
     (name "zfs")
     (version "2.2.4")
-    (outputs '("out" "module" "src"))
     (source
       (origin
         (method url-fetch)
@@ -1453,33 +1452,19 @@ (define-public zfs
                               "/zfs-" version ".tar.gz"))
           (sha256
            (base32 "1h0yqchirzsn2gll1w2gclb13hr8511z67lf85cigm43frgr144p"))))
-    (build-system linux-module-build-system)
+    (build-system gnu-build-system)
     (arguments
      (list
-      ;; The ZFS kernel module should not be downloaded since the license
-      ;; terms don't allow for distributing it, only building it locally.
-      #:substitutable? #f
-      ;; Tests cannot run in an unprivileged build environment.
-      #:tests? #f
+      #:configure-flags #~(list "--with-config=user"
+                                (string-append "--prefix=" #$output)
+                                (string-append "--with-dracutdir=" #$output
+                                               "/lib/dracut")
+                                (string-append "--with-udevdir=" #$output
+                                               "/lib/udev")
+                                (string-append "--with-mounthelperdir=" #$output
+                                               "/sbin"))
       #:phases
       #~(modify-phases %standard-phases
-          (add-after 'configure 'really-configure
-            (lambda* (#:key inputs #:allow-other-keys)
-              (substitute* "configure"
-                (("-/bin/sh") (string-append "-" (which "sh"))))
-              (invoke "./configure"
-                      "--with-config=all"
-                      (string-append "--prefix=" #$output)
-                      (string-append "--with-dracutdir=" #$output
-                                     "/lib/dracut")
-                      (string-append "--with-udevdir=" #$output
-                                     "/lib/udev")
-                      (string-append "--with-mounthelperdir=" #$output
-                                     "/sbin")
-                      (string-append "--with-linux="
-                                     (search-input-directory
-                                      inputs
-                                      "lib/modules/build")))))
           (add-after 'unpack 'patch-source
             (lambda* (#:key inputs #:allow-other-keys)
               ;; New feature "compatibility=" in 2.1.0.
@@ -1511,14 +1496,6 @@ (define-public zfs
                 ;; Just use 'modprobe' in message to user, since Guix
                 ;; does not have a traditional /sbin/
                 (("'/sbin/modprobe ") "'modprobe "))
-              (substitute* "configure"
-                (("/etc/default")
-                 (string-append #$output "/etc/default"))
-                (("/etc/bash_completion.d")
-                 (string-append #$output "/etc/bash_completion.d")))
-              (substitute* "Makefile.in"
-                (("/usr/share/initramfs-tools")
-                 (string-append #$output "/usr/share/initramfs-tools")))
               (substitute* "contrib/initramfs/Makefile.am"
                 (("/usr/share/initramfs-tools")
                  (string-append #$output "/usr/share/initramfs-tools")))
@@ -1548,31 +1525,22 @@ (define-public zfs
                                 (dirname (which "sed")) ":"
                                 (dirname (which "gawk")))))
               (substitute* '("Makefile.am" "Makefile.in")
-                (("\\$\\(prefix)/src") (string-append #$output:src "/src")))
+                (("@initconfdir@") (string-append #$output "/etc/default"))
+                (("/usr/share/initramfs-tools" dir) (string-append #$output dir)))
               (substitute* (find-files "udev/rules.d/" ".rules.in$")
                 (("/sbin/modprobe")
                  (search-input-file inputs "/bin/modprobe")))))
-          (replace 'build
-            (lambda _ (invoke "make")))
           (replace 'install
-            (lambda* (#:key inputs native-inputs #:allow-other-keys)
-              (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
-                (invoke "make" "install"
-                        (string-append "DEFAULT_INITCONF_DIR="
-                                       #$output "/etc/default")
-                        (string-append "DEPMOD="
-                                       (search-input-file
-                                        (or native-inputs inputs)
-                                        "/bin/depmod"))
-                        (string-append "INSTALL_PATH=" #$output)
-                        (string-append "INSTALL_MOD_PATH=" #$output:module)
-                        "INSTALL_MOD_STRIP=1")
-                (install-file
-                 "contrib/bash_completion.d/zfs"
-                 (string-append #$output
-                                "/share/bash-completion/completions"))))))))
+            (lambda _
+              (invoke "make" "install"
+                      (string-append "DEFAULT_INITCONF_DIR="
+                                     #$output "/etc/default")
+                      (string-append "INSTALL_PATH=" #$output)
+                      (string-append "bashcompletiondir="
+                                     #$output
+                                     "/share/bash-completion/completions")))))))
     (native-inputs
-     (list attr kmod pkg-config))
+     (list attr kmod pkg-config python))
     (inputs (list eudev
                   kmod
                   libaio
@@ -1592,6 +1560,58 @@ (define-public zfs
 community.")
     (license license:cddl1.0)))
 
+(define-public (make-zfs-for-kernel kernel-package)
+  (package
+    (inherit zfs)
+    (name (string-join (list (package-name zfs)
+                             "for"
+                             (package-name kernel-package)
+                             (package-version kernel-package)
+                             "version")
+                       "-"))
+    (build-system linux-module-build-system)
+    (arguments
+     (substitute-keyword-arguments
+         (strip-keyword-arguments '(#:configure-flags)
+                                  (package-arguments zfs))
+       ((#:linux _ #f) kernel-package)
+       ((#:substitutable? _ #t) #f)
+       ((#:phases phases)
+        #~(modify-phases %standard-phases
+            (add-after 'unpack 'patch-source
+              (assoc-ref #$phases 'patch-source))
+            (add-after 'configure 'really-configure
+              (lambda* (#:key inputs #:allow-other-keys)
+                (substitute* "configure"
+                  (("-/bin/sh") (string-append "-" (which "sh"))))
+                (invoke "./configure"
+                        "--with-config=kernel"
+                        (string-append "--prefix=" #$output)
+                        (string-append "--with-udevdir=" #$output
+                                       "/lib/udev")
+                        (string-append "--with-linux="
+                                       (search-input-directory
+                                        inputs
+                                        "lib/modules/build")))))
+            (replace 'build
+              (lambda* (#:key (make-flags '()) (parallel-build? #t)
+                        #:allow-other-keys)
+                (apply invoke "make"
+                       `(,@(if parallel-build?
+                               `("-j" ,(number->string (parallel-job-count)))
+                               '())
+                         ,@make-flags))))
+            (replace 'install
+              (lambda* (#:key inputs native-inputs #:allow-other-keys)
+                (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
+                  (invoke "make" "-C" "module" "install"
+                          (string-append "DEPMOD="
+                                         (search-input-file
+                                          (or native-inputs inputs)
+                                          "/bin/depmod"))
+                          (string-append "INSTALL_MOD_PATH=" #$output)
+                          "INSTALL_MOD_STRIP=1"))))))))))
+
 (define-public zfs-auto-snapshot
   (package
     (name "zfs-auto-snapshot")
