7.6 KiB
Quota design
MARS-NWE exposes NetWare user volume restrictions through NCP while the backing storage can use different quota backends. The backend split is intentional and must stay visible in both file names and function names.
Files and responsibilities
include/nwfs/quota.handsrc/nwfs/quota/quota.c- backend-neutral helpers only
- function prefix:
nwfs_quota_*
include/nwfs/nwquota.handsrc/nwfs/quota/nwquota.c- NetWare metadata quota stored in the volume-root
netware.userquotaxattr - function prefix:
nwfs_nwquota_*
- NetWare metadata quota stored in the volume-root
include/nwfs/lnxquota.handsrc/nwfs/quota/lnxquota.c- Linux
quotactl()backend - function prefix:
nwfs_lnxquota_*
- Linux
Do not merge Linux and NetWare metadata handling back into one backend file.
A future BSD quota backend should be added next to these files, for example as
bsdquota.c/h with an nwfs_bsdquota_* prefix.
Backend model
Linuxquota
Linuxquota is the primary source when the backing filesystem has a working
Linux user-quota entry. Restriction and usage values are read from the kernel
with quotactl() and converted to NetWare 4 KiB blocks for NCP replies.
When MARS-NWE successfully changes a Linux quota, it also mirrors the NetWare
restriction to the volume-root netware.userquota xattr. That xattr mirror is
not authoritative while Linuxquota is available. It exists so backup tools that
preserve netware.* metadata can restore the NetWare restriction data along
with the files.
NWQUOTA metadata
NWQUOTA stores the restriction and the NetWare-style used-block accounting in
netware.userquota on the volume root. It is the primary backend for volumes
without Linux kernel quota support and for explicit metadata/NWQUOTA mode.
The stored used-block value is adjusted by MARS-NWE after successful file growth or shrink operations. A filesystem scan is still used as a lower bound so the reported usage never falls below host-owned data that already exists.
Restore fallback
After a restore, a Linux filesystem may support quota but not yet have a kernel
quota entry for a NetWare user. If quotactl() reports that the Linux quota
entry is missing, or returns an unlimited user entry while netware.userquota
contains a finite restriction for that user, MARS-NWE uses the metadata entry as
a restore source.
The restore path is:
- Try Linuxquota first.
- If the Linux quota entry is missing or unlimited, read
netware.userquota. - If a metadata restriction exists, try to write that restriction back to Linuxquota.
- If that write succeeds, Linuxquota is primary again and later reads use the kernel values.
- If the write cannot be performed, the metadata value is returned as a fallback so the restored NetWare restriction is still visible to clients.
This keeps Linuxquota authoritative whenever it is active, while still making
netware.* backups useful for disaster recovery.
Userquota NCP behavior
The NCP layer normalizes all userquota backends to the same values:
restriction4k: maximum allowed blocks in NetWare 4 KiB unitsinuse4k: current used blocks in NetWare 4 KiB units
For write enforcement, MARS-NWE denies growth before storing partial data when projected usage reaches or exceeds the user restriction. The client-visible write failure remains the generic NetWare-style completion used by the existing quota smokes.
tests/nwfs/nwfs_ncpfs_userquota_dual_smoke.sh is the live regression for this
state. After the 0357 directory-quota retest it remained green on both
backends: QUOTA/Linuxquota and SYS/NWQUOTA.
Directory quota NCPs
The classic NetWare 3.x directory quota calls are tracked with decimal NCP notation and wire/code hex notation together:
- decimal 22/35 = wire/code 0x23: Get Directory Disk Space Restriction.
- decimal 22/36 = wire/code 0x24: Set Directory Disk Space Restriction.
- decimal 22/40 = wire/code 0x28: Scan Directory Disk Space.
The classic 3.x set/get/clear endpoint block is done/audited as of 0357.
Finite directory restrictions are stored in netware.metadata.nwm_quota_limit
and marked active with zMOD_DIR_QUOTA.
Clear semantics are deliberate: decimal 22/36 = wire/code 0x24 with limit 0
removes the active zMOD_DIR_QUOTA metadata bit. The stored value may remain
as the inactive sentinel 9223372036854775807; host dumps should therefore show
dirQuotaLimit=9223372036854775807 inactive, and a follow-up decimal 22/35 =
wire/code 0x23 read should return entries=0. Do not require the physical
stored limit to be zero or absent.
Decimal 22/40 = wire/code 0x28 now reads its documented Sequence value Lo-Hi. Richer scan-reply validation remains a follow-up until resource-fork/MAC_RF and related extended disk-space fields have meaningful backing state.
Linux project quota for directory quota
Linux user quota is deliberately not used as a directory-quota backend. User
quota is uid -> blocks, while NetWare directory quota is directory subtree -> blocks; mapping the latter to the former would make one user's writes in
different directories share the same limit and would not match NetWare 3.x
client expectations.
For volumes that use the Linux quota path, Linux project quota is the
authoritative live directory-quota backend. netware.metadata.nwm_quota_limit
plus zMOD_DIR_QUOTA is only a mirror for backup, restore and offline tools.
The bootstrap rule is intentionally the same shape as the Linux userquota
restore path: decimal 22/35 = wire/code 0x23 first reads Linux project quota.
If Linux has no active project-quota limit for the directory yet, but
netware.metadata contains an active directory-quota mirror, MARS seeds Linux
project quota from that mirror once and then treats Linux as authoritative
again. If neither Linux nor metadata contains a limit, decimal 22/35 returns
entries=0.
Decimal 22/36 = wire/code 0x24 sets or clears Linux project quota first on
Linux quota-capable volumes and then mirrors the accepted limit to
netware.metadata. For metadata-only/NWQUOTA volumes, netware.metadata
remains authoritative.
This backend is intended for filesystems that support project IDs and project quota, especially XFS. ext4 can be used only when the filesystem has the project-quota feature and is mounted with project quota enabled. ext3 is not a useful target for this backend.
Recommended QUOTA test volume setup is therefore XFS, for example:
umount /mnt/marsquota 2>/dev/null || true
mkfs.xfs -f /root/marsquota2.img
mount -o prjquota /root/marsquota2.img /mnt/marsquota
findmnt -T /mnt/marsquota
For ext4 experiments, use an ext4 filesystem with project quota support and
mount it with prjquota; do not use ext3 for this work.
Directory quota smoke
tests/nwfs/nwfs_ncpfs_dirquota_smoke.sh is the live smoke for the NetWare
3.x directory disk-space restriction calls. It sets a limit with decimal 22/36
= wire/code 0x24, reads it back with decimal 22/35 = wire/code 0x23, verifies
netware.metadata, clears the limit with decimal 22/36 = wire/code 0x24, and
checks that decimal 22/35 = wire/code 0x23 returns no entries again and that
host-side netware.metadata no longer marks dirQuotaLimit active.
Mario's 0357 live retest produced the expected clear state:
modify_mask=0x0000000000000000
dirQuotaLimit=9223372036854775807 inactive
Patch 0357 corrected the smoke validator so the trailing inactive state is
treated as cleared rather than misread as active.
Screenshots and reference captures
FILER, SYSCON, NWADMIN, or native NetWare reference screenshots for quota
behavior should be stored below this directory, for example in
doc/quota/screenshots/. Keep quota reference material here instead of placing
screenshots directly in the top-level doc/ directory.