git: 32fcc66dd311 - main - stand: Load dynamic system attribute offsets
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 03 Oct 2026 17:34:54 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=32fcc66dd311207451cd4916f9ed837ee19f9e07
commit 32fcc66dd311207451cd4916f9ed837ee19f9e07
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-10-03 14:42:38 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-10-03 17:32:08 +0000
stand: Load dynamic system attribute offsets
zfs_sa_load looks up all the system attribute offsets and stores them in
the mountpoint.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60264
---
stand/libsa/zfs/zfsimpl.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index 41b81e587a85..b9b5b227deec 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -43,12 +43,50 @@
extern int zstd_init(void);
#endif
+/*
+ * We have to map a series of strings to an index number that's varies
+ * filesystem by filesystem. We need all of these attributes, even though the
+ * loader only uses a few since the layout of the system attributes bundles
+ * varies file by file and to get to the one we want, we have to understand
+ * all the different element types.
+ */
+enum zfs_sa_attr_id {
+ ZFS_SA_ATIME,
+ ZFS_SA_MTIME,
+ ZFS_SA_CTIME,
+ ZFS_SA_CRTIME,
+ ZFS_SA_GEN,
+ ZFS_SA_MODE,
+ ZFS_SA_SIZE,
+ ZFS_SA_PARENT,
+ ZFS_SA_LINKS,
+ ZFS_SA_XATTR,
+ ZFS_SA_RDEV,
+ ZFS_SA_FLAGS,
+ ZFS_SA_UID,
+ ZFS_SA_GID,
+ ZFS_SA_PAD,
+ ZFS_SA_ZNODE_ACL,
+ ZFS_SA_DACL_COUNT,
+ ZFS_SA_SYMLINK,
+ ZFS_SA_SCANSTAMP,
+ ZFS_SA_DACL_ACES,
+ ZFS_SA_DXATTR,
+ ZFS_SA_PROJID,
+ ZFS_SA_SEQ,
+ ZFS_SA_COUNT
+};
+
struct zfsmount {
char *path;
const spa_t *spa;
objset_phys_t objset;
uint64_t rootobj;
uint64_t fsid_guid; /* mount's ds_fsid_guid */
+ dnode_phys_t sa_registry;
+ dnode_phys_t sa_layouts;
+ uint64_t sa_attrs[ZFS_SA_COUNT];
+ bool sa_loaded;
STAILQ_ENTRY(zfsmount) next;
};
@@ -3518,6 +3556,7 @@ zfs_mount_impl(const spa_t *spa, uint64_t rootobj, struct zfsmount *mount)
{
mount->spa = spa;
+ mount->sa_loaded = false;
/*
* Find the root object set if not explicitly provided
@@ -3712,6 +3751,89 @@ zfs_spa_init(spa_t *spa)
return (rc);
}
+static const char *zfs_sa_attrs[ZFS_SA_COUNT] = {
+ [ZFS_SA_ATIME] = "ZPL_ATIME",
+ [ZFS_SA_MTIME] = "ZPL_MTIME",
+ [ZFS_SA_CTIME] = "ZPL_CTIME",
+ [ZFS_SA_CRTIME] = "ZPL_CRTIME",
+ [ZFS_SA_GEN] = "ZPL_GEN",
+ [ZFS_SA_MODE] = "ZPL_MODE",
+ [ZFS_SA_SIZE] = "ZPL_SIZE",
+ [ZFS_SA_PARENT] = "ZPL_PARENT",
+ [ZFS_SA_LINKS] = "ZPL_LINKS",
+ [ZFS_SA_XATTR] = "ZPL_XATTR",
+ [ZFS_SA_RDEV] = "ZPL_RDEV",
+ [ZFS_SA_FLAGS] = "ZPL_FLAGS",
+ [ZFS_SA_UID] = "ZPL_UID",
+ [ZFS_SA_GID] = "ZPL_GID",
+ [ZFS_SA_PAD] = "ZPL_PAD",
+ [ZFS_SA_ZNODE_ACL] = "ZPL_ZNODE_ACL",
+ [ZFS_SA_DACL_COUNT] = "ZPL_DACL_COUNT",
+ [ZFS_SA_SYMLINK] = "ZPL_SYMLINK",
+ [ZFS_SA_SCANSTAMP] = "ZPL_SCANSTAMP",
+ [ZFS_SA_DACL_ACES] = "ZPL_DACL_ACES",
+ [ZFS_SA_DXATTR] = "ZPL_DXATTR",
+ [ZFS_SA_PROJID] = "ZPL_PROJID",
+ [ZFS_SA_SEQ] = "ZPL_SEQ",
+};
+
+#define ZFS_SA_MAX_ATTRS 256
+
+/*
+ * Populate the sa_attrs array with the per-filesystem index
+ * numbers used to decode the system attribute bundles.
+ */
+static int
+zfs_sa_load(struct zfsmount *mount)
+{
+ dnode_phys_t master, sa_master;
+ uint64_t sa_object, registry, layouts;
+ int error;
+
+ if (mount->sa_loaded)
+ return (0);
+
+ error = objset_get_dnode(mount->spa, &mount->objset, MASTER_NODE_OBJ,
+ &master);
+ if (error != 0)
+ return (error);
+ error = zap_lookup(mount->spa, &master, ZFS_SA_ATTRS,
+ sizeof(sa_object), 1, &sa_object);
+ if (error != 0)
+ return (error);
+ error = objset_get_dnode(mount->spa, &mount->objset, sa_object,
+ &sa_master);
+ if (error != 0)
+ return (error);
+ error = zap_lookup(mount->spa, &sa_master, SA_REGISTRY,
+ sizeof(registry), 1, ®istry);
+ if (error != 0)
+ return (error);
+ error = zap_lookup(mount->spa, &sa_master, SA_LAYOUTS,
+ sizeof(layouts), 1, &layouts);
+ if (error != 0)
+ return (error);
+ error = objset_get_dnode(mount->spa, &mount->objset, registry,
+ &mount->sa_registry);
+ if (error != 0)
+ return (error);
+ error = objset_get_dnode(mount->spa, &mount->objset, layouts,
+ &mount->sa_layouts);
+ if (error != 0)
+ return (error);
+
+ for (unsigned int i = 0; i < nitems(zfs_sa_attrs); i++) {
+ error = zap_lookup(mount->spa, &mount->sa_registry,
+ zfs_sa_attrs[i], sizeof(mount->sa_attrs[i]), 1,
+ &mount->sa_attrs[i]);
+ if (error != 0)
+ mount->sa_attrs[i] = UINT64_MAX;
+ }
+
+ mount->sa_loaded = true;
+ return (0);
+}
+
static int
zfs_dnode_stat(struct zfsmount *mount, dnode_phys_t *dn, struct stat *sb,
uint64_t fsid_guid, uint64_t objnum)