ZFS acltype: POSIX vs NFSv4 ACLs Without Confusion

Was this helpful?

If you’ve run ZFS in production long enough, you’ve watched permissions turn into a social experiment: one admin “fixes” access with chmod -R, a Windows user changes an ACL in Explorer, an NFS client caches something “helpfully,” and suddenly the helpdesk is melting while the storage team insists “ZFS is fine.” ZFS usually is fine. It’s our mental model that’s broken.

This article is that mental model, rebuilt for people who ship systems: what acltype actually means, how POSIX ACLs differ from NFSv4 ACLs in ways that matter, how SMB and NFS behave, what to set on new datasets, and how to debug the inevitable “Permission denied” in minutes instead of hours.

The decision you’re really making

On ZFS, acltype isn’t a cosmetic preference. It’s a declaration of what permission language the dataset will speak natively and what semantics ZFS will preserve when you do things like chmod, chown, and create new files inside directories with inherited ACLs.

In plain terms:

  • POSIX ACLs extend classic UNIX mode bits and users/groups with a familiar model. They’re great for Linux/Unix workflows, automation, and “what you see in ls -l is basically the story.” But the mask, default ACLs, and limited inheritance rules surprise people regularly.
  • NFSv4 ACLs are richer, closer to Windows ACL semantics, and have explicit inheritance flags. They map better to SMB, mixed environments, and “real enterprise file server” expectations. They also bring more ways to shoot yourself in the foot—more expressiveness means more wrong combinations.

The best way to choose is not “what do I like?” but “which client ecosystem must be the source of truth?” If SMB/Windows is your control plane, NFSv4 ACLs reduce impedance mismatch. If Linux automation and mode-bit simplicity is your control plane, POSIX ACLs keep your on-call life calmer.

One joke, because we’ve earned it: POSIX ACLs are like a pocketknife—simple, handy, and you will eventually cut yourself if you forget the mask exists.

Facts & history that explain today’s mess

Permissions are political history encoded into kernels. A few context points help explain why ZFS ends up feeling “mystical” here.

  1. Classic UNIX permissions predate networks. The owner/group/other bits were designed for multi-user time-sharing, not for cross-domain identity or GUI ACL editors.
  2. POSIX ACLs were a pragmatic patch. They extended the mode-bit model without replacing it, which is why the mask exists: it preserves the idea that mode bits still matter.
  3. NFSv4 ACLs were built with networked filesystems in mind. They include named users/groups, richer allow/deny semantics, and inheritance flags that behave more like Windows.
  4. Windows ACLs influenced NFSv4 ACL design. Not identical, but similar enough that mapping is feasible—important for SMB servers sitting on top of ZFS.
  5. “Deny” ACEs are not a UNIX tradition. In NFSv4, deny entries can short-circuit allow rules depending on order and evaluation model; in POSIX ACLs, you don’t really have an equivalent.
  6. SMB has always cared about ACL fidelity. Windows clients expect inheritance, explicit vs inherited flags, and stable semantics when changing permissions via GUI.
  7. ZFS originally targeted Solaris enterprise workloads. The expectation was mixed clients, centralized storage, and strong metadata features—including ACL support that wasn’t an afterthought.
  8. Linux ACL tooling grew up around POSIX ACLs. getfacl/setfacl are ubiquitous, and people expect them to work everywhere, even when the underlying filesystem is speaking NFSv4 ACLs.
  9. Identity mapping is a separate war. ACLs can be perfect; if your UID/GID/SID mapping is wrong, permissions will still fail. Many “ZFS ACL bugs” are actually directory services bugs.

ZFS properties that control ACL reality

acltype is only one knob. The combination of ACL properties determines how ZFS stores ACLs, how it treats chmod/chown, and how inheritance is applied.

acltype

What it is: The ACL model used for the dataset. Common values depend on platform:

  • POSIX: often represented as posixacl on Linux ZFS implementations.
  • NFSv4: often represented as nfsv4.

