git: b40746e8ead2 - stable/13 - kboot: Convert from getdents to getdents64

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 24 Jan 2023 22:11:33 UTC
The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=b40746e8ead296324dee20c50cb9d766dcdb0113

commit b40746e8ead296324dee20c50cb9d766dcdb0113
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-07-28 04:24:50 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-24 21:49:28 +0000

    kboot: Convert from getdents to getdents64
    
    Linux 2.4 introduced getdents64. Switch to using it because aarch64
    doesn't have getdents as that syscall was obsoleted before that port was
    created.
    
    Sponsored by:           Netflix
    
    (cherry picked from commit 3a1b966ae0c1b9f334e1e3a7ad8b4bf8e845f3c5)
---
 stand/kboot/arch/amd64/syscall_nr.h     |  2 +-
 stand/kboot/arch/powerpc64/syscall_nr.h |  2 +-
 stand/kboot/host_syscall.h              | 21 ++++++++++++++++++++-
 stand/kboot/host_syscalls.c             |  4 ++--
 stand/kboot/kbootfdt.c                  | 18 +++++-------------
 5 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/stand/kboot/arch/amd64/syscall_nr.h b/stand/kboot/arch/amd64/syscall_nr.h
index 4d8db2083ebc..71930001c1cf 100644
--- a/stand/kboot/arch/amd64/syscall_nr.h
+++ b/stand/kboot/arch/amd64/syscall_nr.h
@@ -1,6 +1,6 @@
 #define SYS_close		  3
 #define	SYS_dup			 32
-#define SYS_getdents		 78
+#define SYS_getdents64		217
 #define	SYS_getpid		 39
 #define SYS_gettimeofday	 96
 #define SYS_kexec_load		246
diff --git a/stand/kboot/arch/powerpc64/syscall_nr.h b/stand/kboot/arch/powerpc64/syscall_nr.h
index a467259e8b60..0702673c7228 100644
--- a/stand/kboot/arch/powerpc64/syscall_nr.h
+++ b/stand/kboot/arch/powerpc64/syscall_nr.h
@@ -1,7 +1,7 @@
 #define SYS_close		  6
 #define	SYS_dup			 41
 #define SYS_fstat		108
-#define SYS_getdents		141
+#define SYS_getdents64		202
 #define	SYS_getpid		 20
 #define SYS_gettimeofday	 78
 #define SYS_kexec_load		268
diff --git a/stand/kboot/host_syscall.h b/stand/kboot/host_syscall.h
index b867cd9f0d99..9f876952641e 100644
--- a/stand/kboot/host_syscall.h
+++ b/stand/kboot/host_syscall.h
@@ -131,13 +131,32 @@ struct host_kexec_segment {
 	int memsz;
 };
 
+struct host_dirent64 {
+	uint64_t	d_ino;		/* 64-bit inode number */
+	int64_t		d_off;		/* 64-bit offset to next structure */
+	unsigned short	d_reclen;	/* Size of this dirent */
+	unsigned char	d_type;		/* File type */
+	char		d_name[];	/* Filename (null-terminated) */
+};
+
+/* d_type values */
+#define HOST_DT_UNKNOWN		 0
+#define HOST_DT_FIFO		 1
+#define HOST_DT_CHR		 2
+#define HOST_DT_DIR		 4
+#define HOST_DT_BLK		 6
+#define HOST_DT_REG		 8
+#define HOST_DT_LNK		10
+#define HOST_DT_SOCK		12
+#define HOST_DT_WHT		14
+
 /*
  * System Calls
  */
 int host_close(int fd);
 int host_dup(int fd);
 int host_fstat(int fd, struct host_kstat *sb);
-int host_getdents(int fd, void *dirp, int count);
+int host_getdents64(int fd, void *dirp, int count);
 int host_getpid(void);
 int host_gettimeofday(struct host_timeval *a, void *b);
 int host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags);
diff --git a/stand/kboot/host_syscalls.c b/stand/kboot/host_syscalls.c
index 865107263d7b..771f9e128fdd 100644
--- a/stand/kboot/host_syscalls.c
+++ b/stand/kboot/host_syscalls.c
@@ -26,9 +26,9 @@ host_fstat(int fd, struct host_kstat *sb)
 }
 
 int
-host_getdents(int fd, void *dirp, int count)
+host_getdents64(int fd, void *dirp, int count)
 {
-	return host_syscall(SYS_getdents, fd, (uintptr_t)dirp, count);
+	return host_syscall(SYS_getdents64, fd, (uintptr_t)dirp, count);
 }
 
 int
diff --git a/stand/kboot/kbootfdt.c b/stand/kboot/kbootfdt.c
index 5e0ef9ea3068..e4e8e7cfbf04 100644
--- a/stand/kboot/kbootfdt.c
+++ b/stand/kboot/kbootfdt.c
@@ -40,30 +40,23 @@ add_node_to_fdt(void *buffer, const char *path, int fdt_offset)
 	void *propbuf;
 	ssize_t proplen;
 
-	struct host_dent {
-		unsigned long d_fileno;
-		unsigned long d_off;
-		unsigned short d_reclen;
-		char d_name[];
-		/* uint8_t	d_type; */
-	};
 	char dents[2048];
-	struct host_dent *dent;
+	struct host_dirent64 *dent;
 	int d_type;
 
 	fd = host_open(path, O_RDONLY, 0);
 	while (1) {
-		dentsize = host_getdents(fd, dents, sizeof(dents));
+		dentsize = host_getdents64(fd, dents, sizeof(dents));
 		if (dentsize <= 0)
 			break;
-		for (dent = (struct host_dent *)dents;
+		for (dent = (struct host_dirent64 *)dents;
 		     (char *)dent < dents + dentsize;
-		     dent = (struct host_dent *)((void *)dent + dent->d_reclen)) {
+		     dent = (struct host_dirent64 *)((void *)dent + dent->d_reclen)) {
 			sprintf(subpath, "%s/%s", path, dent->d_name);
 			if (strcmp(dent->d_name, ".") == 0 ||
 			    strcmp(dent->d_name, "..") == 0)
 				continue;
-			d_type = *((char *)(dent) + dent->d_reclen - 1);
+			d_type = dent->d_type;
 			if (d_type == 4 /* DT_DIR */) {
 				child_offset = fdt_add_subnode(buffer, fdt_offset,
 				    dent->d_name);
@@ -72,7 +65,6 @@ add_node_to_fdt(void *buffer, const char *path, int fdt_offset)
 					    child_offset, path, dent->d_name);
 					continue;
 				}
-		
 				add_node_to_fdt(buffer, subpath, child_offset);
 			} else {
 				propbuf = malloc(1024);