2 * Copyright (c) 2000-2003 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "xfs_trans.h"
26 #include "xfs_alloc.h"
27 #include "xfs_quota.h"
28 #include "xfs_mount.h"
29 #include "xfs_bmap_btree.h"
30 #include "xfs_inode.h"
32 #include "xfs_rtalloc.h"
33 #include "xfs_error.h"
34 #include "xfs_itable.h"
36 #include "xfs_buf_item.h"
37 #include "xfs_trans_priv.h"
41 * returns the number of iovecs needed to log the given dquot item.
45 xfs_qm_dquot_logitem_size(
46 xfs_dq_logitem_t
*logitem
)
49 * we need only two iovecs, one for the format, one for the real thing
55 * fills in the vector of log iovecs for the given dquot log item.
58 xfs_qm_dquot_logitem_format(
59 xfs_dq_logitem_t
*logitem
,
60 xfs_log_iovec_t
*logvec
)
63 ASSERT(logitem
->qli_dquot
);
65 logvec
->i_addr
= (xfs_caddr_t
)&logitem
->qli_format
;
66 logvec
->i_len
= sizeof(xfs_dq_logformat_t
);
67 logvec
->i_type
= XLOG_REG_TYPE_QFORMAT
;
69 logvec
->i_addr
= (xfs_caddr_t
)&logitem
->qli_dquot
->q_core
;
70 logvec
->i_len
= sizeof(xfs_disk_dquot_t
);
71 logvec
->i_type
= XLOG_REG_TYPE_DQUOT
;
73 ASSERT(2 == logitem
->qli_item
.li_desc
->lid_size
);
74 logitem
->qli_format
.qlf_size
= 2;
79 * Increment the pin count of the given dquot.
82 xfs_qm_dquot_logitem_pin(
83 xfs_dq_logitem_t
*logitem
)
85 xfs_dquot_t
*dqp
= logitem
->qli_dquot
;
87 ASSERT(XFS_DQ_IS_LOCKED(dqp
));
88 atomic_inc(&dqp
->q_pincount
);
92 * Decrement the pin count of the given dquot, and wake up
93 * anyone in xfs_dqwait_unpin() if the count goes to 0. The
94 * dquot must have been previously pinned with a call to
95 * xfs_qm_dquot_logitem_pin().
99 xfs_qm_dquot_logitem_unpin(
100 xfs_dq_logitem_t
*logitem
,
103 xfs_dquot_t
*dqp
= logitem
->qli_dquot
;
105 ASSERT(atomic_read(&dqp
->q_pincount
) > 0);
106 if (atomic_dec_and_test(&dqp
->q_pincount
))
107 wake_up(&dqp
->q_pinwait
);
111 * Given the logitem, this writes the corresponding dquot entry to disk
112 * asynchronously. This is called with the dquot entry securely locked;
113 * we simply get xfs_qm_dqflush() to do the work, and unlock the dquot
117 xfs_qm_dquot_logitem_push(
118 xfs_dq_logitem_t
*logitem
)
123 dqp
= logitem
->qli_dquot
;
125 ASSERT(XFS_DQ_IS_LOCKED(dqp
));
126 ASSERT(!completion_done(&dqp
->q_flush
));
129 * Since we were able to lock the dquot's flush lock and
130 * we found it on the AIL, the dquot must be dirty. This
131 * is because the dquot is removed from the AIL while still
132 * holding the flush lock in xfs_dqflush_done(). Thus, if
133 * we found it in the AIL and were able to obtain the flush
134 * lock without sleeping, then there must not have been
135 * anyone in the process of flushing the dquot.
137 error
= xfs_qm_dqflush(dqp
, 0);
139 xfs_fs_cmn_err(CE_WARN
, dqp
->q_mount
,
140 "xfs_qm_dquot_logitem_push: push error %d on dqp %p",
147 xfs_qm_dquot_logitem_committed(
152 * We always re-log the entire dquot when it becomes dirty,
153 * so, the latest copy _is_ the only one that matters.
160 * This is called to wait for the given dquot to be unpinned.
161 * Most of these pin/unpin routines are plagiarized from inode code.
167 ASSERT(XFS_DQ_IS_LOCKED(dqp
));
168 if (atomic_read(&dqp
->q_pincount
) == 0)
172 * Give the log a push so we don't wait here too long.
174 xfs_log_force(dqp
->q_mount
, 0);
175 wait_event(dqp
->q_pinwait
, (atomic_read(&dqp
->q_pincount
) == 0));
179 * This is called when IOP_TRYLOCK returns XFS_ITEM_PUSHBUF to indicate that
180 * the dquot is locked by us, but the flush lock isn't. So, here we are
181 * going to see if the relevant dquot buffer is incore, waiting on DELWRI.
182 * If so, we want to push it out to help us take this item off the AIL as soon
185 * We must not be holding the AIL lock at this point. Calling incore() to
186 * search the buffer cache can be a time consuming thing, and AIL lock is a
190 xfs_qm_dquot_logitem_pushbuf(
191 xfs_dq_logitem_t
*qip
)
197 dqp
= qip
->qli_dquot
;
198 ASSERT(XFS_DQ_IS_LOCKED(dqp
));
201 * If flushlock isn't locked anymore, chances are that the
202 * inode flush completed and the inode was taken off the AIL.
205 if (completion_done(&dqp
->q_flush
) ||
206 ((qip
->qli_item
.li_flags
& XFS_LI_IN_AIL
) == 0)) {
211 bp
= xfs_incore(mp
->m_ddev_targp
, qip
->qli_format
.qlf_blkno
,
212 mp
->m_quotainfo
->qi_dqchunklen
, XBF_TRYLOCK
);
216 if (XFS_BUF_ISDELAYWRITE(bp
))
217 xfs_buf_delwri_promote(bp
);
224 * This is called to attempt to lock the dquot associated with this
225 * dquot log item. Don't sleep on the dquot lock or the flush lock.
226 * If the flush lock is already held, indicating that the dquot has
227 * been or is in the process of being flushed, then see if we can
228 * find the dquot's buffer in the buffer cache without sleeping. If
229 * we can and it is marked delayed write, then we want to send it out.
230 * We delay doing so until the push routine, though, to avoid sleeping
231 * in any device strategy routines.
234 xfs_qm_dquot_logitem_trylock(
235 xfs_dq_logitem_t
*qip
)
239 dqp
= qip
->qli_dquot
;
240 if (atomic_read(&dqp
->q_pincount
) > 0)
241 return XFS_ITEM_PINNED
;
243 if (! xfs_qm_dqlock_nowait(dqp
))
244 return XFS_ITEM_LOCKED
;
246 if (!xfs_dqflock_nowait(dqp
)) {
248 * dquot has already been flushed to the backing buffer,
249 * leave it locked, pushbuf routine will unlock it.
251 return XFS_ITEM_PUSHBUF
;
254 ASSERT(qip
->qli_item
.li_flags
& XFS_LI_IN_AIL
);
255 return XFS_ITEM_SUCCESS
;
260 * Unlock the dquot associated with the log item.
261 * Clear the fields of the dquot and dquot log item that
262 * are specific to the current transaction. If the
263 * hold flags is set, do not unlock the dquot.
266 xfs_qm_dquot_logitem_unlock(
267 xfs_dq_logitem_t
*ql
)
273 ASSERT(XFS_DQ_IS_LOCKED(dqp
));
276 * Clear the transaction pointer in the dquot
278 dqp
->q_transp
= NULL
;
281 * dquots are never 'held' from getting unlocked at the end of
282 * a transaction. Their locking and unlocking is hidden inside the
283 * transaction layer, within trans_commit. Hence, no LI_HOLD flag
291 * this needs to stamp an lsn into the dquot, I think.
292 * rpc's that look at user dquot's would then have to
293 * push on the dependency recorded in the dquot
297 xfs_qm_dquot_logitem_committing(
306 * This is the ops vector for dquots
308 static struct xfs_item_ops xfs_dquot_item_ops
= {
309 .iop_size
= (uint(*)(xfs_log_item_t
*))xfs_qm_dquot_logitem_size
,
310 .iop_format
= (void(*)(xfs_log_item_t
*, xfs_log_iovec_t
*))
311 xfs_qm_dquot_logitem_format
,
312 .iop_pin
= (void(*)(xfs_log_item_t
*))xfs_qm_dquot_logitem_pin
,
313 .iop_unpin
= (void(*)(xfs_log_item_t
*, int))xfs_qm_dquot_logitem_unpin
,
314 .iop_trylock
= (uint(*)(xfs_log_item_t
*))
315 xfs_qm_dquot_logitem_trylock
,
316 .iop_unlock
= (void(*)(xfs_log_item_t
*))xfs_qm_dquot_logitem_unlock
,
317 .iop_committed
= (xfs_lsn_t(*)(xfs_log_item_t
*, xfs_lsn_t
))
318 xfs_qm_dquot_logitem_committed
,
319 .iop_push
= (void(*)(xfs_log_item_t
*))xfs_qm_dquot_logitem_push
,
320 .iop_pushbuf
= (void(*)(xfs_log_item_t
*))
321 xfs_qm_dquot_logitem_pushbuf
,
322 .iop_committing
= (void(*)(xfs_log_item_t
*, xfs_lsn_t
))
323 xfs_qm_dquot_logitem_committing
327 * Initialize the dquot log item for a newly allocated dquot.
328 * The dquot isn't locked at this point, but it isn't on any of the lists
329 * either, so we don't care.
332 xfs_qm_dquot_logitem_init(
333 struct xfs_dquot
*dqp
)
335 xfs_dq_logitem_t
*lp
;
336 lp
= &dqp
->q_logitem
;
338 xfs_log_item_init(dqp
->q_mount
, &lp
->qli_item
, XFS_LI_DQUOT
,
339 &xfs_dquot_item_ops
);
341 lp
->qli_format
.qlf_type
= XFS_LI_DQUOT
;
342 lp
->qli_format
.qlf_id
= be32_to_cpu(dqp
->q_core
.d_id
);
343 lp
->qli_format
.qlf_blkno
= dqp
->q_blkno
;
344 lp
->qli_format
.qlf_len
= 1;
346 * This is just the offset of this dquot within its buffer
347 * (which is currently 1 FSB and probably won't change).
348 * Hence 32 bits for this offset should be just fine.
349 * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t))
350 * here, and recompute it at recovery time.
352 lp
->qli_format
.qlf_boffset
= (__uint32_t
)dqp
->q_bufoffset
;
355 /*------------------ QUOTAOFF LOG ITEMS -------------------*/
358 * This returns the number of iovecs needed to log the given quotaoff item.
359 * We only need 1 iovec for an quotaoff item. It just logs the
360 * quotaoff_log_format structure.
364 xfs_qm_qoff_logitem_size(xfs_qoff_logitem_t
*qf
)
370 * This is called to fill in the vector of log iovecs for the
371 * given quotaoff log item. We use only 1 iovec, and we point that
372 * at the quotaoff_log_format structure embedded in the quotaoff item.
373 * It is at this point that we assert that all of the extent
374 * slots in the quotaoff item have been filled.
377 xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t
*qf
,
378 xfs_log_iovec_t
*log_vector
)
380 ASSERT(qf
->qql_format
.qf_type
== XFS_LI_QUOTAOFF
);
382 log_vector
->i_addr
= (xfs_caddr_t
)&(qf
->qql_format
);
383 log_vector
->i_len
= sizeof(xfs_qoff_logitem_t
);
384 log_vector
->i_type
= XLOG_REG_TYPE_QUOTAOFF
;
385 qf
->qql_format
.qf_size
= 1;
390 * Pinning has no meaning for an quotaoff item, so just return.
394 xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t
*qf
)
401 * Since pinning has no meaning for an quotaoff item, unpinning does
406 xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t
*qf
, int remove
)
412 * Quotaoff items have no locking, so just return success.
416 xfs_qm_qoff_logitem_trylock(xfs_qoff_logitem_t
*qf
)
418 return XFS_ITEM_LOCKED
;
422 * Quotaoff items have no locking or pushing, so return failure
423 * so that the caller doesn't bother with us.
427 xfs_qm_qoff_logitem_unlock(xfs_qoff_logitem_t
*qf
)
433 * The quotaoff-start-item is logged only once and cannot be moved in the log,
434 * so simply return the lsn at which it's been logged.
438 xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t
*qf
, xfs_lsn_t lsn
)
444 * There isn't much you can do to push on an quotaoff item. It is simply
445 * stuck waiting for the log to be flushed to disk.
449 xfs_qm_qoff_logitem_push(xfs_qoff_logitem_t
*qf
)
457 xfs_qm_qoffend_logitem_committed(
458 xfs_qoff_logitem_t
*qfe
,
461 xfs_qoff_logitem_t
*qfs
;
462 struct xfs_ail
*ailp
;
464 qfs
= qfe
->qql_start_lip
;
465 ailp
= qfs
->qql_item
.li_ailp
;
466 spin_lock(&ailp
->xa_lock
);
468 * Delete the qoff-start logitem from the AIL.
469 * xfs_trans_ail_delete() drops the AIL lock.
471 xfs_trans_ail_delete(ailp
, (xfs_log_item_t
*)qfs
);
474 return (xfs_lsn_t
)-1;
478 * XXX rcc - don't know quite what to do with this. I think we can
479 * just ignore it. The only time that isn't the case is if we allow
480 * the client to somehow see that quotas have been turned off in which
481 * we can't allow that to get back until the quotaoff hits the disk.
482 * So how would that happen? Also, do we need different routines for
483 * quotaoff start and quotaoff end? I suspect the answer is yes but
484 * to be sure, I need to look at the recovery code and see how quota off
485 * recovery is handled (do we roll forward or back or do something else).
486 * If we roll forwards or backwards, then we need two separate routines,
487 * one that does nothing and one that stamps in the lsn that matters
488 * (truly makes the quotaoff irrevocable). If we do something else,
489 * then maybe we don't need two.
493 xfs_qm_qoff_logitem_committing(xfs_qoff_logitem_t
*qip
, xfs_lsn_t commit_lsn
)
500 xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t
*qip
, xfs_lsn_t commit_lsn
)
505 static struct xfs_item_ops xfs_qm_qoffend_logitem_ops
= {
506 .iop_size
= (uint(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_size
,
507 .iop_format
= (void(*)(xfs_log_item_t
*, xfs_log_iovec_t
*))
508 xfs_qm_qoff_logitem_format
,
509 .iop_pin
= (void(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_pin
,
510 .iop_unpin
= (void(*)(xfs_log_item_t
*, int))xfs_qm_qoff_logitem_unpin
,
511 .iop_trylock
= (uint(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_trylock
,
512 .iop_unlock
= (void(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_unlock
,
513 .iop_committed
= (xfs_lsn_t(*)(xfs_log_item_t
*, xfs_lsn_t
))
514 xfs_qm_qoffend_logitem_committed
,
515 .iop_push
= (void(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_push
,
517 .iop_committing
= (void(*)(xfs_log_item_t
*, xfs_lsn_t
))
518 xfs_qm_qoffend_logitem_committing
522 * This is the ops vector shared by all quotaoff-start log items.
524 static struct xfs_item_ops xfs_qm_qoff_logitem_ops
= {
525 .iop_size
= (uint(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_size
,
526 .iop_format
= (void(*)(xfs_log_item_t
*, xfs_log_iovec_t
*))
527 xfs_qm_qoff_logitem_format
,
528 .iop_pin
= (void(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_pin
,
529 .iop_unpin
= (void(*)(xfs_log_item_t
*, int))xfs_qm_qoff_logitem_unpin
,
530 .iop_trylock
= (uint(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_trylock
,
531 .iop_unlock
= (void(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_unlock
,
532 .iop_committed
= (xfs_lsn_t(*)(xfs_log_item_t
*, xfs_lsn_t
))
533 xfs_qm_qoff_logitem_committed
,
534 .iop_push
= (void(*)(xfs_log_item_t
*))xfs_qm_qoff_logitem_push
,
536 .iop_committing
= (void(*)(xfs_log_item_t
*, xfs_lsn_t
))
537 xfs_qm_qoff_logitem_committing
541 * Allocate and initialize an quotaoff item of the correct quota type(s).
544 xfs_qm_qoff_logitem_init(
545 struct xfs_mount
*mp
,
546 xfs_qoff_logitem_t
*start
,
549 xfs_qoff_logitem_t
*qf
;
551 qf
= (xfs_qoff_logitem_t
*) kmem_zalloc(sizeof(xfs_qoff_logitem_t
), KM_SLEEP
);
553 xfs_log_item_init(mp
, &qf
->qql_item
, XFS_LI_QUOTAOFF
, start
?
554 &xfs_qm_qoffend_logitem_ops
: &xfs_qm_qoff_logitem_ops
);
555 qf
->qql_item
.li_mountp
= mp
;
556 qf
->qql_format
.qf_type
= XFS_LI_QUOTAOFF
;
557 qf
->qql_format
.qf_flags
= flags
;
558 qf
->qql_start_lip
= start
;