diff options
author | Jie Liu <jeff.liu@oracle.com> | 2013-11-26 08:38:54 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-12-06 17:10:21 -0500 |
commit | 37eb9706ebf5b99d14c6086cdeef2c2f73f9c9fb (patch) | |
tree | 4f6c58e7dbf2d881aa660351b11619fc7a25f873 /fs | |
parent | afbd123db4e72d5fe44db235976af64a22b32976 (diff) |
xfs: fix false assertion at xfs_qm_vop_create_dqattach
After the previous fix, there still has another ASSERT failure if turning
off any type of quota while fsstress is running at the same time.
Backtrace in this case:
[ 50.867897] XFS: Assertion failed: XFS_IS_GQUOTA_ON(mp), file: fs/xfs/xfs_qm.c, line: 2118
[ 50.867924] ------------[ cut here ]------------
... <snip>
[ 50.867957] Kernel BUG at ffffffffa0b55a32 [verbose debug info unavailable]
[ 50.867999] invalid opcode: 0000 [#1] SMP
[ 50.869407] Call Trace:
[ 50.869446] [<ffffffffa0bc408a>] xfs_qm_vop_create_dqattach+0x19a/0x2d0 [xfs]
[ 50.869512] [<ffffffffa0b9cc45>] xfs_create+0x5c5/0x6a0 [xfs]
[ 50.869564] [<ffffffffa0b5307c>] xfs_vn_mknod+0xac/0x1d0 [xfs]
[ 50.869615] [<ffffffffa0b531d6>] xfs_vn_mkdir+0x16/0x20 [xfs]
[ 50.869655] [<ffffffff811becd5>] vfs_mkdir+0x95/0x130
[ 50.869689] [<ffffffff811bf63a>] SyS_mkdirat+0xaa/0xe0
[ 50.869723] [<ffffffff811bf689>] SyS_mkdir+0x19/0x20
[ 50.869757] [<ffffffff8170f7dd>] system_call_fastpath+0x1a/0x1f
[ 50.869793] Code: 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 <snip>
[ 50.870003] RIP [<ffffffffa0b55a32>] assfail+0x22/0x30 [xfs]
[ 50.870050] RSP <ffff88002941fd60>
[ 50.879251] ---[ end trace c93a2b342341c65b ]---
We're hitting the ASSERT(XFS_IS_*QUOTA_ON(mp)) in xfs_qm_vop_create_dqattach(),
however the assertion itself is not right IMHO. While performing quota off, we
firstly clear the XFS_*QUOTA_ACTIVE bit(s) from struct xfs_mount without taking
any special locks, see xfs_qm_scall_quotaoff(). Hence there is no guarantee
that the desired quota is still active.
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_qm.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 14a4996cfec6..588e4909c589 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -2082,24 +2082,21 @@ xfs_qm_vop_create_dqattach( | |||
2082 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 2082 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2083 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); | 2083 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); |
2084 | 2084 | ||
2085 | if (udqp) { | 2085 | if (udqp && XFS_IS_UQUOTA_ON(mp)) { |
2086 | ASSERT(ip->i_udquot == NULL); | 2086 | ASSERT(ip->i_udquot == NULL); |
2087 | ASSERT(XFS_IS_UQUOTA_ON(mp)); | ||
2088 | ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id)); | 2087 | ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id)); |
2089 | 2088 | ||
2090 | ip->i_udquot = xfs_qm_dqhold(udqp); | 2089 | ip->i_udquot = xfs_qm_dqhold(udqp); |
2091 | xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1); | 2090 | xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1); |
2092 | } | 2091 | } |
2093 | if (gdqp) { | 2092 | if (gdqp && XFS_IS_GQUOTA_ON(mp)) { |
2094 | ASSERT(ip->i_gdquot == NULL); | 2093 | ASSERT(ip->i_gdquot == NULL); |
2095 | ASSERT(XFS_IS_GQUOTA_ON(mp)); | ||
2096 | ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id)); | 2094 | ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id)); |
2097 | ip->i_gdquot = xfs_qm_dqhold(gdqp); | 2095 | ip->i_gdquot = xfs_qm_dqhold(gdqp); |
2098 | xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); | 2096 | xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); |
2099 | } | 2097 | } |
2100 | if (pdqp) { | 2098 | if (pdqp && XFS_IS_PQUOTA_ON(mp)) { |
2101 | ASSERT(ip->i_pdquot == NULL); | 2099 | ASSERT(ip->i_pdquot == NULL); |
2102 | ASSERT(XFS_IS_PQUOTA_ON(mp)); | ||
2103 | ASSERT(xfs_get_projid(ip) == be32_to_cpu(pdqp->q_core.d_id)); | 2100 | ASSERT(xfs_get_projid(ip) == be32_to_cpu(pdqp->q_core.d_id)); |
2104 | 2101 | ||
2105 | ip->i_pdquot = xfs_qm_dqhold(pdqp); | 2102 | ip->i_pdquot = xfs_qm_dqhold(pdqp); |