What it changes: How ACLs are interpreted and which tools/semantics behave natively. It also affects how SMB servers can present and store ACLs.

aclmode

What it is: What ZFS does when you run chmod on a file that has an ACL. This is the number one source of “chmod didn’t do what I think it did.”

Typical behaviors (names vary by platform, but the semantics hold):

  • discard: throw away ACL entries that don’t fit the new mode. Dangerous for rich ACL environments.
  • groupmask: maintain ACLs but treat group permissions conservatively based on the mode bits (common default in some environments).
  • passthrough: let chmod adjust mode bits without trying to “fix” ACLs. Often best if you manage ACLs explicitly and do not want chmod to rewrite them.
  • restricted: prevent chmod from making ACLs more permissive than they were. Good for safety; surprising for “I’m root, why can’t I?” moments.

aclinherit

What it is: How ACLs on directories are inherited by new files/directories created inside them.

This is where NFSv4 ACLs shine: they have explicit inheritance flags, so you can get predictable “this folder behaves like a Windows share” outcomes. POSIX can do default ACLs, but it’s less expressive and easy to misapply.

xattr and sa

ACLs usually live in extended attributes. ZFS can store xattrs in “system attributes” (SA) for performance (xattr=sa on many systems). This can be a legitimate performance win for metadata-heavy workloads—but it doesn’t make permissions simpler, and it can affect how you think about replication and compatibility.

case sensitivity and normalization

Not an ACL property, but if you’re mixing Windows and Unix clients, casesensitivity and Unicode normalization can trigger access-path confusion that looks like permission trouble. You’ll swear a user “has access” but they’re hitting a different path than the one you audited.

POSIX vs NFSv4 ACLs: practical differences

Mental model: what “permission” means

POSIX ACLs answer: “Given an owning user, owning group, mode bits, and optional additional user/group entries, is this operation allowed?” The POSIX ACL mask effectively caps the permissions of named users/groups and the group class. If you forget the mask, you will mis-audit access.

NFSv4 ACLs answer: “Given a list of ordered access control entries (ACEs) with allow/deny and rich rights, plus inheritance rules, is this operation allowed?” It’s more like a firewall ruleset for files. Order matters more. “Deny” exists. Inheritance is first-class.

Inheritance: default ACLs vs explicit flags

POSIX uses “default ACLs” on directories. When a new file is created, those default entries can become access ACL entries on the child, subject to umask and mask behavior. It works, but it’s not as expressive as Windows-like inheritance.

NFSv4 has inheritance flags directly on ACEs: apply to files, to directories, only to children, etc. This is why Windows-on-ZFS setups typically prefer NFSv4 ACLs: the mental model matches what Explorer does.

Expressiveness: rights granularity

POSIX permissions are coarse: read/write/execute plus some special bits. POSIX ACLs largely mirror that: they extend “who” but not “what.”

NFSv4 breaks “what” into a bunch of distinct rights: read data, write data, append, delete, read attributes, write attributes, read ACL, write ACL, take ownership, and more. That’s powerful and dangerous: you can create a file that someone can write but not delete, or can read but not list directory contents, depending on which rights you assign.

Tooling: what your admins will actually use

POSIX wins in everyday CLI tooling. Most Linux admins can reason about chmod, chown, getfacl, setfacl. The trap is that they’ll use these tools in a dataset where they shouldn’t, and things will half-work.

NFSv4 tooling varies. Some environments use nfs4_getfacl/nfs4_setfacl. SMB environments often manage ACLs via Windows tools. That’s fine—until a well-meaning Linux admin runs chmod -R and “cleans up” the carefully-crafted ACE order.

Joke #2 (and that’s all you’re getting)

NFSv4 ACLs are like a programmable thermostat: incredibly capable, and somehow the office is still freezing because one person discovered “schedule overrides.”

SMB, NFS, and “it worked on my client”

Most ACL incidents happen at the protocol boundary. ZFS stores something; SMB and NFS present something; your admins change something; and the mapping logic tries its best.

