Showing error 1003

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: fs/xfs/quota/xfs_dquot_item.c
Line in file: 211
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-03-02 21:35:18 UTC


Source:

  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 */
 55STATIC uint
 56xfs_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 */
 68STATIC void
 69xfs_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 */
 93STATIC void
 94xfs_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 */
112STATIC void
113xfs_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 */
130STATIC void
131xfs_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 */
144STATIC void
145xfs_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(!completion_done(&dqp->q_flush));
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*/
174STATIC xfs_lsn_t
175xfs_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 */
191void
192xfs_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 */
224STATIC void
225xfs_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 (completion_done(&dqp->q_flush)  ||
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                                  !completion_done(&dqp->q_flush));
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 */
305STATIC uint
306xfs_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_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 */
363STATIC void
364xfs_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 */
394STATIC void
395xfs_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 */
406static 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 */
432void
433xfs_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*/
465STATIC uint
466xfs_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 */
478STATIC void
479xfs_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*/
495STATIC void
496xfs_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*/
507STATIC void
508xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale)
509{
510        return;
511}
512
513/*ARGSUSED*/
514STATIC void
515xfs_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*/
524STATIC uint
525xfs_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*/
535STATIC void
536xfs_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*/
546STATIC xfs_lsn_t
547xfs_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*/
557STATIC void
558xfs_qm_qoff_logitem_push(xfs_qoff_logitem_t *qf)
559{
560        return;
561}
562
563
564/*ARGSUSED*/
565STATIC xfs_lsn_t
566xfs_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);
580        kmem_free(qfe);
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 */
599STATIC void
600xfs_qm_qoff_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
601{
602        return;
603}
604
605/* ARGSUSED */
606STATIC void
607xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
608{
609        return;
610}
611
612static 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 */
634static 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 */
656xfs_qoff_logitem_t *
657xfs_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}