diff options
Diffstat (limited to 'fs/xfs/quota')
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 91 |
1 files changed, 43 insertions, 48 deletions
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index f152af8cfab0..6526e87cade0 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -54,8 +54,6 @@ | |||
54 | flush lock - ditto. | 54 | flush lock - ditto. |
55 | */ | 55 | */ |
56 | 56 | ||
57 | STATIC void xfs_qm_dqflush_done(xfs_buf_t *, xfs_dq_logitem_t *); | ||
58 | |||
59 | #ifdef DEBUG | 57 | #ifdef DEBUG |
60 | xfs_buftarg_t *xfs_dqerror_target; | 58 | xfs_buftarg_t *xfs_dqerror_target; |
61 | int xfs_do_dqerror; | 59 | int xfs_do_dqerror; |
@@ -1131,6 +1129,46 @@ xfs_qm_dqrele( | |||
1131 | xfs_qm_dqput(dqp); | 1129 | xfs_qm_dqput(dqp); |
1132 | } | 1130 | } |
1133 | 1131 | ||
1132 | /* | ||
1133 | * This is the dquot flushing I/O completion routine. It is called | ||
1134 | * from interrupt level when the buffer containing the dquot is | ||
1135 | * flushed to disk. It is responsible for removing the dquot logitem | ||
1136 | * from the AIL if it has not been re-logged, and unlocking the dquot's | ||
1137 | * flush lock. This behavior is very similar to that of inodes.. | ||
1138 | */ | ||
1139 | STATIC void | ||
1140 | xfs_qm_dqflush_done( | ||
1141 | struct xfs_buf *bp, | ||
1142 | struct xfs_log_item *lip) | ||
1143 | { | ||
1144 | xfs_dq_logitem_t *qip = (struct xfs_dq_logitem *)lip; | ||
1145 | xfs_dquot_t *dqp = qip->qli_dquot; | ||
1146 | struct xfs_ail *ailp = lip->li_ailp; | ||
1147 | |||
1148 | /* | ||
1149 | * We only want to pull the item from the AIL if its | ||
1150 | * location in the log has not changed since we started the flush. | ||
1151 | * Thus, we only bother if the dquot's lsn has | ||
1152 | * not changed. First we check the lsn outside the lock | ||
1153 | * since it's cheaper, and then we recheck while | ||
1154 | * holding the lock before removing the dquot from the AIL. | ||
1155 | */ | ||
1156 | if ((lip->li_flags & XFS_LI_IN_AIL) && | ||
1157 | lip->li_lsn == qip->qli_flush_lsn) { | ||
1158 | |||
1159 | /* xfs_trans_ail_delete() drops the AIL lock. */ | ||
1160 | spin_lock(&ailp->xa_lock); | ||
1161 | if (lip->li_lsn == qip->qli_flush_lsn) | ||
1162 | xfs_trans_ail_delete(ailp, lip); | ||
1163 | else | ||
1164 | spin_unlock(&ailp->xa_lock); | ||
1165 | } | ||
1166 | |||
1167 | /* | ||
1168 | * Release the dq's flush lock since we're done with it. | ||
1169 | */ | ||
1170 | xfs_dqfunlock(dqp); | ||
1171 | } | ||
1134 | 1172 | ||
1135 | /* | 1173 | /* |
1136 | * Write a modified dquot to disk. | 1174 | * Write a modified dquot to disk. |
@@ -1212,8 +1250,9 @@ xfs_qm_dqflush( | |||
1212 | * Attach an iodone routine so that we can remove this dquot from the | 1250 | * Attach an iodone routine so that we can remove this dquot from the |
1213 | * AIL and release the flush lock once the dquot is synced to disk. | 1251 | * AIL and release the flush lock once the dquot is synced to disk. |
1214 | */ | 1252 | */ |
1215 | xfs_buf_attach_iodone(bp, (void(*)(xfs_buf_t *, xfs_log_item_t *)) | 1253 | xfs_buf_attach_iodone(bp, xfs_qm_dqflush_done, |
1216 | xfs_qm_dqflush_done, &(dqp->q_logitem.qli_item)); | 1254 | &dqp->q_logitem.qli_item); |
1255 | |||
1217 | /* | 1256 | /* |
1218 | * If the buffer is pinned then push on the log so we won't | 1257 | * If the buffer is pinned then push on the log so we won't |
1219 | * get stuck waiting in the write for too long. | 1258 | * get stuck waiting in the write for too long. |
@@ -1237,50 +1276,6 @@ xfs_qm_dqflush( | |||
1237 | 1276 | ||
1238 | } | 1277 | } |
1239 | 1278 | ||
1240 | /* | ||
1241 | * This is the dquot flushing I/O completion routine. It is called | ||
1242 | * from interrupt level when the buffer containing the dquot is | ||
1243 | * flushed to disk. It is responsible for removing the dquot logitem | ||
1244 | * from the AIL if it has not been re-logged, and unlocking the dquot's | ||
1245 | * flush lock. This behavior is very similar to that of inodes.. | ||
1246 | */ | ||
1247 | /*ARGSUSED*/ | ||
1248 | STATIC void | ||
1249 | xfs_qm_dqflush_done( | ||
1250 | xfs_buf_t *bp, | ||
1251 | xfs_dq_logitem_t *qip) | ||
1252 | { | ||
1253 | xfs_dquot_t *dqp; | ||
1254 | struct xfs_ail *ailp; | ||
1255 | |||
1256 | dqp = qip->qli_dquot; | ||
1257 | ailp = qip->qli_item.li_ailp; | ||
1258 | |||
1259 | /* | ||
1260 | * We only want to pull the item from the AIL if its | ||
1261 | * location in the log has not changed since we started the flush. | ||
1262 | * Thus, we only bother if the dquot's lsn has | ||
1263 | * not changed. First we check the lsn outside the lock | ||
1264 | * since it's cheaper, and then we recheck while | ||
1265 | * holding the lock before removing the dquot from the AIL. | ||
1266 | */ | ||
1267 | if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && | ||
1268 | qip->qli_item.li_lsn == qip->qli_flush_lsn) { | ||
1269 | |||
1270 | /* xfs_trans_ail_delete() drops the AIL lock. */ | ||
1271 | spin_lock(&ailp->xa_lock); | ||
1272 | if (qip->qli_item.li_lsn == qip->qli_flush_lsn) | ||
1273 | xfs_trans_ail_delete(ailp, (xfs_log_item_t*)qip); | ||
1274 | else | ||
1275 | spin_unlock(&ailp->xa_lock); | ||
1276 | } | ||
1277 | |||
1278 | /* | ||
1279 | * Release the dq's flush lock since we're done with it. | ||
1280 | */ | ||
1281 | xfs_dqfunlock(dqp); | ||
1282 | } | ||
1283 | |||
1284 | int | 1279 | int |
1285 | xfs_qm_dqlock_nowait( | 1280 | xfs_qm_dqlock_nowait( |
1286 | xfs_dquot_t *dqp) | 1281 | xfs_dquot_t *dqp) |