SMB on ZFS: where NFSv4 ACLs usually make sense

If your dataset backs an SMB share and Windows users manage permissions, you want ACL semantics that resemble Windows. NFSv4 ACLs tend to map more cleanly to Windows-style inheritance and rights. You still need consistent identity mapping (SIDs to Unix IDs, depending on your stack), but the “shape” of the ACL fits the client’s expectations.

What usually breaks is not “ACLs don’t work,” but “ACLs work differently than mode bits.” Windows admins expect that removing “Write” removes the ability to create files, modify attributes, delete, etc. If your mapping collapses multiple rights into a single bit, you can create weird edge cases: can write but can’t rename; can create but can’t delete; can traverse but can’t list.

NFS on ZFS: pick the semantics your clients understand

NFSv3 clients largely live in a mode-bit universe. NFSv4 clients can handle NFSv4 ACLs, but whether your client tooling and admin practices do is a separate question. If you run NFS for Linux application servers, POSIX ACLs are often the least surprising option—provided you set aclmode and aclinherit to match your operational reality.

Mixed SMB + NFS: decide who is authoritative

The cleanest mixed setup is one where a single system is authoritative for ACL edits. Common patterns:

  • Windows authoritative: NFSv4 ACLs, edits via SMB, NFS clients mostly consume. Linux admins are trained not to “fix” with chmod.
  • Unix authoritative: POSIX ACLs, edits via CLI and config management, SMB (if present) is treated as a compatibility view with limited expectations.

If you allow both sides to freely edit permissions, you’re not building a file server—you’re building a time machine that randomly revisits old ACL states.

Three corporate-world mini-stories

Mini-story 1: an incident caused by a wrong assumption

The setup looked standard: ZFS dataset backing an SMB share for a finance team, plus NFS mounts for a batch job that generated nightly reports. Someone created a new “Reports” folder, copied last year’s structure, and everything seemed fine. Then, right after month-end close, the batch job started failing with “Permission denied” when writing files—only in one subfolder.

The on-call admin did what many of us would do at 2 a.m.: chmod -R g+rwX on the folder tree. It “worked” for the Linux job, but the next morning Windows users reported they couldn’t change permissions anymore, and some inherited permissions vanished. Now the incident had a second act.

The wrong assumption was that mode bits were the source of truth. The dataset had NFSv4 ACLs tuned for Windows inheritance. chmod wasn’t just changing the mode—it was triggering aclmode behavior that effectively rewrote parts of the ACLs to match the new mode. The Linux job was saved by accident; the Windows ACL structure was collateral damage.

The fix was boring and surgical: restore ACLs from a snapshot for the affected subtree, set a dedicated service principal for the batch job, and grant explicit rights via the NFSv4 ACL model (or via SMB with consistent identity mapping). The long-term fix was cultural: “chmod is not an ACL editor” became a runbook rule on that storage.

Mini-story 2: an optimization that backfired

A platform team wanted faster metadata operations on a busy home-directory pool: lots of small files, constant ACL checks, and users complaining about slow directory listings. Someone suggested enabling SA-based xattrs (the classic “store xattrs more efficiently” tuning) and making ACLs “more compatible” by switching ACL handling and inheritance defaults to match the SMB side.

Performance improved—briefly. The real backfire came weeks later during a replication test and a restore drill. A subset of restored datasets showed subtly different ACL behavior: certain directories were inheriting permissions differently than before, and a handful of service accounts lost the ability to traverse paths they used daily. No one noticed in staging because test data didn’t include the weird edge cases: deep directory trees with mixed explicit and inherited ACEs.

The root cause wasn’t that SA was “bad.” It was that the team combined multiple changes (xattr storage, ACL inheritance behavior, and admin workflows) and validated only “fast” and “seems accessible.” In other words: they optimized the easy metric and skipped the hard one—semantic equivalence.

The recovery was straightforward but painful: back out the ACL behavior changes first, re-test replication with ACL verification (not just file counts), then reintroduce performance tuning one knob at a time. The lesson: performance tuning is easy; proving you didn’t change meaning is the real engineering.

