From this old discussion thread:
On boot kernel reads filesystem usage and limits information from aquota.user and aquota.group files stored on the respective filesystem when quotaon is run (e.g. from init.d). While system is up:
- In case of plain quota when new filesystem storage is being allocated to files or being released, quota information is tracked by kernel continuously but written to
aquota.* files only when quotaoff or quotasync command (i.e. (Q_SYNC sub-command of quotactl syscall) are run (usually as a part of shutdown script).
- With journaled quota, the difference is that usage information in
aquota.* files is being updated as a part of a filesystem transaction doing the space allocation.
If an unclean filesystem shutdown is detected during boot (e.g. if /var/lib/quota/off is not found on Debian systems because quotaoff wasn't run), it's very likely that filesystem usage and limits information in kernel memory could not be properly flushed to aquota.* files before shutdown.
- So in case of plain quota
quotacheck is run which updates the aquota.* files with the actual usage information gathered by reading block allocation structures on the filesystem.
- While in case of journaled quota space usage information in
aquota.* files is automatically updated when (fsck is run and) journal is replayed after a system crash. However quotacheck has to be run if (in addition to journal replaying) fsck finds some filesystem corruption (e.g. metadata inconsistencies recorded in superblock) and needs to fix it by modifying filesystem.
Note that in both cases if a system is booted with quotas disabled (or disabled after booting system), the usage information maintained by kernel will become and remain out of sync with the actual usage information, unless quotacheck is run - manually or as a result of unclean shutdown. cron jobs and init.d scripts are usually written to not perform quotacheck during normal working of a system or after a clean shutdown (see quotacheck.mode kernel command-line parameter).
What is more, a mount option (which I cannot find documentation about) that should be used when creating journaled quota is qfmt=vfsv1.
It's the format of aquota.* files. From kernel configuration:
config QFMT_V2
...
This config option enables kernel support for vfsv0 and vfsv1 quota formats. Both these formats support 32-bit UIDs/GIDs and vfsv1 format also supports 64-bit inode and block quota limits.
And from quotactl(2):
Currently, there are three supported quota formats:
QFMT_VFS_OLD The original quota format.
QFMT_VFS_V0 The standard VFS v0 quota format, which can handle 32-bit UIDs and GIDs and quota limits up to 2^42 bytes and 2^32 inodes.
QFMT_VFS_V1 A quota format that can handle 32-bit UIDs and GIDs and quota limits of 2^64 bytes and 2^64 inodes.
Version 1 quota files (format QFMT_VFS_OLD or mount option jqfmt=vfsold, kernel configuration QFMT_V1) were named as quota.*. Version 2 quota files (format QFMT_VFS_V0 and QFMT_VFS_V1 or mount options jqfmt=vfsv0 and jqfmt=vfsv1) support journaled quotas.