aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/quota/xfs_dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota/xfs_dquot.c')
-rw-r--r--fs/xfs/quota/xfs_dquot.c114
1 files changed, 46 insertions, 68 deletions
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 585e7633dfc7..e1a2f6800e01 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -23,25 +23,15 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_alloc.h" 26#include "xfs_alloc.h"
28#include "xfs_dmapi.h"
29#include "xfs_quota.h" 27#include "xfs_quota.h"
30#include "xfs_mount.h" 28#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h"
34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
36#include "xfs_dinode.h"
37#include "xfs_inode.h" 30#include "xfs_inode.h"
38#include "xfs_btree.h"
39#include "xfs_ialloc.h"
40#include "xfs_bmap.h" 31#include "xfs_bmap.h"
41#include "xfs_rtalloc.h" 32#include "xfs_rtalloc.h"
42#include "xfs_error.h" 33#include "xfs_error.h"
43#include "xfs_itable.h" 34#include "xfs_itable.h"
44#include "xfs_rw.h"
45#include "xfs_attr.h" 35#include "xfs_attr.h"
46#include "xfs_buf_item.h" 36#include "xfs_buf_item.h"
47#include "xfs_trans_space.h" 37#include "xfs_trans_space.h"
@@ -64,8 +54,6 @@
64 flush lock - ditto. 54 flush lock - ditto.
65*/ 55*/
66 56
67STATIC void xfs_qm_dqflush_done(xfs_buf_t *, xfs_dq_logitem_t *);
68
69#ifdef DEBUG 57#ifdef DEBUG
70xfs_buftarg_t *xfs_dqerror_target; 58xfs_buftarg_t *xfs_dqerror_target;
71int xfs_do_dqerror; 59int xfs_do_dqerror;
@@ -390,21 +378,14 @@ xfs_qm_dqalloc(
390 return (ESRCH); 378 return (ESRCH);
391 } 379 }
392 380
393 /* 381 xfs_trans_ijoin_ref(tp, quotip, XFS_ILOCK_EXCL);
394 * xfs_trans_commit normally decrements the vnode ref count
395 * when it unlocks the inode. Since we want to keep the quota
396 * inode around, we bump the vnode ref count now.
397 */
398 IHOLD(quotip);
399
400 xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL);
401 nmaps = 1; 382 nmaps = 1;
402 if ((error = xfs_bmapi(tp, quotip, 383 if ((error = xfs_bmapi(tp, quotip,
403 offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB, 384 offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB,
404 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, 385 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
405 &firstblock, 386 &firstblock,
406 XFS_QM_DQALLOC_SPACE_RES(mp), 387 XFS_QM_DQALLOC_SPACE_RES(mp),
407 &map, &nmaps, &flist, NULL))) { 388 &map, &nmaps, &flist))) {
408 goto error0; 389 goto error0;
409 } 390 }
410 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); 391 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -520,7 +501,7 @@ xfs_qm_dqtobp(
520 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset, 501 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
521 XFS_DQUOT_CLUSTER_SIZE_FSB, 502 XFS_DQUOT_CLUSTER_SIZE_FSB,
522 XFS_BMAPI_METADATA, 503 XFS_BMAPI_METADATA,
523 NULL, 0, &map, &nmaps, NULL, NULL); 504 NULL, 0, &map, &nmaps, NULL);
524 505
525 xfs_iunlock(quotip, XFS_ILOCK_SHARED); 506 xfs_iunlock(quotip, XFS_ILOCK_SHARED);
526 if (error) 507 if (error)
@@ -1141,6 +1122,46 @@ xfs_qm_dqrele(
1141 xfs_qm_dqput(dqp); 1122 xfs_qm_dqput(dqp);
1142} 1123}
1143 1124
1125/*
1126 * This is the dquot flushing I/O completion routine. It is called
1127 * from interrupt level when the buffer containing the dquot is
1128 * flushed to disk. It is responsible for removing the dquot logitem
1129 * from the AIL if it has not been re-logged, and unlocking the dquot's
1130 * flush lock. This behavior is very similar to that of inodes..
1131 */
1132STATIC void
1133xfs_qm_dqflush_done(
1134 struct xfs_buf *bp,
1135 struct xfs_log_item *lip)
1136{
1137 xfs_dq_logitem_t *qip = (struct xfs_dq_logitem *)lip;
1138 xfs_dquot_t *dqp = qip->qli_dquot;
1139 struct xfs_ail *ailp = lip->li_ailp;
1140
1141 /*
1142 * We only want to pull the item from the AIL if its
1143 * location in the log has not changed since we started the flush.
1144 * Thus, we only bother if the dquot's lsn has
1145 * not changed. First we check the lsn outside the lock
1146 * since it's cheaper, and then we recheck while
1147 * holding the lock before removing the dquot from the AIL.
1148 */
1149 if ((lip->li_flags & XFS_LI_IN_AIL) &&
1150 lip->li_lsn == qip->qli_flush_lsn) {
1151
1152 /* xfs_trans_ail_delete() drops the AIL lock. */
1153 spin_lock(&ailp->xa_lock);
1154 if (lip->li_lsn == qip->qli_flush_lsn)
1155 xfs_trans_ail_delete(ailp, lip);
1156 else
1157 spin_unlock(&ailp->xa_lock);
1158 }
1159
1160 /*
1161 * Release the dq's flush lock since we're done with it.
1162 */
1163 xfs_dqfunlock(dqp);
1164}
1144 1165
1145/* 1166/*
1146 * Write a modified dquot to disk. 1167 * Write a modified dquot to disk.
@@ -1222,8 +1243,9 @@ xfs_qm_dqflush(
1222 * Attach an iodone routine so that we can remove this dquot from the 1243 * Attach an iodone routine so that we can remove this dquot from the
1223 * AIL and release the flush lock once the dquot is synced to disk. 1244 * AIL and release the flush lock once the dquot is synced to disk.
1224 */ 1245 */
1225 xfs_buf_attach_iodone(bp, (void(*)(xfs_buf_t *, xfs_log_item_t *)) 1246 xfs_buf_attach_iodone(bp, xfs_qm_dqflush_done,
1226 xfs_qm_dqflush_done, &(dqp->q_logitem.qli_item)); 1247 &dqp->q_logitem.qli_item);
1248
1227 /* 1249 /*
1228 * If the buffer is pinned then push on the log so we won't 1250 * If the buffer is pinned then push on the log so we won't
1229 * get stuck waiting in the write for too long. 1251 * get stuck waiting in the write for too long.
@@ -1247,50 +1269,6 @@ xfs_qm_dqflush(
1247 1269
1248} 1270}
1249 1271
1250/*
1251 * This is the dquot flushing I/O completion routine. It is called
1252 * from interrupt level when the buffer containing the dquot is
1253 * flushed to disk. It is responsible for removing the dquot logitem
1254 * from the AIL if it has not been re-logged, and unlocking the dquot's
1255 * flush lock. This behavior is very similar to that of inodes..
1256 */
1257/*ARGSUSED*/
1258STATIC void
1259xfs_qm_dqflush_done(
1260 xfs_buf_t *bp,
1261 xfs_dq_logitem_t *qip)
1262{
1263 xfs_dquot_t *dqp;
1264 struct xfs_ail *ailp;
1265
1266 dqp = qip->qli_dquot;
1267 ailp = qip->qli_item.li_ailp;
1268
1269 /*
1270 * We only want to pull the item from the AIL if its
1271 * location in the log has not changed since we started the flush.
1272 * Thus, we only bother if the dquot's lsn has
1273 * not changed. First we check the lsn outside the lock
1274 * since it's cheaper, and then we recheck while
1275 * holding the lock before removing the dquot from the AIL.
1276 */
1277 if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
1278 qip->qli_item.li_lsn == qip->qli_flush_lsn) {
1279
1280 /* xfs_trans_ail_delete() drops the AIL lock. */
1281 spin_lock(&ailp->xa_lock);
1282 if (qip->qli_item.li_lsn == qip->qli_flush_lsn)
1283 xfs_trans_ail_delete(ailp, (xfs_log_item_t*)qip);
1284 else
1285 spin_unlock(&ailp->xa_lock);
1286 }
1287
1288 /*
1289 * Release the dq's flush lock since we're done with it.
1290 */
1291 xfs_dqfunlock(dqp);
1292}
1293
1294int 1272int
1295xfs_qm_dqlock_nowait( 1273xfs_qm_dqlock_nowait(
1296 xfs_dquot_t *dqp) 1274 xfs_dquot_t *dqp)