Mini-story 3: a boring but correct practice that saved the day

A storage team ran a multi-tenant ZFS platform for internal apps: NFS for Linux services, SMB for a few legacy teams. They had one unglamorous rule: every dataset had an “intent label” documented in the dataset properties and mirrored in naming—something like apps-posix versus shares-nfsv4. They also had a CI check in infrastructure-as-code that refused to create a dataset without explicit acltype, aclmode, and aclinherit settings.

One Friday, a project requested “just a quick share” for a vendor dropbox. A well-meaning engineer cloned an existing dataset and exported it via SMB. Vendors could upload, but internal users couldn’t read the files afterward. It smelled like identity mapping, but the team didn’t chase ghosts.

They checked the dataset’s intent label first. It was a POSIX-oriented dataset cloned from an application export. The SMB share was a mistake at the architecture level, not a permissions tweak. They created a new NFSv4-oriented dataset for the dropbox, moved the data, and stopped trying to make one dataset satisfy conflicting semantics.

No heroics, no weekend-long ACL archaeology. The “boring” practice—explicit intent and enforced properties—turned a potential outage into a small, reversible change.

Hands-on tasks (commands + interpretation)

The commands below assume a Linux system with ZFS utilities installed. Some environments differ slightly in property names and available tools, but the operational logic carries across platforms. Each task includes what you’re looking for and how to interpret it.

Task 1: Identify dataset ACL model and related properties

cr0x@server:~$ sudo zfs get -r acltype,aclmode,aclinherit,xattr pool/share
NAME        PROPERTY    VALUE        SOURCE
pool/share  acltype     nfsv4        local
pool/share  aclmode     restricted   local
pool/share  aclinherit  passthrough  local
pool/share  xattr       sa           local

Interpretation: This dataset is NFSv4 ACL-native. aclmode=restricted means chmod will be constrained; aclinherit=passthrough suggests inheritance behavior is designed to preserve ACE intent. xattr=sa means xattrs (often including ACLs) are stored efficiently in SA, which can help metadata-heavy workloads.

Task 2: Confirm whether files have ACLs beyond mode bits

cr0x@server:~$ ls -l /pool/share/project
total 4
drwxrwx---+  5 root finance 5 Dec 24 09:10 Reports
-rw-r-----+  1 root finance 0 Dec 24 09:10 readme.txt

Interpretation: The + indicates an ACL exists. Mode bits alone won’t tell the full story.

Task 3: Read POSIX ACLs with getfacl (POSIX datasets)

cr0x@server:~$ getfacl -p /pool/posixdata/team
# file: /pool/posixdata/team
# owner: root
# group: team
user::rwx
group::r-x
other::---
default:user::rwx
default:group::r-x
default:other::---

Interpretation: Default ACLs exist, so new children inherit these as a starting point. If there’s a mask:: entry, remember it caps effective permissions for named users/groups and the group class.

Task 4: Show the mask effect (classic POSIX ACL surprise)

cr0x@server:~$ setfacl -m u:alice:rwx /pool/posixdata/team
cr0x@server:~$ getfacl -p /pool/posixdata/team | sed -n '1,12p'
# file: /pool/posixdata/team
# owner: root
# group: team
user::rwx
user:alice:rwx
group::r-x
mask::r-x
other::---

Interpretation: Alice has rwx in the ACL entry, but the effective permissions are capped by mask::r-x. If Alice can’t write, the mask is the first suspect.

Task 5: Fix the mask intentionally (not by accident)

cr0x@server:~$ setfacl -m m::rwx /pool/posixdata/team
cr0x@server:~$ getfacl -p /pool/posixdata/team | grep -E 'user:alice|mask::'
user:alice:rwx
mask::rwx

Interpretation: You’ve widened the effective permissions ceiling. Do this knowingly; masks are there to preserve mode-bit style constraints.

Task 6: Inspect NFSv4 ACLs (NFSv4 datasets)

