Skip to contentSkip to conversation

xfs: don't fill statvfs with project quota for a directory if it was not enabled.

PATCH In review Jeff Liu 3 participants 8 messages Apr 1, 2012 – Apr 11, 2012 XFS filesystem

lore
Share & tools
lore

Jeff Liu

author
#0 lore raw

PATCH 1/1 xfs: don't fill statvfs with project quota for a directory if it was not enabled.

Hello,

I can trigger a BUG() at fs/xfs/xfs_dquot.c on vanilla kernel 3.3.0 by the following steps:

1. mount a XFS partition without 'pquota' option.
/dev/sda7 on /xfs type xfs (rw)

2. setup project1 on it.

   $ cat /etc/projects 
   1:/xfs
   $ cat /etc/projid
   project1:1
   $ sudo xfs_quota -x -c 'project -s project1' /xfs

3. du -sh /xfs

[  170.024496] XFS: Assertion failed: XFS_IS_QUOTA_RUNNING(mp), file: fs/xfs/xfs_dquot.c, line: 680
[  170.024534] ------------[ cut here ]------------
[  170.024630] kernel BUG at fs/xfs/xfs_message.c:101!
[  170.024718] invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC
[  170.024836] Modules linked in: xfs cryptd aes_i586 aes_generic ....
[  170.026787] Pid: 2082, comm: du Not tainted 3.3.0-dirty #48 LENOVO 7661D43/7661D43
[  170.026950] EIP: 0060:[<f94892c4>] EFLAGS: 00010246 CPU: 1
[  170.027126] EIP is at assfail+0x47/0x57 [xfs]
[  170.027207] EAX: 0000006a EBX: e2031f58 ECX: 00000000 EDX: 00000007
[  170.027319] ESI: 00000000 EDI: e364f000 EBP: e2031e88 ESP: e2031e74
[  170.027432]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[  170.027530] Process du (pid: 2082, ti=e2030000 task=e3096a80 task.ti=e2030000)
[  170.027659] Stack:
[  170.027702]  00000000 f9543fbb f95523d2 f955210c 000002a8 e2031ec0 f9521d2c 3432302e
[  170.027912]  5d303834 00000020 e364f0dc 00000001 c13abe66 00000246 e2031eb4 00000246
[  170.028015]  e2031f58 e2031f58 e2b01880 e2031edc f9527edc 00000002 00000000 e2031ed4
[  170.028015] Call Trace:
[  170.028015]  [<f9521d2c>] xfs_qm_dqget+0x4e/0x90d [xfs]
[  170.028015]  [<c13abe66>] ? do_raw_spin_lock+0xdc/0x1fd
[  170.028015]  [<f9527edc>] xfs_qm_statvfs+0x4e/0xa5 [xfs]
[  170.028015]  [<f948a666>] xfs_fs_statfs+0x2b0/0x2c8 [xfs]
[  170.028015]  [<c1263c8b>] statfs_by_dentry+0x82/0xc1
[  170.028015]  [<c1263cee>] vfs_statfs+0x24/0x12a
[  170.028015]  [<c1263ed8>] fd_statfs+0x55/0x81
[  170.028015]  [<c126407b>] sys_fstatfs64+0x3f/0x7a
[  170.028015]  [<c183071c>] syscall_call+0x7/0xb
[  170.028015] Code: 10 89 54 24 0c 89 44 24 08 c7 44 24 04 bb 3f 54 f9 c7 04 24 00 ...
[  170.028015] EIP: [<f94892c4>] assfail+0x47/0x57 [xfs] SS:ESP 0068:e2031e74
[  170.083305] ---[ end trace 76dc24be29466355 ]---

IMHO, we can check if the project quota is running or not before performing xfs_qm_statvfs(), just return if not.

---
 fs/xfs/xfs_super.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
