Bug 669632 - In the ext4+delalloc filesystem, repqouta cannot display the right used block value!
Summary: In the ext4+delalloc filesystem, repqouta cannot display the right used block...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: kernel
Version: 6.0
Hardware: x86_64
OS: Linux
low
medium
Target Milestone: rc
: ---
Assignee: Red Hat Kernel Manager
QA Contact: Red Hat Kernel QE team
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-01-14 07:03 UTC by Zhang Liang
Modified: 2011-01-14 14:42 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2011-01-14 14:42:03 UTC
Target Upstream Version:


Attachments (Terms of Use)
test script! (1016 bytes, application/octet-stream)
2011-01-14 07:03 UTC, Zhang Liang
no flags Details
Dumped aqouta.user files (305 bytes, application/x-tar)
2011-01-14 13:47 UTC, Petr Pisar
no flags Details

Description Zhang Liang 2011-01-14 07:03:23 UTC
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

Comment 2 Petr Pisar 2011-01-14 11:18:02 UTC
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, ...).

Comment 3 Petr Pisar 2011-01-14 13:47:31 UTC
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.

Comment 4 Petr Pisar 2011-01-14 13:57:34 UTC
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.

Comment 5 Ric Wheeler 2011-01-14 14:42:03 UTC
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.


Note You need to log in before you can comment on or make changes to this bug.