cr0x@server:~$ nfs4_getfacl /pool/share/project/Reports
A::OWNER@:rwatTnNcCy
A::GROUP@:rxtncy
A::EVERYONE@:tncy

Interpretation: You’re looking at ACEs. The letters represent rights; exact sets vary. Pay attention to whether permissions are granted to OWNER@, GROUP@, or named principals, and whether there are deny entries (which would be shown with D in many outputs).

Task 7: Check whether ACL inheritance is configured at the dataset level

cr0x@server:~$ sudo zfs get aclinherit pool/share
NAME       PROPERTY    VALUE        SOURCE
pool/share aclinherit  passthrough  local

Interpretation: passthrough generally means ZFS will try not to “simplify” inherited ACEs. If you’re seeing inheritance stripped or altered, this property is part of the explanation.

Task 8: See what chmod does on an ACL-bearing file (and why it surprises)

cr0x@server:~$ sudo zfs get aclmode pool/share
NAME       PROPERTY  VALUE       SOURCE
pool/share aclmode   restricted  local

cr0x@server:~$ chmod 777 /pool/share/project/readme.txt
chmod: changing permissions of '/pool/share/project/readme.txt': Operation not permitted

Interpretation: With aclmode=restricted, chmod may be prevented from making the file more permissive than its ACL allows. This is a safety feature, but it’s also a debugging clue: if chmod fails or “does nothing,” check aclmode and the ACL itself.

Task 9: Confirm who ZFS thinks owns the file and group (identity sanity)

cr0x@server:~$ stat -c '%n owner=%U(%u) group=%G(%g) mode=%a' /pool/share/project/Reports
/pool/share/project/Reports owner=root(0) group=finance(10025) mode=770

Interpretation: If you see numeric IDs where you expected names (or wrong names), you likely have an identity mapping problem, not an ACL problem. Fix identity first or you’ll apply ACLs to the wrong principals.

Task 10: Trace an access failure from the client’s perspective

cr0x@server:~$ sudo -u alice bash -lc 'cd /pool/share/project/Reports && touch testfile'
touch: cannot touch 'testfile': Permission denied

Interpretation: Reproducing as the user removes guesswork. If Alice can’t create, you’re debugging directory write/create rights (not file rights). With NFSv4 ACLs, you may need specific rights like “add file” equivalents; with POSIX, you need write+execute on the directory.

Task 11: Snapshot before ACL surgery (cheap insurance)

cr0x@server:~$ sudo zfs snapshot pool/share@before-acl-fix
cr0x@server:~$ sudo zfs list -t snapshot -o name,creation | grep 'pool/share@before-acl-fix'
pool/share@before-acl-fix  Wed Dec 24 09:35 2025

Interpretation: ACL work is reversible if you snapshot first. This is the difference between “we’ll fix it quickly” and “we’ll be here all night.”

Task 12: Compare ACLs across two directories to spot drift

cr0x@server:~$ getfacl -p /pool/posixdata/team > /tmp/team.acl
cr0x@server:~$ getfacl -p /pool/posixdata/team-archive > /tmp/team-archive.acl
cr0x@server:~$ diff -u /tmp/team.acl /tmp/team-archive.acl | sed -n '1,80p'
--- /tmp/team.acl
+++ /tmp/team-archive.acl
@@
 group::r-x
-mask::rwx
+mask::r-x

Interpretation: A single mask difference can explain why “it works in one folder but not the other.” This is a fast way to catch the subtle changes that happen after “quick fixes.”

Task 13: Audit dataset mountpoint and ensure you’re editing the right path

cr0x@server:~$ sudo zfs get mountpoint pool/share
NAME       PROPERTY    VALUE         SOURCE
pool/share mountpoint  /pool/share   local

cr0x@server:~$ mount | grep '/pool/share'
pool/share on /pool/share type zfs (rw,xattr,noacl)

Interpretation: Confirm the dataset you think you’re changing is the one mounted where you think it is. Editing a bind-mounted path or a different dataset is a classic self-own. (Note: mount options shown vary by platform.)

