Index: usr.sbin/kldxref/kldxref.c
===================================================================
--- usr.sbin/kldxref/kldxref.c
+++ usr.sbin/kldxref/kldxref.c
@@ -49,6 +49,7 @@
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <fts.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -657,6 +658,40 @@
 	return (fdopen(fd, "w+"));
 }
 
+/*
+ * Copy an existing file identified by its path to the path specified. The
+ * destination is first truncated if it already exists. On error, a warning
+ * is written to stderr with the details.
+ */
+static void
+copyfile(const char *src, const char *dst)
+{
+	int copy_result, src_fd, dst_fd;
+
+	src_fd = open(src, O_RDONLY);
+	if (src_fd < 0) {
+		warn("can't open %s", src);
+		return;
+	}
+	dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC);
+	if (dst_fd < 0) {
+		warn("can't create %s", dst);
+		close(src_fd);
+		return;
+	}
+
+	while ((copy_result = copy_file_range(src_fd, NULL, dst_fd, NULL,
+	    SSIZE_MAX, 0)) > 0) {
+		/* Continue until the entirety of the source has been copied */
+	}
+	if (copy_result < 0) {
+		warn("can't copy %s to %s", src, dst);
+	}
+
+	close(src_fd);
+	close(dst_fd);
+}
+
 static char xrefname[MAXPATHLEN], tempname[MAXPATHLEN];
 
 static void
@@ -732,7 +767,15 @@
 			fclose(fxref);
 			fxref = NULL;
 			if (reccnt != 0) {
-				rename(tempname, xrefname);
+				if (rename(tempname, xrefname) != 0) {
+					/* handle src/dst being on different filesystems */
+					if (errno == EXDEV) {
+						copyfile(tempname, xrefname);
+					} else {
+						warn("can't rename %s to %s", xrefname, tempname);
+					}
+					unlink(tempname);
+				}
 			} else {
 				/* didn't find any entry, ignore this file */
 				unlink(tempname);