diff options
Diffstat (limited to 'fs/xfs/quota/xfs_dquot.c')
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index f2705f2fd43c..591ca6602bfb 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -101,7 +101,7 @@ xfs_qm_dqinit( | |||
101 | if (brandnewdquot) { | 101 | if (brandnewdquot) { |
102 | dqp->dq_flnext = dqp->dq_flprev = dqp; | 102 | dqp->dq_flnext = dqp->dq_flprev = dqp; |
103 | mutex_init(&dqp->q_qlock); | 103 | mutex_init(&dqp->q_qlock); |
104 | sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq"); | 104 | init_waitqueue_head(&dqp->q_pinwait); |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * Because we want to use a counting completion, complete | 107 | * Because we want to use a counting completion, complete |
@@ -131,7 +131,7 @@ xfs_qm_dqinit( | |||
131 | dqp->q_res_bcount = 0; | 131 | dqp->q_res_bcount = 0; |
132 | dqp->q_res_icount = 0; | 132 | dqp->q_res_icount = 0; |
133 | dqp->q_res_rtbcount = 0; | 133 | dqp->q_res_rtbcount = 0; |
134 | dqp->q_pincount = 0; | 134 | atomic_set(&dqp->q_pincount, 0); |
135 | dqp->q_hash = NULL; | 135 | dqp->q_hash = NULL; |
136 | ASSERT(dqp->dq_flnext == dqp->dq_flprev); | 136 | ASSERT(dqp->dq_flnext == dqp->dq_flprev); |
137 | 137 | ||
@@ -1221,16 +1221,14 @@ xfs_qm_dqflush( | |||
1221 | xfs_dqtrace_entry(dqp, "DQFLUSH"); | 1221 | xfs_dqtrace_entry(dqp, "DQFLUSH"); |
1222 | 1222 | ||
1223 | /* | 1223 | /* |
1224 | * If not dirty, nada. | 1224 | * If not dirty, or it's pinned and we are not supposed to |
1225 | * block, nada. | ||
1225 | */ | 1226 | */ |
1226 | if (!XFS_DQ_IS_DIRTY(dqp)) { | 1227 | if (!XFS_DQ_IS_DIRTY(dqp) || |
1228 | (!(flags & XFS_QMOPT_SYNC) && atomic_read(&dqp->q_pincount) > 0)) { | ||
1227 | xfs_dqfunlock(dqp); | 1229 | xfs_dqfunlock(dqp); |
1228 | return (0); | 1230 | return 0; |
1229 | } | 1231 | } |
1230 | |||
1231 | /* | ||
1232 | * Cant flush a pinned dquot. Wait for it. | ||
1233 | */ | ||
1234 | xfs_qm_dqunpin_wait(dqp); | 1232 | xfs_qm_dqunpin_wait(dqp); |
1235 | 1233 | ||
1236 | /* | 1234 | /* |
@@ -1274,10 +1272,8 @@ xfs_qm_dqflush( | |||
1274 | dqp->dq_flags &= ~(XFS_DQ_DIRTY); | 1272 | dqp->dq_flags &= ~(XFS_DQ_DIRTY); |
1275 | mp = dqp->q_mount; | 1273 | mp = dqp->q_mount; |
1276 | 1274 | ||
1277 | /* lsn is 64 bits */ | 1275 | xfs_trans_ail_copy_lsn(mp->m_ail, &dqp->q_logitem.qli_flush_lsn, |
1278 | spin_lock(&mp->m_ail_lock); | 1276 | &dqp->q_logitem.qli_item.li_lsn); |
1279 | dqp->q_logitem.qli_flush_lsn = dqp->q_logitem.qli_item.li_lsn; | ||
1280 | spin_unlock(&mp->m_ail_lock); | ||
1281 | 1277 | ||
1282 | /* | 1278 | /* |
1283 | * Attach an iodone routine so that we can remove this dquot from the | 1279 | * Attach an iodone routine so that we can remove this dquot from the |
@@ -1323,8 +1319,10 @@ xfs_qm_dqflush_done( | |||
1323 | xfs_dq_logitem_t *qip) | 1319 | xfs_dq_logitem_t *qip) |
1324 | { | 1320 | { |
1325 | xfs_dquot_t *dqp; | 1321 | xfs_dquot_t *dqp; |
1322 | struct xfs_ail *ailp; | ||
1326 | 1323 | ||
1327 | dqp = qip->qli_dquot; | 1324 | dqp = qip->qli_dquot; |
1325 | ailp = qip->qli_item.li_ailp; | ||
1328 | 1326 | ||
1329 | /* | 1327 | /* |
1330 | * We only want to pull the item from the AIL if its | 1328 | * We only want to pull the item from the AIL if its |
@@ -1337,15 +1335,12 @@ xfs_qm_dqflush_done( | |||
1337 | if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && | 1335 | if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && |
1338 | qip->qli_item.li_lsn == qip->qli_flush_lsn) { | 1336 | qip->qli_item.li_lsn == qip->qli_flush_lsn) { |
1339 | 1337 | ||
1340 | spin_lock(&dqp->q_mount->m_ail_lock); | 1338 | /* xfs_trans_ail_delete() drops the AIL lock. */ |
1341 | /* | 1339 | spin_lock(&ailp->xa_lock); |
1342 | * xfs_trans_delete_ail() drops the AIL lock. | ||
1343 | */ | ||
1344 | if (qip->qli_item.li_lsn == qip->qli_flush_lsn) | 1340 | if (qip->qli_item.li_lsn == qip->qli_flush_lsn) |
1345 | xfs_trans_delete_ail(dqp->q_mount, | 1341 | xfs_trans_ail_delete(ailp, (xfs_log_item_t*)qip); |
1346 | (xfs_log_item_t*)qip); | ||
1347 | else | 1342 | else |
1348 | spin_unlock(&dqp->q_mount->m_ail_lock); | 1343 | spin_unlock(&ailp->xa_lock); |
1349 | } | 1344 | } |
1350 | 1345 | ||
1351 | /* | 1346 | /* |
@@ -1375,7 +1370,7 @@ xfs_dqunlock( | |||
1375 | mutex_unlock(&(dqp->q_qlock)); | 1370 | mutex_unlock(&(dqp->q_qlock)); |
1376 | if (dqp->q_logitem.qli_dquot == dqp) { | 1371 | if (dqp->q_logitem.qli_dquot == dqp) { |
1377 | /* Once was dqp->q_mount, but might just have been cleared */ | 1372 | /* Once was dqp->q_mount, but might just have been cleared */ |
1378 | xfs_trans_unlocked_item(dqp->q_logitem.qli_item.li_mountp, | 1373 | xfs_trans_unlocked_item(dqp->q_logitem.qli_item.li_ailp, |
1379 | (xfs_log_item_t*)&(dqp->q_logitem)); | 1374 | (xfs_log_item_t*)&(dqp->q_logitem)); |
1380 | } | 1375 | } |
1381 | } | 1376 | } |
@@ -1489,7 +1484,7 @@ xfs_qm_dqpurge( | |||
1489 | "xfs_qm_dqpurge: dquot %p flush failed", dqp); | 1484 | "xfs_qm_dqpurge: dquot %p flush failed", dqp); |
1490 | xfs_dqflock(dqp); | 1485 | xfs_dqflock(dqp); |
1491 | } | 1486 | } |
1492 | ASSERT(dqp->q_pincount == 0); | 1487 | ASSERT(atomic_read(&dqp->q_pincount) == 0); |
1493 | ASSERT(XFS_FORCED_SHUTDOWN(mp) || | 1488 | ASSERT(XFS_FORCED_SHUTDOWN(mp) || |
1494 | !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL)); | 1489 | !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL)); |
1495 | 1490 | ||