git: f382ef1dc82c - main - stand: update zfs_dnode_stat to use zfs_dnode_sa_lookup

From: Warner Losh <imp_at_FreeBSD.org>
Date: Sat, 03 Oct 2026 17:34:57 UTC
The branch main has been updated by imp:

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

commit f382ef1dc82cf0679b164be1e6cce51c022a204c
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-10-03 14:42:53 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-10-03 17:32:08 +0000

    stand: update zfs_dnode_stat to use zfs_dnode_sa_lookup
    
    Find the SA values with the zfs_dnode_sa_lookup and read out the
    relevant bits for the stat buffer.
    
    Sponsored by:           Netflix
    Differential Revision:  https://reviews.freebsd.org/D60267
---
 stand/libsa/zfs/zfsimpl.c | 54 ++++++++++++++---------------------------------
 1 file changed, 16 insertions(+), 38 deletions(-)

diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index 1eb1923fac49..a13f8d805049 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -3958,44 +3958,22 @@ zfs_dnode_stat(struct zfsmount *mount, dnode_phys_t *dn, struct stat *sb,
 		sb->st_gid = zp->zp_gid;
 		sb->st_size = zp->zp_size;
 	} else {
-		sa_hdr_phys_t *sahdrp;
-		int hdrsize;
-		size_t size = 0;
-		void *buf = NULL;
-
-		if (dn->dn_bonuslen != 0)
-			sahdrp = (sa_hdr_phys_t *)DN_BONUS(dn);
-		else {
-			if ((dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0) {
-				blkptr_t *bp = DN_SPILL_BLKPTR(dn);
-				int error;
-
-				size = BP_GET_LSIZE(bp);
-				buf = malloc(size);
-				if (buf == NULL)
-					error = ENOMEM;
-				else
-					error = zio_read(mount->spa, bp, buf);
-
-				if (error != 0) {
-					free(buf);
-					return (error);
-				}
-				sahdrp = buf;
-			} else {
-				return (EIO);
-			}
-		}
-		hdrsize = SA_HDR_SIZE(sahdrp);
-		sb->st_mode = *(uint64_t *)((char *)sahdrp + hdrsize +
-		    SA_MODE_OFFSET);
-		sb->st_uid = *(uint64_t *)((char *)sahdrp + hdrsize +
-		    SA_UID_OFFSET);
-		sb->st_gid = *(uint64_t *)((char *)sahdrp + hdrsize +
-		    SA_GID_OFFSET);
-		sb->st_size = *(uint64_t *)((char *)sahdrp + hdrsize +
-		    SA_SIZE_OFFSET);
-		free(buf);
+		uint64_t value;
+		size_t size;
+		int error;
+
+#define	SA_STAT(attr, field) do { \
+		size = sizeof(value); \
+		error = zfs_dnode_sa_lookup(mount, dn, attr, &value, &size); \
+		if (error != 0 || size != sizeof(value)) \
+			return (error != 0 ? error : EIO); \
+		sb->field = value; \
+} while (0)
+		SA_STAT(ZFS_SA_MODE, st_mode);
+		SA_STAT(ZFS_SA_UID, st_uid);
+		SA_STAT(ZFS_SA_GID, st_gid);
+		SA_STAT(ZFS_SA_SIZE, st_size);
+#undef SA_STAT
 	}
 
 	/*