Hide Forgot
Created attachment 473478 [details] test script! Description of problem: In the ext4+delalloc filesystem, repqouta cannot display the rightly have been used block until system run the command sync ! Version-Release number of selected component (if applicable): redhat enterprise linux 6 beta2 x86_64 How reproducible: Always! Steps to Reproduce: 1.#mkdir /mnt/mp1; 2.#userdel quotausr1 (if your system exist user quotausr1); 3.#./repquotatest.sh Actual results: [root@quota-dxk bangzi]# ./repquotatest.sh #### first repquota *** Report for user quotas on device /dev/sdb1 Block grace time: 7days; Inode grace time: 7days Block limits File limits User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 20 0 0 2 0 0 quotausr1 -- 0 0 0 1 0 0 #### second repquota *** Report for user quotas on device /dev/sdb1 Block grace time: 7days; Inode grace time: 7days Block limits File limits User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 20 0 0 2 0 0 quotausr1 -- 0 0 0 1 0 0 #### third repquota *** Report for user quotas on device /dev/sdb1 Block grace time: 7days; Inode grace time: 7days Block limits File limits User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 20 0 0 2 0 0 quotausr1 -- 1024 0 0 1 0 0 Expected results: [root@quota-dxk bangzi]# ./repquotatest.sh #### first repquota *** Report for user quotas on device /dev/sdb1 Block grace time: 7days; Inode grace time: 7days Block limits File limits User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 20 0 0 2 0 0 quotausr1 -- 0 0 0 1 0 0 #### second repquota *** Report for user quotas on device /dev/sdb1 Block grace time: 7days; Inode grace time: 7days Block limits File limits User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 20 0 0 2 0 0 quotausr1 -- 1024 0 0 1 0 0 #### third repquota *** Report for user quotas on device /dev/sdb1 Block grace time: 7days; Inode grace time: 7days Block limits File limits User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 20 0 0 2 0 0 quotausr1 -- 1024 0 0 1 0 0 Additional info: [root@quota-dxk bangzi]# lsb_release -a LSB Version: :core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch Distributor ID: RedHatEnterpriseServer Description: Red Hat Enterprise Linux Server release 6.0 Beta (Santiago) Release: 6.0 Codename: Santiago [root@quota-dxk bangzi]# uname -r 2.6.32-37.el6.x86_64
repquota(8) calls quotactl(Q_SYNC|USRQUOTA, ...) to synchronize in-kernel quotas into quota file and then repquota parses the quota file ({a,}quota.user). quota(1) gets the quotas from running kernel instead and thus it provides up-to-date values. repquota(8) gets data from the file because it's faster than querying kernel for each user (a syscall for a user). Per quotaclt(2) manual the quota file should be synchronized after quotacl(Q_SYNC, ...). I thought wasn't for some reason. It looked like a bug in the kernel (2.6.32-94.el6.x86_64 from RHEL-6 and 2.6.35.10-74.fc14.x86_64 from Fedora-14). I copied and checked aquota.users content before repquota(8), before sync(8) and after sync(8). My testing user has ID 500 (0x1F4) and it owns 1 file with size 1 MiB exactly (0x400 KiB). I found this: Before repquota: No entry in aquota.sync for the user After repquota, before sync: Entry for UID, correct usage size 0001440 01f4 0000 0000 0000 0000 0000 0001 0000 0001450 0000 0000 0000 0000 0400 0000 0000 0000 After sync: Entry for UID, correct usage size 0001440 01f4 0000 0000 0000 0000 0000 0001 0000 0001450 0000 0000 0000 0000 0400 0010 0000 0000 So apparently reqpuota() gets the old data from read(2) buffer as it opens the file and read headers before quotactl(Q_SYNC, ...).
Created attachment 473523 [details] Dumped aqouta.user files Unfortunately the quota file before sync(1) and after sync(1) differs. I let repquota to parse and display those files by repquota and only the after sync(1) one shows correct counters. I'm attaching those three files. aquota.user.1 is before creating file, aquota.user.2 after quotactl(Q_SYNC, ...) and aquota.user.3 after sync(1). Also I made a mistake while running strace output for repquota tool. repquota reopens the quota file after syncing quotas: open("/mnt/ext4/aquota.user", O_RDONLY) = 3 close(3) = 0 quotactl(Q_SYNC|USRQUOTA, "/dev/mapper/vg_dhcp0122-ext4", 0, NULL) = 0 open("/mnt/ext4/aquota.user", O_RDONLY) = 3 and it reads counters from the file after that.
IMHO repquota shows correct data: Before sync: Block limits File limits User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 13 0 0 2 0 0 petr -- 1 0 0 1 0 0 After sync: User used soft hard grace used soft hard grace ---------------------------------------------------------------------- root -- 13 0 0 2 0 0 petr -- 1025 0 0 1 0 0 I think the delay is understandable for _delayed_ allocation. If you have a sparse file, quota will count used space---not a size of the file. However reassigning to kernel to evaluate accounting on delayed ext4 properly.
This is actually behaving exactly as it should for delayed allocation - until you sync (or the application issues an fsync or fdatasync), blocks are not really allocated.