Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6] / fs / xfs / quota / xfs_dquot_item.c
1 /*
2  * Copyright (c) 2000-2003 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
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.
8  *
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.
13  *
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
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_bit.h"
21 #include "xfs_log.h"
22 #include "xfs_inum.h"
23 #include "xfs_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_dir2.h"
27 #include "xfs_alloc.h"
28 #include "xfs_dmapi.h"
29 #include "xfs_quota.h"
30 #include "xfs_mount.h"
31 #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"
38 #include "xfs_bmap.h"
39 #include "xfs_btree.h"
40 #include "xfs_ialloc.h"
41 #include "xfs_rtalloc.h"
42 #include "xfs_error.h"
43 #include "xfs_itable.h"
44 #include "xfs_rw.h"
45 #include "xfs_acl.h"
46 #include "xfs_attr.h"
47 #include "xfs_buf_item.h"
48 #include "xfs_trans_priv.h"
49 #include "xfs_qm.h"
50
51 /*
52  * returns the number of iovecs needed to log the given dquot item.
53  */
54 /* ARGSUSED */
55 STATIC uint
56 xfs_qm_dquot_logitem_size(
57         xfs_dq_logitem_t        *logitem)
58 {
59         /*
60          * we need only two iovecs, one for the format, one for the real thing
61          */
62         return (2);
63 }
64
65 /*
66  * fills in the vector of log iovecs for the given dquot log item.
67  */
68 STATIC void
69 xfs_qm_dquot_logitem_format(
70         xfs_dq_logitem_t        *logitem,
71         xfs_log_iovec_t         *logvec)
72 {
73         ASSERT(logitem);
74         ASSERT(logitem->qli_dquot);
75
76         logvec->i_addr = (xfs_caddr_t)&logitem->qli_format;
77         logvec->i_len  = sizeof(xfs_dq_logformat_t);
78         XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_QFORMAT);
79         logvec++;
80         logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core;
81         logvec->i_len  = sizeof(xfs_disk_dquot_t);
82         XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_DQUOT);
83
84         ASSERT(2 == logitem->qli_item.li_desc->lid_size);
85         logitem->qli_format.qlf_size = 2;
86
87 }
88
89 /*
90  * Increment the pin count of the given dquot.
91  * This value is protected by pinlock spinlock in the xQM structure.
92  */
93 STATIC void
94 xfs_qm_dquot_logitem_pin(
95         xfs_dq_logitem_t *logitem)
96 {
97         xfs_dquot_t *dqp;
98
99         dqp = logitem->qli_dquot;
100         ASSERT(XFS_DQ_IS_LOCKED(dqp));
101         spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
102         dqp->q_pincount++;
103         spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
104 }
105
106 /*
107  * Decrement the pin count of the given dquot, and wake up
108  * anyone in xfs_dqwait_unpin() if the count goes to 0.  The
109  * dquot must have been previously pinned with a call to xfs_dqpin().
110  */
111 /* ARGSUSED */
112 STATIC void
113 xfs_qm_dquot_logitem_unpin(
114         xfs_dq_logitem_t *logitem,
115         int               stale)
116 {
117         xfs_dquot_t *dqp;
118
119         dqp = logitem->qli_dquot;
120         ASSERT(dqp->q_pincount > 0);
121         spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
122         dqp->q_pincount--;
123         if (dqp->q_pincount == 0) {
124                 sv_broadcast(&dqp->q_pinwait);
125         }
126         spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
127 }
128
129 /* ARGSUSED */
130 STATIC void
131 xfs_qm_dquot_logitem_unpin_remove(
132         xfs_dq_logitem_t *logitem,
133         xfs_trans_t      *tp)
134 {
135         xfs_qm_dquot_logitem_unpin(logitem, 0);
136 }
137
138 /*
139  * Given the logitem, this writes the corresponding dquot entry to disk
140  * asynchronously. This is called with the dquot entry securely locked;
141  * we simply get xfs_qm_dqflush() to do the work, and unlock the dquot
142  * at the end.
143  */
144 STATIC void
145 xfs_qm_dquot_logitem_push(
146         xfs_dq_logitem_t        *logitem)
147 {
148         xfs_dquot_t     *dqp;
149         int             error;
150
151         dqp = logitem->qli_dquot;
152
153         ASSERT(XFS_DQ_IS_LOCKED(dqp));
154         ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp));
155
156         /*
157          * Since we were able to lock the dquot's flush lock and
158          * we found it on the AIL, the dquot must be dirty.  This
159          * is because the dquot is removed from the AIL while still
160          * holding the flush lock in xfs_dqflush_done().  Thus, if
161          * we found it in the AIL and were able to obtain the flush
162          * lock without sleeping, then there must not have been
163          * anyone in the process of flushing the dquot.
164          */
165         error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI);
166         if (error)
167                 xfs_fs_cmn_err(CE_WARN, dqp->q_mount,
168                         "xfs_qm_dquot_logitem_push: push error %d on dqp %p",
169                         error, dqp);
170         xfs_dqunlock(dqp);
171 }
172
173 /*ARGSUSED*/
174 STATIC xfs_lsn_t
175 xfs_qm_dquot_logitem_committed(
176         xfs_dq_logitem_t        *l,
177         xfs_lsn_t               lsn)
178 {
179         /*
180          * We always re-log the entire dquot when it becomes dirty,
181          * so, the latest copy _is_ the only one that matters.
182          */
183         return (lsn);
184 }
185
186
187 /*
188  * This is called to wait for the given dquot to be unpinned.
189  * Most of these pin/unpin routines are plagiarized from inode code.
190  */
191 void
192 xfs_qm_dqunpin_wait(
193         xfs_dquot_t     *dqp)
194 {
195         ASSERT(XFS_DQ_IS_LOCKED(dqp));
196         if (dqp->q_pincount == 0) {
197                 return;
198         }
199
200         /*
201          * Give the log a push so we don't wait here too long.
202          */
203         xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE);
204         spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
205         if (dqp->q_pincount == 0) {
206                 spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
207                 return;
208         }
209         sv_wait(&(dqp->q_pinwait), PINOD,
210                 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s);
211 }
212
213 /*
214  * This is called when IOP_TRYLOCK returns XFS_ITEM_PUSHBUF to indicate that
215  * the dquot is locked by us, but the flush lock isn't. So, here we are
216  * going to see if the relevant dquot buffer is incore, waiting on DELWRI.
217  * If so, we want to push it out to help us take this item off the AIL as soon
218  * as possible.
219  *
220  * We must not be holding the AIL lock at this point. Calling incore() to
221  * search the buffer cache can be a time consuming thing, and AIL lock is a
222  * spinlock.
223  */
224 STATIC void
225 xfs_qm_dquot_logitem_pushbuf(
226         xfs_dq_logitem_t    *qip)
227 {
228         xfs_dquot_t     *dqp;
229         xfs_mount_t     *mp;
230         xfs_buf_t       *bp;
231         uint            dopush;
232
233         dqp = qip->qli_dquot;
234         ASSERT(XFS_DQ_IS_LOCKED(dqp));
235
236         /*
237          * The qli_pushbuf_flag keeps others from
238          * trying to duplicate our effort.
239          */
240         ASSERT(qip->qli_pushbuf_flag != 0);
241         ASSERT(qip->qli_push_owner == current_pid());
242
243         /*
244          * If flushlock isn't locked anymore, chances are that the
245          * inode flush completed and the inode was taken off the AIL.
246          * So, just get out.
247          */
248         if (!issemalocked(&(dqp->q_flock))  ||
249             ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
250                 qip->qli_pushbuf_flag = 0;
251                 xfs_dqunlock(dqp);
252                 return;
253         }
254         mp = dqp->q_mount;
255         bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno,
256                     XFS_QI_DQCHUNKLEN(mp),
257                     XFS_INCORE_TRYLOCK);
258         if (bp != NULL) {
259                 if (XFS_BUF_ISDELAYWRITE(bp)) {
260                         dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
261                                   issemalocked(&(dqp->q_flock)));
262                         qip->qli_pushbuf_flag = 0;
263                         xfs_dqunlock(dqp);
264
265                         if (XFS_BUF_ISPINNED(bp)) {
266                                 xfs_log_force(mp, (xfs_lsn_t)0,
267                                               XFS_LOG_FORCE);
268                         }
269                         if (dopush) {
270                                 int     error;
271 #ifdef XFSRACEDEBUG
272                                 delay_for_intr();
273                                 delay(300);
274 #endif
275                                 error = xfs_bawrite(mp, bp);
276                                 if (error)
277                                         xfs_fs_cmn_err(CE_WARN, mp,
278         "xfs_qm_dquot_logitem_pushbuf: pushbuf error %d on qip %p, bp %p",
279                                                         error, qip, bp);
280                         } else {
281                                 xfs_buf_relse(bp);
282                         }
283                 } else {
284                         qip->qli_pushbuf_flag = 0;
285                         xfs_dqunlock(dqp);
286                         xfs_buf_relse(bp);
287                 }
288                 return;
289         }
290
291         qip->qli_pushbuf_flag = 0;
292         xfs_dqunlock(dqp);
293 }
294
295 /*
296  * This is called to attempt to lock the dquot associated with this
297  * dquot log item.  Don't sleep on the dquot lock or the flush lock.
298  * If the flush lock is already held, indicating that the dquot has
299  * been or is in the process of being flushed, then see if we can
300  * find the dquot's buffer in the buffer cache without sleeping.  If
301  * we can and it is marked delayed write, then we want to send it out.
302  * We delay doing so until the push routine, though, to avoid sleeping
303  * in any device strategy routines.
304  */
305 STATIC uint
306 xfs_qm_dquot_logitem_trylock(
307         xfs_dq_logitem_t        *qip)
308 {
309         xfs_dquot_t             *dqp;
310         uint                    retval;
311
312         dqp = qip->qli_dquot;
313         if (dqp->q_pincount > 0)
314                 return (XFS_ITEM_PINNED);
315
316         if (! xfs_qm_dqlock_nowait(dqp))
317                 return (XFS_ITEM_LOCKED);
318
319         retval = XFS_ITEM_SUCCESS;
320         if (! xfs_qm_dqflock_nowait(dqp)) {
321                 /*
322                  * The dquot is already being flushed.  It may have been
323                  * flushed delayed write, however, and we don't want to
324                  * get stuck waiting for that to complete.  So, we want to check
325                  * to see if we can lock the dquot's buffer without sleeping.
326                  * If we can and it is marked for delayed write, then we
327                  * hold it and send it out from the push routine.  We don't
328                  * want to do that now since we might sleep in the device
329                  * strategy routine.  We also don't want to grab the buffer lock
330                  * here because we'd like not to call into the buffer cache
331                  * while holding the AIL lock.
332                  * Make sure to only return PUSHBUF if we set pushbuf_flag
333                  * ourselves.  If someone else is doing it then we don't
334                  * want to go to the push routine and duplicate their efforts.
335                  */
336                 if (qip->qli_pushbuf_flag == 0) {
337                         qip->qli_pushbuf_flag = 1;
338                         ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno);
339 #ifdef DEBUG
340                         qip->qli_push_owner = current_pid();
341 #endif
342                         /*
343                          * The dquot is left locked.
344                          */
345                         retval = XFS_ITEM_PUSHBUF;
346                 } else {
347                         retval = XFS_ITEM_FLUSHING;
348                         xfs_dqunlock_nonotify(dqp);
349                 }
350         }
351
352         ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL);
353         return (retval);
354 }
355
356
357 /*
358  * Unlock the dquot associated with the log item.
359  * Clear the fields of the dquot and dquot log item that
360  * are specific to the current transaction.  If the
361  * hold flags is set, do not unlock the dquot.
362  */
363 STATIC void
364 xfs_qm_dquot_logitem_unlock(
365         xfs_dq_logitem_t    *ql)
366 {
367         xfs_dquot_t     *dqp;
368
369         ASSERT(ql != NULL);
370         dqp = ql->qli_dquot;
371         ASSERT(XFS_DQ_IS_LOCKED(dqp));
372
373         /*
374          * Clear the transaction pointer in the dquot
375          */
376         dqp->q_transp = NULL;
377
378         /*
379          * dquots are never 'held' from getting unlocked at the end of
380          * a transaction.  Their locking and unlocking is hidden inside the
381          * transaction layer, within trans_commit. Hence, no LI_HOLD flag
382          * for the logitem.
383          */
384         xfs_dqunlock(dqp);
385 }
386
387
388 /*
389  * this needs to stamp an lsn into the dquot, I think.
390  * rpc's that look at user dquot's would then have to
391  * push on the dependency recorded in the dquot
392  */
393 /* ARGSUSED */
394 STATIC void
395 xfs_qm_dquot_logitem_committing(
396         xfs_dq_logitem_t        *l,
397         xfs_lsn_t               lsn)
398 {
399         return;
400 }
401
402
403 /*
404  * This is the ops vector for dquots
405  */
406 static struct xfs_item_ops xfs_dquot_item_ops = {
407         .iop_size       = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
408         .iop_format     = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
409                                         xfs_qm_dquot_logitem_format,
410         .iop_pin        = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin,
411         .iop_unpin      = (void(*)(xfs_log_item_t*, int))
412                                         xfs_qm_dquot_logitem_unpin,
413         .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
414                                         xfs_qm_dquot_logitem_unpin_remove,
415         .iop_trylock    = (uint(*)(xfs_log_item_t*))
416                                         xfs_qm_dquot_logitem_trylock,
417         .iop_unlock     = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unlock,
418         .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
419                                         xfs_qm_dquot_logitem_committed,
420         .iop_push       = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push,
421         .iop_pushbuf    = (void(*)(xfs_log_item_t*))
422                                         xfs_qm_dquot_logitem_pushbuf,
423         .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
424                                         xfs_qm_dquot_logitem_committing
425 };
426
427 /*
428  * Initialize the dquot log item for a newly allocated dquot.
429  * The dquot isn't locked at this point, but it isn't on any of the lists
430  * either, so we don't care.
431  */
432 void
433 xfs_qm_dquot_logitem_init(
434         struct xfs_dquot *dqp)
435 {
436         xfs_dq_logitem_t  *lp;
437         lp = &dqp->q_logitem;
438
439         lp->qli_item.li_type = XFS_LI_DQUOT;
440         lp->qli_item.li_ops = &xfs_dquot_item_ops;
441         lp->qli_item.li_mountp = dqp->q_mount;
442         lp->qli_dquot = dqp;
443         lp->qli_format.qlf_type = XFS_LI_DQUOT;
444         lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id);
445         lp->qli_format.qlf_blkno = dqp->q_blkno;
446         lp->qli_format.qlf_len = 1;
447         /*
448          * This is just the offset of this dquot within its buffer
449          * (which is currently 1 FSB and probably won't change).
450          * Hence 32 bits for this offset should be just fine.
451          * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t))
452          * here, and recompute it at recovery time.
453          */
454         lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset;
455 }
456
457 /*------------------  QUOTAOFF LOG ITEMS  -------------------*/
458
459 /*
460  * This returns the number of iovecs needed to log the given quotaoff item.
461  * We only need 1 iovec for an quotaoff item.  It just logs the
462  * quotaoff_log_format structure.
463  */
464 /*ARGSUSED*/
465 STATIC uint
466 xfs_qm_qoff_logitem_size(xfs_qoff_logitem_t *qf)
467 {
468         return (1);
469 }
470
471 /*
472  * This is called to fill in the vector of log iovecs for the
473  * given quotaoff log item. We use only 1 iovec, and we point that
474  * at the quotaoff_log_format structure embedded in the quotaoff item.
475  * It is at this point that we assert that all of the extent
476  * slots in the quotaoff item have been filled.
477  */
478 STATIC void
479 xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t   *qf,
480                            xfs_log_iovec_t      *log_vector)
481 {
482         ASSERT(qf->qql_format.qf_type == XFS_LI_QUOTAOFF);
483
484         log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format);
485         log_vector->i_len = sizeof(xfs_qoff_logitem_t);
486         XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_QUOTAOFF);
487         qf->qql_format.qf_size = 1;
488 }
489
490
491 /*
492  * Pinning has no meaning for an quotaoff item, so just return.
493  */
494 /*ARGSUSED*/
495 STATIC void
496 xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t *qf)
497 {
498         return;
499 }
500
501
502 /*
503  * Since pinning has no meaning for an quotaoff item, unpinning does
504  * not either.
505  */
506 /*ARGSUSED*/
507 STATIC void
508 xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale)
509 {
510         return;
511 }
512
513 /*ARGSUSED*/
514 STATIC void
515 xfs_qm_qoff_logitem_unpin_remove(xfs_qoff_logitem_t *qf, xfs_trans_t *tp)
516 {
517         return;
518 }
519
520 /*
521  * Quotaoff items have no locking, so just return success.
522  */
523 /*ARGSUSED*/
524 STATIC uint
525 xfs_qm_qoff_logitem_trylock(xfs_qoff_logitem_t *qf)
526 {
527         return XFS_ITEM_LOCKED;
528 }
529
530 /*
531  * Quotaoff items have no locking or pushing, so return failure
532  * so that the caller doesn't bother with us.
533  */
534 /*ARGSUSED*/
535 STATIC void
536 xfs_qm_qoff_logitem_unlock(xfs_qoff_logitem_t *qf)
537 {
538         return;
539 }
540
541 /*
542  * The quotaoff-start-item is logged only once and cannot be moved in the log,
543  * so simply return the lsn at which it's been logged.
544  */
545 /*ARGSUSED*/
546 STATIC xfs_lsn_t
547 xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn)
548 {
549         return (lsn);
550 }
551
552 /*
553  * There isn't much you can do to push on an quotaoff item.  It is simply
554  * stuck waiting for the log to be flushed to disk.
555  */
556 /*ARGSUSED*/
557 STATIC void
558 xfs_qm_qoff_logitem_push(xfs_qoff_logitem_t *qf)
559 {
560         return;
561 }
562
563
564 /*ARGSUSED*/
565 STATIC xfs_lsn_t
566 xfs_qm_qoffend_logitem_committed(
567         xfs_qoff_logitem_t *qfe,
568         xfs_lsn_t lsn)
569 {
570         xfs_qoff_logitem_t      *qfs;
571
572         qfs = qfe->qql_start_lip;
573         spin_lock(&qfs->qql_item.li_mountp->m_ail_lock);
574         /*
575          * Delete the qoff-start logitem from the AIL.
576          * xfs_trans_delete_ail() drops the AIL lock.
577          */
578         xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs);
579         kmem_free(qfs, sizeof(xfs_qoff_logitem_t));
580         kmem_free(qfe, sizeof(xfs_qoff_logitem_t));
581         return (xfs_lsn_t)-1;
582 }
583
584 /*
585  * XXX rcc - don't know quite what to do with this.  I think we can
586  * just ignore it.  The only time that isn't the case is if we allow
587  * the client to somehow see that quotas have been turned off in which
588  * we can't allow that to get back until the quotaoff hits the disk.
589  * So how would that happen?  Also, do we need different routines for
590  * quotaoff start and quotaoff end?  I suspect the answer is yes but
591  * to be sure, I need to look at the recovery code and see how quota off
592  * recovery is handled (do we roll forward or back or do something else).
593  * If we roll forwards or backwards, then we need two separate routines,
594  * one that does nothing and one that stamps in the lsn that matters
595  * (truly makes the quotaoff irrevocable).  If we do something else,
596  * then maybe we don't need two.
597  */
598 /* ARGSUSED */
599 STATIC void
600 xfs_qm_qoff_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
601 {
602         return;
603 }
604
605 /* ARGSUSED */
606 STATIC void
607 xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
608 {
609         return;
610 }
611
612 static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
613         .iop_size       = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
614         .iop_format     = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
615                                         xfs_qm_qoff_logitem_format,
616         .iop_pin        = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
617         .iop_unpin      = (void(*)(xfs_log_item_t* ,int))
618                                         xfs_qm_qoff_logitem_unpin,
619         .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
620                                         xfs_qm_qoff_logitem_unpin_remove,
621         .iop_trylock    = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
622         .iop_unlock     = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
623         .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
624                                         xfs_qm_qoffend_logitem_committed,
625         .iop_push       = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
626         .iop_pushbuf    = NULL,
627         .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
628                                         xfs_qm_qoffend_logitem_committing
629 };
630
631 /*
632  * This is the ops vector shared by all quotaoff-start log items.
633  */
634 static struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
635         .iop_size       = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
636         .iop_format     = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
637                                         xfs_qm_qoff_logitem_format,
638         .iop_pin        = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
639         .iop_unpin      = (void(*)(xfs_log_item_t*, int))
640                                         xfs_qm_qoff_logitem_unpin,
641         .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
642                                         xfs_qm_qoff_logitem_unpin_remove,
643         .iop_trylock    = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
644         .iop_unlock     = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
645         .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
646                                         xfs_qm_qoff_logitem_committed,
647         .iop_push       = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
648         .iop_pushbuf    = NULL,
649         .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
650                                         xfs_qm_qoff_logitem_committing
651 };
652
653 /*
654  * Allocate and initialize an quotaoff item of the correct quota type(s).
655  */
656 xfs_qoff_logitem_t *
657 xfs_qm_qoff_logitem_init(
658         struct xfs_mount *mp,
659         xfs_qoff_logitem_t *start,
660         uint flags)
661 {
662         xfs_qoff_logitem_t      *qf;
663
664         qf = (xfs_qoff_logitem_t*) kmem_zalloc(sizeof(xfs_qoff_logitem_t), KM_SLEEP);
665
666         qf->qql_item.li_type = XFS_LI_QUOTAOFF;
667         if (start)
668                 qf->qql_item.li_ops = &xfs_qm_qoffend_logitem_ops;
669         else
670                 qf->qql_item.li_ops = &xfs_qm_qoff_logitem_ops;
671         qf->qql_item.li_mountp = mp;
672         qf->qql_format.qf_type = XFS_LI_QUOTAOFF;
673         qf->qql_format.qf_flags = flags;
674         qf->qql_start_lip = start;
675         return (qf);
676 }