Task 14: Verify that inheritance on a directory is doing what you think

cr0x@server:~$ mkdir -p /pool/posixdata/team/newdir
cr0x@server:~$ touch /pool/posixdata/team/newdir/newfile
cr0x@server:~$ getfacl -p /pool/posixdata/team/newdir | sed -n '1,25p'
# file: /pool/posixdata/team/newdir
# owner: root
# group: team
user::rwx
group::r-x
other::---
default:user::rwx
default:group::r-x
default:other::---

Interpretation: If the default ACL isn’t present on the new directory, inheritance isn’t set the way you think, or a creation process is overriding it. For NFSv4, you would do the equivalent by inspecting inherited ACEs on child objects.

Fast diagnosis playbook

This is the triage flow I use when “permissions are broken” hits a storage/SRE queue. The goal is to find the real bottleneck quickly: semantics mismatch, identity mismatch, or a property/tooling mismatch.

First: confirm what permission model you’re in

  1. Check dataset properties: acltype, aclmode, aclinherit, xattr.
  2. Confirm the object has an ACL (+ in ls -l), and fetch the ACL using the right tool (getfacl for POSIX; nfs4_getfacl for NFSv4 where applicable).

If you skip this and jump straight to chmod/chown, you’re debugging blind.

Second: reproduce as the user and identify the operation

  1. Reproduce with sudo -u user locally (or equivalent) to confirm it’s not a client cache or application bug.
  2. Determine the operation that fails: directory traversal, list, create, rename, delete, read, write, change attributes.

Different operations map to different rights. “Can write file but can’t rename” is a directory permission issue, not a file permission issue.

Third: validate identity mapping before rewriting ACLs

  1. Check ownership via stat and confirm expected UID/GID resolution.
  2. In mixed environments, confirm the user is represented consistently across SMB/NFS/Linux. If “alice” is UID 1001 on Linux but maps differently through directory services, your ACL edits might target the wrong principal.

Fourth: check whether dataset-level properties are rewriting your intent

  1. If chmod appears to “fail” or “not stick,” check aclmode.
  2. If new files don’t inherit expected permissions, check aclinherit and whether the parent directory has default ACLs (POSIX) or inheritable ACEs (NFSv4).

Fifth: only then, change permissions—minimally and reversibly

  1. Snapshot first.
  2. Change the smallest scope that fixes the problem.
  3. Verify from both client types if you’re in a mixed environment.

Common mistakes, symptoms, fixes

Mistake 1: Treating chmod as an ACL editor on NFSv4 datasets

Symptoms: Windows inheritance breaks; ACLs “simplify”; permissions drift after a Linux-side chmod; chmod errors out with “Operation not permitted.”

Fix: Stop using chmod for policy changes on NFSv4 datasets. Use NFSv4 ACL tooling or SMB/Windows ACL management consistently. Review aclmode; consider passthrough behavior if your environment requires chmod not to rewrite ACLs, but only if you understand the security implications.

Mistake 2: Forgetting the POSIX ACL mask exists

Symptoms: getfacl shows user:alice:rwx but Alice can’t write; “it looks like rwx but behaves like r-x.”

Fix: Check mask::. Adjust it deliberately with setfacl -m m::rwx (or the least permissive mask that meets requirements). Educate operators: the mask caps effective rights.

Mistake 3: Assuming “group write” means “can delete files”

Symptoms: User can create files but can’t delete/rename, or vice versa, depending on directory permissions and sticky bit behavior; on NFSv4, rights don’t map cleanly to “write.”

Fix: Debug directory permissions separately from file permissions. On POSIX: directory needs write+execute for create/delete/rename; sticky bit changes delete semantics. On NFSv4: ensure the directory ACEs include rights appropriate for delete/rename/add-file operations.

Mistake 4: Mixing SMB-side ACL edits with Linux-side setfacl on the same dataset

Symptoms: Permissions oscillate; inherited ACE flags disappear; Windows shows “weird” entries; Linux shows ACLs that don’t correspond to Windows intent.

