diff options
Diffstat (limited to 'fs/xfs/quota/xfs_dquot.c')
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 114 |
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 | ||
67 | STATIC void xfs_qm_dqflush_done(xfs_buf_t *, xfs_dq_logitem_t *); | ||
68 | |||
69 | #ifdef DEBUG | 57 | #ifdef DEBUG |
70 | xfs_buftarg_t *xfs_dqerror_target; | 58 | xfs_buftarg_t *xfs_dqerror_target; |
71 | int xfs_do_dqerror; | 59 | int 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 | */ | ||
1132 | STATIC void | ||
1133 | xfs_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*/ | ||
1258 | STATIC void | ||
1259 | xfs_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 | |||
1294 | int | 1272 | int |
1295 | xfs_qm_dqlock_nowait( | 1273 | xfs_qm_dqlock_nowait( |
1296 | xfs_dquot_t *dqp) | 1274 | xfs_dquot_t *dqp) |