aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dquot_item.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dquot_item.c')
-rw-r--r--fs/xfs/xfs_dquot_item.c162
1 files changed, 44 insertions, 118 deletions
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
index 34baeae4526..57aa4b03720 100644
--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -17,9 +17,7 @@
17 */ 17 */
18#include "xfs.h" 18#include "xfs.h"
19#include "xfs_fs.h" 19#include "xfs_fs.h"
20#include "xfs_bit.h"
21#include "xfs_log.h" 20#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h" 21#include "xfs_trans.h"
24#include "xfs_sb.h" 22#include "xfs_sb.h"
25#include "xfs_ag.h" 23#include "xfs_ag.h"
@@ -108,38 +106,6 @@ xfs_qm_dquot_logitem_unpin(
108 wake_up(&dqp->q_pinwait); 106 wake_up(&dqp->q_pinwait);
109} 107}
110 108
111/*
112 * Given the logitem, this writes the corresponding dquot entry to disk
113 * asynchronously. This is called with the dquot entry securely locked;
114 * we simply get xfs_qm_dqflush() to do the work, and unlock the dquot
115 * at the end.
116 */
117STATIC void
118xfs_qm_dquot_logitem_push(
119 struct xfs_log_item *lip)
120{
121 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
122 int error;
123
124 ASSERT(XFS_DQ_IS_LOCKED(dqp));
125 ASSERT(!completion_done(&dqp->q_flush));
126
127 /*
128 * Since we were able to lock the dquot's flush lock and
129 * we found it on the AIL, the dquot must be dirty. This
130 * is because the dquot is removed from the AIL while still
131 * holding the flush lock in xfs_dqflush_done(). Thus, if
132 * we found it in the AIL and were able to obtain the flush
133 * lock without sleeping, then there must not have been
134 * anyone in the process of flushing the dquot.
135 */
136 error = xfs_qm_dqflush(dqp, SYNC_TRYLOCK);
137 if (error)
138 xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p",
139 __func__, error, dqp);
140 xfs_dqunlock(dqp);
141}
142
143STATIC xfs_lsn_t 109STATIC xfs_lsn_t
144xfs_qm_dquot_logitem_committed( 110xfs_qm_dquot_logitem_committed(
145 struct xfs_log_item *lip, 111 struct xfs_log_item *lip,
@@ -171,67 +137,15 @@ xfs_qm_dqunpin_wait(
171 wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); 137 wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
172} 138}
173 139
174/*
175 * This is called when IOP_TRYLOCK returns XFS_ITEM_PUSHBUF to indicate that
176 * the dquot is locked by us, but the flush lock isn't. So, here we are
177 * going to see if the relevant dquot buffer is incore, waiting on DELWRI.
178 * If so, we want to push it out to help us take this item off the AIL as soon
179 * as possible.
180 *
181 * We must not be holding the AIL lock at this point. Calling incore() to
182 * search the buffer cache can be a time consuming thing, and AIL lock is a
183 * spinlock.
184 */
185STATIC bool
186xfs_qm_dquot_logitem_pushbuf(
187 struct xfs_log_item *lip)
188{
189 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
190 struct xfs_dquot *dqp = qlip->qli_dquot;
191 struct xfs_buf *bp;
192 bool ret = true;
193
194 ASSERT(XFS_DQ_IS_LOCKED(dqp));
195
196 /*
197 * If flushlock isn't locked anymore, chances are that the
198 * inode flush completed and the inode was taken off the AIL.
199 * So, just get out.
200 */
201 if (completion_done(&dqp->q_flush) ||
202 !(lip->li_flags & XFS_LI_IN_AIL)) {
203 xfs_dqunlock(dqp);
204 return true;
205 }
206
207 bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno,
208 dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
209 xfs_dqunlock(dqp);
210 if (!bp)
211 return true;
212 if (XFS_BUF_ISDELAYWRITE(bp))
213 xfs_buf_delwri_promote(bp);
214 if (xfs_buf_ispinned(bp))
215 ret = false;
216 xfs_buf_relse(bp);
217 return ret;
218}
219
220/*
221 * This is called to attempt to lock the dquot associated with this
222 * dquot log item. Don't sleep on the dquot lock or the flush lock.
223 * If the flush lock is already held, indicating that the dquot has
224 * been or is in the process of being flushed, then see if we can
225 * find the dquot's buffer in the buffer cache without sleeping. If
226 * we can and it is marked delayed write, then we want to send it out.
227 * We delay doing so until the push routine, though, to avoid sleeping
228 * in any device strategy routines.
229 */
230STATIC uint 140STATIC uint
231xfs_qm_dquot_logitem_trylock( 141xfs_qm_dquot_logitem_push(
232 struct xfs_log_item *lip) 142 struct xfs_log_item *lip,
143 struct list_head *buffer_list)
233{ 144{
234 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 145 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
146 struct xfs_buf *bp = NULL;
147 uint rval = XFS_ITEM_SUCCESS;
148 int error;
235 149
236 if (atomic_read(&dqp->q_pincount) > 0) 150 if (atomic_read(&dqp->q_pincount) > 0)
237 return XFS_ITEM_PINNED; 151 return XFS_ITEM_PINNED;
@@ -239,16 +153,41 @@ xfs_qm_dquot_logitem_trylock(
239 if (!xfs_dqlock_nowait(dqp)) 153 if (!xfs_dqlock_nowait(dqp))
240 return XFS_ITEM_LOCKED; 154 return XFS_ITEM_LOCKED;
241 155
156 /*
157 * Re-check the pincount now that we stabilized the value by
158 * taking the quota lock.
159 */
160 if (atomic_read(&dqp->q_pincount) > 0) {
161 rval = XFS_ITEM_PINNED;
162 goto out_unlock;
163 }
164
165 /*
166 * Someone else is already flushing the dquot. Nothing we can do
167 * here but wait for the flush to finish and remove the item from
168 * the AIL.
169 */
242 if (!xfs_dqflock_nowait(dqp)) { 170 if (!xfs_dqflock_nowait(dqp)) {
243 /* 171 rval = XFS_ITEM_FLUSHING;
244 * dquot has already been flushed to the backing buffer, 172 goto out_unlock;
245 * leave it locked, pushbuf routine will unlock it.
246 */
247 return XFS_ITEM_PUSHBUF;
248 } 173 }
249 174
250 ASSERT(lip->li_flags & XFS_LI_IN_AIL); 175 spin_unlock(&lip->li_ailp->xa_lock);
251 return XFS_ITEM_SUCCESS; 176
177 error = xfs_qm_dqflush(dqp, &bp);
178 if (error) {
179 xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p",
180 __func__, error, dqp);
181 } else {
182 if (!xfs_buf_delwri_queue(bp, buffer_list))
183 rval = XFS_ITEM_FLUSHING;
184 xfs_buf_relse(bp);
185 }
186
187 spin_lock(&lip->li_ailp->xa_lock);
188out_unlock:
189 xfs_dqunlock(dqp);
190 return rval;
252} 191}
253 192
254/* 193/*
@@ -299,11 +238,9 @@ static const struct xfs_item_ops xfs_dquot_item_ops = {
299 .iop_format = xfs_qm_dquot_logitem_format, 238 .iop_format = xfs_qm_dquot_logitem_format,
300 .iop_pin = xfs_qm_dquot_logitem_pin, 239 .iop_pin = xfs_qm_dquot_logitem_pin,
301 .iop_unpin = xfs_qm_dquot_logitem_unpin, 240 .iop_unpin = xfs_qm_dquot_logitem_unpin,
302 .iop_trylock = xfs_qm_dquot_logitem_trylock,
303 .iop_unlock = xfs_qm_dquot_logitem_unlock, 241 .iop_unlock = xfs_qm_dquot_logitem_unlock,
304 .iop_committed = xfs_qm_dquot_logitem_committed, 242 .iop_committed = xfs_qm_dquot_logitem_committed,
305 .iop_push = xfs_qm_dquot_logitem_push, 243 .iop_push = xfs_qm_dquot_logitem_push,
306 .iop_pushbuf = xfs_qm_dquot_logitem_pushbuf,
307 .iop_committing = xfs_qm_dquot_logitem_committing 244 .iop_committing = xfs_qm_dquot_logitem_committing
308}; 245};
309 246
@@ -398,11 +335,13 @@ xfs_qm_qoff_logitem_unpin(
398} 335}
399 336
400/* 337/*
401 * Quotaoff items have no locking, so just return success. 338 * There isn't much you can do to push a quotaoff item. It is simply
339 * stuck waiting for the log to be flushed to disk.
402 */ 340 */
403STATIC uint 341STATIC uint
404xfs_qm_qoff_logitem_trylock( 342xfs_qm_qoff_logitem_push(
405 struct xfs_log_item *lip) 343 struct xfs_log_item *lip,
344 struct list_head *buffer_list)
406{ 345{
407 return XFS_ITEM_LOCKED; 346 return XFS_ITEM_LOCKED;
408} 347}
@@ -429,17 +368,6 @@ xfs_qm_qoff_logitem_committed(
429 return lsn; 368 return lsn;
430} 369}
431 370
432/*
433 * There isn't much you can do to push on an quotaoff item. It is simply
434 * stuck waiting for the log to be flushed to disk.
435 */
436STATIC void
437xfs_qm_qoff_logitem_push(
438 struct xfs_log_item *lip)
439{
440}
441
442
443STATIC xfs_lsn_t 371STATIC xfs_lsn_t
444xfs_qm_qoffend_logitem_committed( 372xfs_qm_qoffend_logitem_committed(
445 struct xfs_log_item *lip, 373 struct xfs_log_item *lip,
@@ -454,7 +382,7 @@ xfs_qm_qoffend_logitem_committed(
454 * xfs_trans_ail_delete() drops the AIL lock. 382 * xfs_trans_ail_delete() drops the AIL lock.
455 */ 383 */
456 spin_lock(&ailp->xa_lock); 384 spin_lock(&ailp->xa_lock);
457 xfs_trans_ail_delete(ailp, (xfs_log_item_t *)qfs); 385 xfs_trans_ail_delete(ailp, &qfs->qql_item, SHUTDOWN_LOG_IO_ERROR);
458 386
459 kmem_free(qfs); 387 kmem_free(qfs);
460 kmem_free(qfe); 388 kmem_free(qfe);
@@ -487,7 +415,6 @@ static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
487 .iop_format = xfs_qm_qoff_logitem_format, 415 .iop_format = xfs_qm_qoff_logitem_format,
488 .iop_pin = xfs_qm_qoff_logitem_pin, 416 .iop_pin = xfs_qm_qoff_logitem_pin,
489 .iop_unpin = xfs_qm_qoff_logitem_unpin, 417 .iop_unpin = xfs_qm_qoff_logitem_unpin,
490 .iop_trylock = xfs_qm_qoff_logitem_trylock,
491 .iop_unlock = xfs_qm_qoff_logitem_unlock, 418 .iop_unlock = xfs_qm_qoff_logitem_unlock,
492 .iop_committed = xfs_qm_qoffend_logitem_committed, 419 .iop_committed = xfs_qm_qoffend_logitem_committed,
493 .iop_push = xfs_qm_qoff_logitem_push, 420 .iop_push = xfs_qm_qoff_logitem_push,
@@ -502,7 +429,6 @@ static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
502 .iop_format = xfs_qm_qoff_logitem_format, 429 .iop_format = xfs_qm_qoff_logitem_format,
503 .iop_pin = xfs_qm_qoff_logitem_pin, 430 .iop_pin = xfs_qm_qoff_logitem_pin,
504 .iop_unpin = xfs_qm_qoff_logitem_unpin, 431 .iop_unpin = xfs_qm_qoff_logitem_unpin,
505 .iop_trylock = xfs_qm_qoff_logitem_trylock,
506 .iop_unlock = xfs_qm_qoff_logitem_unlock, 432 .iop_unlock = xfs_qm_qoff_logitem_unlock,
507 .iop_committed = xfs_qm_qoff_logitem_committed, 433 .iop_committed = xfs_qm_qoff_logitem_committed,
508 .iop_push = xfs_qm_qoff_logitem_push, 434 .iop_push = xfs_qm_qoff_logitem_push,