Fix: Decide an authoritative editor path. If SMB is authoritative, manage ACLs via SMB/Windows tools and keep Linux changes minimal and procedural. If Linux is authoritative, keep SMB expectations limited and document them.

Mistake 5: Applying recursive permission changes without snapshots

Symptoms: Broad outages; you “fixed” one service and broke ten others; rollback is hand-crafted and slow.

Fix: Snapshot before recursion. If you must do recursive changes, test on a small subtree, validate clients, then proceed.

Mistake 6: Debugging permissions before debugging identity

Symptoms: ACLs look correct but access is denied; names resolve inconsistently; files show numeric owners; SMB users appear as unexpected IDs on the server.

Fix: Validate UID/GID/SID mapping. Ensure consistent directory service configuration. ACL correctness is meaningless if principals don’t map to the intended identities.

Mistake 7: Confusing “traverse” with “list” on directories

Symptoms: User can access a known file path but can’t list the directory; or the inverse, can list but can’t enter.

Fix: On POSIX: execute on a directory is traverse; read is list. On NFSv4: ensure ACEs include appropriate rights for listing vs traversing.

Checklists / step-by-step plans

Checklist: choosing acltype for a new dataset

  1. Identify primary client protocol: SMB-first or NFS/Linux-first.
  2. Decide authoritative ACL editor: Windows tools or Linux CLI/IaC.
  3. Select acltype: NFSv4 for SMB-first; POSIX for Linux-first.
  4. Set aclmode intentionally: if you want chmod to be constrained, use restricted-like behavior; if you want chmod to avoid rewriting ACLs, choose passthrough-like behavior (with caution).
  5. Set aclinherit intentionally: pick a mode that preserves inheritance semantics you actually want.
  6. Decide xattr storage: consider xattr=sa for metadata-heavy workloads; validate compatibility in your environment.
  7. Document intent: include it in dataset naming or properties so operators know which rules apply.

Step-by-step: create a POSIX-ACL oriented dataset for Linux apps

cr0x@server:~$ sudo zfs create -o acltype=posixacl -o xattr=sa pool/apps
cr0x@server:~$ sudo zfs set aclmode=groupmask pool/apps
cr0x@server:~$ sudo zfs set aclinherit=passthrough pool/apps
cr0x@server:~$ sudo zfs get acltype,aclmode,aclinherit,xattr pool/apps
NAME      PROPERTY    VALUE        SOURCE
pool/apps acltype     posixacl     local
pool/apps aclmode     groupmask    local
pool/apps aclinherit  passthrough  local
pool/apps xattr       sa           local

Interpretation: This is a sane baseline for Linux environments that use POSIX ACLs. You may choose different aclmode/aclinherit depending on policy, but the point is: set them explicitly, don’t inherit defaults blindly.

Step-by-step: create an NFSv4-ACL oriented dataset for SMB shares

cr0x@server:~$ sudo zfs create -o acltype=nfsv4 -o xattr=sa pool/shares
cr0x@server:~$ sudo zfs set aclmode=restricted pool/shares
cr0x@server:~$ sudo zfs set aclinherit=passthrough pool/shares
cr0x@server:~$ sudo zfs get acltype,aclmode,aclinherit,xattr pool/shares
NAME        PROPERTY    VALUE        SOURCE
pool/shares acltype     nfsv4        local
pool/shares aclmode     restricted   local
pool/shares aclinherit  passthrough  local
pool/shares xattr       sa           local

Interpretation: This aligns with “SMB/Windows is authoritative.” It reduces the chance that a chmod on the host will accidentally broaden access. It does not replace the need for consistent identity mapping.

Step-by-step: permission incident response (safe procedure)

  1. Snapshot the affected dataset or at least the smallest dataset boundary that contains the impacted path.
  2. Capture current ACLs from a few representative paths into text files.
  3. Reproduce the failure as the user and determine the failing operation.
  4. Fix identity mapping issues first if present.
  5. Apply minimal ACL changes using the correct model/tooling.
  6. Verify from each relevant client type (SMB and/or NFS) and from local shell.
  7. Document what changed and why; ACL drift without documentation is a repeat incident.