fs/xfs/xfs_super.c +9 -4
index ee5b695..dfc3666 100644
@@ -1059,10 +1059,15 @@ xfs_fs_statfs(
 
 	spin_unlock(&mp->m_sb_lock);
 
-	if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
-	    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
-			      (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
-		xfs_qm_statvfs(ip, statp);
+	/* don't try to fill statvfs with project quota if it's not running */
+	if (XFS_IS_PQUOTA_RUNNING(mp)) {
+		if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
+		    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+		     (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) {
+			xfs_qm_statvfs(ip, statp);
+		}
+	}
+
 	return 0;
 }
 
Signature · 6 lines
1.7.9

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
#1 lore raw
Quoted 7 lines · Jeff Liu

Hello,

I can trigger a BUG() at fs/xfs/xfs_dquot.c on vanilla kernel 3.3.0 by the following steps:

1. mount a XFS partition without 'pquota' option.
/dev/sda7 on /xfs type xfs (rw)

Quoted 8 lines

2. setup project1 on it.

   $ cat /etc/projects 
   1:/xfs
   $ cat /etc/projid
   project1:1
   $ sudo xfs_quota -x -c 'project -s project1' /xfs

3. du -sh /xfs

Can you wire this up as a test case for xfstests?

fs/xfs/xfs_super.c xfs_fs_statfs( · line 1066

Quoted 2 lines
fs/xfs/xfs_super.c +2 -0
+		    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+		     (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) {

This check is supposed to return false. I guess Chandras separate project quota inode preparations somehow broke it.

Chandra, can you look into this issue?

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#2 lore raw

Will look into it, and report back.

Quoted 19 lines · Christoph Hellwig
Quoted 7 lines · Jeff Liu

Hello,

I can trigger a BUG() at fs/xfs/xfs_dquot.c on vanilla kernel 3.3.0 by the following steps:

1. mount a XFS partition without 'pquota' option.
/dev/sda7 on /xfs type xfs (rw)

Quoted 8 lines

2. setup project1 on it.

   $ cat /etc/projects 
   1:/xfs
   $ cat /etc/projid
   project1:1
   $ sudo xfs_quota -x -c 'project -s project1' /xfs

3. du -sh /xfs

Can you wire this up as a test case for xfstests?

Quoted 8 lines

fs/xfs/xfs_super.c xfs_fs_statfs( · line 1066

Quoted 2 lines
fs/xfs/xfs_super.c +2 -0
+		    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+		     (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) {

This check is supposed to return false. I guess Chandras separate project quota inode preparations somehow broke it.

Chandra, can you look into this issue?

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

author
#3 lore raw
In reply to Christoph Hellwig
Quoted 15 lines · Christoph Hellwig
Quoted 14 lines · Jeff Liu

Hello,

I can trigger a BUG() at fs/xfs/xfs_dquot.c on vanilla kernel 3.3.0 by the following steps:

1. mount a XFS partition without 'pquota' option.
/dev/sda7 on /xfs type xfs (rw)

2. setup project1 on it.

   $ cat /etc/projects 
   1:/xfs
   $ cat /etc/projid
   project1:1
   $ sudo xfs_quota -x -c 'project -s project1' /xfs
Quoted 3 lines
Quoted 1 line

3. du -sh /xfs

Can you wire this up as a test case for xfstests?

Ok, I'll work it out.

Thanks,
-Jeff

Quoted 7 lines

fs/xfs/xfs_super.c xfs_fs_statfs( · line 1066

Quoted 3 lines
fs/xfs/xfs_super.c +2 -0
+		    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+		     (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) {

This check is supposed to return false. I guess Chandras separate project quota inode preparations somehow broke it.

Quoted 6 lines

Chandra, can you look into this issue?

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#4 lore raw
In reply to Christoph Hellwig

I tried the steps in latest xfs tree and on mainline 3.3.0. Unable to reproduce the problem.

Jeff, how big was the FS and how full was it ?

Christoph, BTW, 3.3.0 does not have my changes. Ben pushed it for 3.4-rc1

Here is my results with 3.3.0
-------------------
-bash-4.1$ uname -r
3.3.0
bash-4.1$ mount | grep xfs
/dev/sdb1 on /xfs type xfs (rw)
bash-4.1$ cat /etc/projects
1:/xfs
bash-4.1$ cat /etc/projid
project1:1
bash-4.1$ sudo xfs_quota -x -c 'project -s project1' /xfs [sudo] password for chandra:
Setting up project project1 (path /xfs)...
Processed 1 (/etc/projects and cmdline) paths for project project1 with recursion depth infinite (-1).
bash-4.1$ du -sh /xfs
0 /xfs
bash-4.1$ exit
------------------

Chandra

Quoted 19 lines · Christoph Hellwig
Quoted 7 lines · Jeff Liu

Hello,

I can trigger a BUG() at fs/xfs/xfs_dquot.c on vanilla kernel 3.3.0 by the following steps:

1. mount a XFS partition without 'pquota' option.
/dev/sda7 on /xfs type xfs (rw)

Quoted 8 lines

2. setup project1 on it.

   $ cat /etc/projects 
   1:/xfs
   $ cat /etc/projid
   project1:1
   $ sudo xfs_quota -x -c 'project -s project1' /xfs

3. du -sh /xfs

Can you wire this up as a test case for xfstests?

Quoted 8 lines

fs/xfs/xfs_super.c xfs_fs_statfs( · line 1066

Quoted 2 lines
fs/xfs/xfs_super.c +2 -0
+		    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+		     (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) {

This check is supposed to return false. I guess Chandras separate project quota inode preparations somehow broke it.

Chandra, can you look into this issue?

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

author
#5 lore raw

Hi Chandra,

Quoted 4 lines · Chandra Seetharaman

I tried the steps in latest xfs tree and on mainline 3.3.0. Unable to reproduce the problem.

Jeff, how big was the FS and how full was it ?

Sorry, I have missed one major step to reproduce this issue previously. Could you try to create a file under the project directory before setting it up?

Steps:
1. echo "1:/xfs" > /etc/projects; echo "project1:1" > /etc/projid
2. echo "test" > /xfs/testme
3. xfs_quota -x -c 'project -s project1' /xfs
4. du -sh /xfs

I have posted a test to xfstest at below link, it can help reproducing this issue.
http://www.spinics.net/lists/xfs/msg10744.html

Thanks,
-Jeff

Quoted 24 lines

Christoph, BTW, 3.3.0 does not have my changes. Ben pushed it for 3.4-rc1

Here is my results with 3.3.0
-------------------
-bash-4.1$ uname -r
3.3.0
bash-4.1$ mount | grep xfs
/dev/sdb1 on /xfs type xfs (rw)
bash-4.1$ cat /etc/projects
1:/xfs
bash-4.1$ cat /etc/projid
project1:1
bash-4.1$ sudo xfs_quota -x -c 'project -s project1' /xfs [sudo] password for chandra:
Setting up project project1 (path /xfs)...
Processed 1 (/etc/projects and cmdline) paths for project project1 with recursion depth infinite (-1).
bash-4.1$ du -sh /xfs
0 /xfs
bash-4.1$ exit
------------------

Quoted 32 lines

Chandra

Quoted 27 lines · Christoph Hellwig
Quoted 7 lines · Jeff Liu

Hello,

I can trigger a BUG() at fs/xfs/xfs_dquot.c on vanilla kernel 3.3.0 by the following steps:

1. mount a XFS partition without 'pquota' option.
/dev/sda7 on /xfs type xfs (rw)

Quoted 8 lines

2. setup project1 on it.

   $ cat /etc/projects 
   1:/xfs
   $ cat /etc/projid
   project1:1
   $ sudo xfs_quota -x -c 'project -s project1' /xfs

3. du -sh /xfs

Can you wire this up as a test case for xfstests?

fs/xfs/xfs_super.c xfs_fs_statfs( · line 1066

Quoted 2 lines
fs/xfs/xfs_super.c +2 -0
+		    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+		     (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) {

This check is supposed to return false. I guess Chandras separate project quota inode preparations somehow broke it.

Chandra, can you look into this issue?

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

author
#6 lore raw
Quoted 7 lines · Jeff Liu

Hi Chandra,

Quoted 4 lines · Chandra Seetharaman

I tried the steps in latest xfs tree and on mainline 3.3.0. Unable to reproduce the problem.

Jeff, how big was the FS and how full was it ?

It is irrelevant to the FS space status, looks this is an old issue since I can reproduce it on kernel-2.6.39 too:

Apr  5 13:50:36 pibroch kernel: [  144.667978] XFS: Assertion failed: XFS_IS_QUOTA_RUNNING(mp), file: fs/xfs/quota/xfs_dquot.c, line: 819
Apr  5 13:50:36 pibroch kernel: [  144.668119] ------------[ cut here ]------------
Apr  5 13:50:36 pibroch kernel: [  144.668208] kernel BUG at fs/xfs/linux-2.6/xfs_message.c:119!
Apr  5 13:50:37 pibroch kernel: [  144.668298] invalid opcode: 0000 [#1] SMP
Apr  5 13:50:37 pibroch kernel: [  144.668383] last sysfs file: /sys/devices/virtual/block/loop0/queue/rotational
Apr  5 13:50:37 pibroch kernel: [  144.668492] Modules linked in: xfs cryptd ...
Apr  5 13:50:37 pibroch kernel: [  144.670132]
Apr  5 13:50:37 pibroch kernel: [  144.670164] Pid: 2711, comm: du Not tainted 2.6.39 #1 LENOVO 7661D43/7661D43
Apr  5 13:50:37 pibroch kernel: [  144.670293] EIP: 0060:[<fa8b9b57>] EFLAGS: 00010246 CPU: 0
Apr  5 13:50:37 pibroch kernel: [  144.670444] EIP is at assfail+0x47/0x60 [xfs]
Apr  5 13:50:37 pibroch kernel: [  144.670512] EAX: 00000070 EBX: f29a6800 ECX: f1a65960 EDX: 00000000
Apr  5 13:50:37 pibroch kernel: [  144.670605] ESI: 00000000 EDI: ffffffff EBP: f233de80 ESP: f233de6c
Apr  5 13:50:37 pibroch kernel: [  144.670701]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
Apr  5 13:50:37 pibroch kernel: [  144.670787] Process du (pid: 2711, ti=f233c000 task=f1a65960 task.ti=f233c000)
Apr  5 13:50:37 pibroch kernel: [  144.670894] Stack:
Apr  5 13:50:37 pibroch kernel: [  144.670929]  00000000 fa8da474 fa8dcc2e fa8dcad4 00000333 f233dec8 fa7d677f f233df58
Apr  5 13:50:37 pibroch kernel: [  144.671100]  f233dec8 c1431e4b 00000246 00000000 00000002 00000000 00000000 fa8b9d81
Apr  5 13:50:37 pibroch kernel: [  144.671271]  00000001 00000246 00000000 00000246 f233df58 f233df58 ffffffff f233dee4
Apr  5 13:50:37 pibroch kernel: [  144.671443] Call Trace:
Apr  5 13:50:37 pibroch kernel: [  144.671542]  [<fa7d677f>] xfs_qm_dqget+0x4f/0xa20 [xfs]
Apr  5 13:50:37 pibroch kernel: [  144.671632]  [<c1431e4b>] ? do_raw_spin_lock+0x5b/0x230
Apr  5 13:50:37 pibroch kernel: [  144.671777]  [<fa8b9d81>] ? xfs_fs_statfs+0x91/0x2d0 [xfs]
Apr  5 13:50:37 pibroch kernel: [  144.671915]  [<fa7de68e>] xfs_qm_statvfs+0x4e/0xb0 [xfs]
Apr  5 13:50:37 pibroch kernel: [  144.672003]  [<c196f66c>] ? _raw_spin_unlock+0x4c/0x60
Apr  5 13:50:37 pibroch kernel: [  144.672020]  [<fa8b9f5a>] xfs_fs_statfs+0x26a/0x2d0 [xfs]
Apr  5 13:50:37 pibroch kernel: [  144.672020]  [<c12b6a1b>] statfs_by_dentry+0x8b/0xf0
Apr  5 13:50:37 pibroch kernel: [  144.672020]  [<c12b6aa4>] vfs_statfs+0x24/0x140
Apr  5 13:50:37 pibroch kernel: [  144.672020]  [<c12b6cbc>] fd_statfs+0x5c/0xa0
Apr  5 13:50:37 pibroch kernel: [  144.672020]  [<c12b6e9a>] sys_fstatfs64+0x2a/0x90
Apr  5 13:50:37 pibroch kernel: [  144.672020]  [<c19703a4>] syscall_call+0x7/0xb
Apr  5 13:50:37 pibroch kernel: [  144.672020] Code: 10 89 54 24 0c 89 44 24 08 c7 44 24 04 74 a4 8d fa c7 04 24 00 00 00 00 ...
Apr  5 13:50:37 pibroch kernel: [  144.672020] EIP: [<fa8b9b57>] assfail+0x47/0x60 [xfs] SS:ESP 0068:f233de6c
Apr  5 13:50:37 pibroch kernel: [  144.801094] ---[ end trace ae19ce1ca9446f05 ]---

At xfs_ioctl_setattr(), xfs_set_diflags() enabled the XFS_DIFLAG_PROJINHERIT flag of an inode if the given mask has FSX_XFLAGS no matter "PQUOTA is RUNNING or ON".

if (mask & FSX_XFLAGS) {
        xfs_set_diflags(ip, fa->fsx_xflags);
        xfs_diflags_to_linux(ip);
}

In this case, the following condition became always true at xfs_fs_statfs():
if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||

     ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
                       (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
     xfs_qm_statvfs(ip, statp);

Hence xfs_qm_statvfs()->xfs_qm_dqget()->ASSERT(XFS_IS_QUOTA_RUNNING(mp)) will failed, that's why I proposed to check if XFS_IS_QUOTA_RUNNING(mp) or not before doing it.

Thanks,
-Jeff

Quoted 74 lines

Sorry, I have missed one major step to reproduce this issue previously. Could you try to create a file under the project directory before setting it up?

Steps:
1. echo "1:/xfs" > /etc/projects; echo "project1:1" > /etc/projid
2. echo "test" > /xfs/testme
3. xfs_quota -x -c 'project -s project1' /xfs
4. du -sh /xfs

I have posted a test to xfstest at below link, it can help reproducing this issue.
http://www.spinics.net/lists/xfs/msg10744.html

Thanks,
-Jeff

Quoted 24 lines

Christoph, BTW, 3.3.0 does not have my changes. Ben pushed it for 3.4-rc1

Here is my results with 3.3.0
-------------------
-bash-4.1$ uname -r
3.3.0
bash-4.1$ mount | grep xfs
/dev/sdb1 on /xfs type xfs (rw)
bash-4.1$ cat /etc/projects
1:/xfs
bash-4.1$ cat /etc/projid
project1:1
bash-4.1$ sudo xfs_quota -x -c 'project -s project1' /xfs [sudo] password for chandra:
Setting up project project1 (path /xfs)...
Processed 1 (/etc/projects and cmdline) paths for project project1 with recursion depth infinite (-1).
bash-4.1$ du -sh /xfs
0 /xfs
bash-4.1$ exit
------------------

Quoted 32 lines

Chandra

Quoted 27 lines · Christoph Hellwig
Quoted 7 lines · Jeff Liu

Hello,

I can trigger a BUG() at fs/xfs/xfs_dquot.c on vanilla kernel 3.3.0 by the following steps:

1. mount a XFS partition without 'pquota' option.
/dev/sda7 on /xfs type xfs (rw)

Quoted 8 lines

2. setup project1 on it.

   $ cat /etc/projects 
   1:/xfs
   $ cat /etc/projid
   project1:1
   $ sudo xfs_quota -x -c 'project -s project1' /xfs

3. du -sh /xfs

Can you wire this up as a test case for xfstests?

fs/xfs/xfs_super.c xfs_fs_statfs( · line 1066

Quoted 2 lines
fs/xfs/xfs_super.c +2 -0
+		    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+		     (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) {

This check is supposed to return false. I guess Chandras separate project quota inode preparations somehow broke it.

Chandra, can you look into this issue?

Quoted 4 lines

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#7 lore raw
In reply to Jeff Liu

Sorry for taking so long to get back to this, but conferences and work kept me really busy the last two weeks.

fs/xfs/xfs_super.c xfs_fs_statfs( · line 1065

Quoted 4 lines
fs/xfs/xfs_super.c +0 -4
-	if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
-	    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
-			      (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
-		xfs_qm_statvfs(ip, statp);

I thjink the correct fix here is to replace the || between the inode flag and quota flag check with and && - we want both the above conditions to be true. Can you respin the patch by doing that and make sure it still passes the test case? I'd like to send it of to -stable ASAP.

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs