Files
mars-nwe/doc/quota/README.md
OpenAI 7a81776cf1
All checks were successful
Source release / source-package (push) Successful in 1m15s
quota: make linux project quota authoritative for dirquota bootstrap
2026-06-11 21:02:27 +02:00

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.h and src/nwfs/quota/quota.c
    • backend-neutral helpers only
    • function prefix: nwfs_quota_*
  • include/nwfs/nwquota.h and src/nwfs/quota/nwquota.c
    • NetWare metadata quota stored in the volume-root netware.userquota xattr
    • function prefix: nwfs_nwquota_*
  • include/nwfs/lnxquota.h and src/nwfs/quota/lnxquota.c
    • Linux quotactl() backend
    • function prefix: nwfs_lnxquota_*

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:

  1. Try Linuxquota first.
  2. If the Linux quota entry is missing or unlimited, read netware.userquota.
  3. If a metadata restriction exists, try to write that restriction back to Linuxquota.
  4. If that write succeeds, Linuxquota is primary again and later reads use the kernel values.
  5. 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 units
  • inuse4k: 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.