FAQ

1) What exactly does acltype change on ZFS?

It selects the ACL semantics ZFS will use for that dataset: POSIX ACL behavior (mask, default ACLs) versus NFSv4 ACL behavior (ACE lists with inheritance flags and richer rights). It influences how ACLs are stored and how permission-modifying operations interact with existing ACLs.

2) If I use NFSv4 ACLs, can I still use chmod and chown?

You can, but you must understand aclmode. In many setups, chmod is constrained or prevented from making changes that conflict with the ACL policy. If your organization expects “chmod fixes everything,” NFSv4 datasets will generate tickets unless you retrain workflows.

3) Why does ls -l show permissions that don’t match reality?

Because mode bits are only part of the story when ACLs exist. With POSIX ACLs, the mask can cap effective permissions. With NFSv4 ACLs, the mode bits are often a summary view and not a complete representation of rights like delete, rename, or write-ACL.

4) Should I use POSIX ACLs for NFS shares?

Often yes for NFSv3-heavy Linux environments, because the operational model aligns. For NFSv4 clients that truly use NFSv4 ACLs end-to-end, NFSv4 ACLs can be a good fit—but only if your client tooling and admin habits match that world.

5) Should I use NFSv4 ACLs for SMB shares?

In most mixed Windows environments, yes. NFSv4 ACLs tend to preserve Windows-like inheritance semantics better and avoid lossy mappings. The caveat is identity mapping: if your users/groups don’t map consistently, the best ACL model won’t save you.

6) Can I switch acltype on an existing dataset safely?

“Safely” depends on what exists in the dataset and how clients depend on current semantics. Switching models can change how ACLs are interpreted or represented. In production, treat it like a migration: snapshot, test on a clone, validate with real workloads, and expect edge cases.

7) Why do some users have “write” but can’t delete files?

On POSIX, delete is controlled by the directory permissions (and sticky bit rules), not the file’s writable bit. On NFSv4, delete/rename rights can be separate from write data rights. Diagnose directory ACLs/permissions, not just file ACLs.

8) What’s the quickest way to debug “Permission denied”?

Confirm acltype and fetch the ACL using the correct tool, reproduce as the user, identify whether the failure is directory traversal/list/create/rename, then validate identity mapping. Only after that should you modify ACLs. This prevents the classic “chmod made it worse” spiral.

9) Does xattr=sa change ACL behavior?

It primarily changes where xattrs are stored for performance, not the semantics. But performance changes can expose latent problems (like apps doing more metadata ops than you thought), and operationally you should validate replication/restore and tooling compatibility in your environment.

10) If I must support both SMB and NFS, what’s the least painful strategy?

Pick one authoritative permission model per dataset and enforce it. Use separate datasets for SMB-first and NFS-first workloads. Mixed-authority ACL editing in the same dataset is where long-lived permission weirdness comes from.

Conclusion

acltype is less about ZFS internals and more about operational truth: who gets to define access policy, and which client semantics you promise to preserve. POSIX ACLs are the natural extension of Unix mode bits and are usually the calmest path for Linux-first estates—provided you respect the mask and default ACL rules. NFSv4 ACLs are the right tool when Windows/SMB semantics and inheritance must remain intact—provided you stop treating chmod as a universal solvent.

The real win is consistency. Decide your dataset’s identity and permission authority up front, set properties explicitly, snapshot before making recursive changes, and debug identity mapping before you rewrite ACLs. Do that, and ZFS permissions stop being a haunted house and start being a system you can reason about—on-call, under pressure, with grown-up uptime expectations.

← Previous
Ubuntu 24.04: MySQL “server has gone away” — fix timeouts and packet limits properly (case #36)
Next →
ZFS vdev removal: What You Can Remove (and the Limits You Must Respect)

Leave a comment