10b61f8a4SDave Chinner // SPDX-License-Identifier: GPL-2.0 2c59d87c4SChristoph Hellwig /* 3c59d87c4SChristoph Hellwig * Copyright (c) 2000-2003 Silicon Graphics, Inc. 4c59d87c4SChristoph Hellwig * All Rights Reserved. 5c59d87c4SChristoph Hellwig */ 6c59d87c4SChristoph Hellwig #include "xfs.h" 7c59d87c4SChristoph Hellwig #include "xfs_fs.h" 85467b34bSDarrick J. Wong #include "xfs_shared.h" 96ca1c906SDave Chinner #include "xfs_format.h" 10239880efSDave Chinner #include "xfs_log_format.h" 11239880efSDave Chinner #include "xfs_trans_resv.h" 12c59d87c4SChristoph Hellwig #include "xfs_mount.h" 13c59d87c4SChristoph Hellwig #include "xfs_inode.h" 14a4fbe6abSDave Chinner #include "xfs_quota.h" 15239880efSDave Chinner #include "xfs_trans.h" 16c59d87c4SChristoph Hellwig #include "xfs_buf_item.h" 17c59d87c4SChristoph Hellwig #include "xfs_trans_priv.h" 18c59d87c4SChristoph Hellwig #include "xfs_qm.h" 19239880efSDave Chinner #include "xfs_log.h" 20c59d87c4SChristoph Hellwig 21c59d87c4SChristoph Hellwig static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip) 22c59d87c4SChristoph Hellwig { 23c59d87c4SChristoph Hellwig return container_of(lip, struct xfs_dq_logitem, qli_item); 24c59d87c4SChristoph Hellwig } 25c59d87c4SChristoph Hellwig 26c59d87c4SChristoph Hellwig /* 27c59d87c4SChristoph Hellwig * returns the number of iovecs needed to log the given dquot item. 28c59d87c4SChristoph Hellwig */ 29166d1368SDave Chinner STATIC void 30c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_size( 31166d1368SDave Chinner struct xfs_log_item *lip, 32166d1368SDave Chinner int *nvecs, 33166d1368SDave Chinner int *nbytes) 34c59d87c4SChristoph Hellwig { 35166d1368SDave Chinner *nvecs += 2; 36166d1368SDave Chinner *nbytes += sizeof(struct xfs_dq_logformat) + 37166d1368SDave Chinner sizeof(struct xfs_disk_dquot); 38c59d87c4SChristoph Hellwig } 39c59d87c4SChristoph Hellwig 40c59d87c4SChristoph Hellwig /* 41c59d87c4SChristoph Hellwig * fills in the vector of log iovecs for the given dquot log item. 42c59d87c4SChristoph Hellwig */ 43c59d87c4SChristoph Hellwig STATIC void 44c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_format( 45c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 46bde7cff6SChristoph Hellwig struct xfs_log_vec *lv) 47c59d87c4SChristoph Hellwig { 48*0b0fa1d1SDarrick J. Wong struct xfs_disk_dquot ddq; 49c59d87c4SChristoph Hellwig struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); 50bde7cff6SChristoph Hellwig struct xfs_log_iovec *vecp = NULL; 51ce8e9629SChristoph Hellwig struct xfs_dq_logformat *qlf; 52c59d87c4SChristoph Hellwig 53ce8e9629SChristoph Hellwig qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT); 54ce8e9629SChristoph Hellwig qlf->qlf_type = XFS_LI_DQUOT; 55ce8e9629SChristoph Hellwig qlf->qlf_size = 2; 56ce8e9629SChristoph Hellwig qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id); 57ce8e9629SChristoph Hellwig qlf->qlf_blkno = qlip->qli_dquot->q_blkno; 58ce8e9629SChristoph Hellwig qlf->qlf_len = 1; 59ce8e9629SChristoph Hellwig qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; 60ce8e9629SChristoph Hellwig xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat)); 61bde7cff6SChristoph Hellwig 62*0b0fa1d1SDarrick J. Wong xfs_dquot_to_disk(&ddq, qlip->qli_dquot); 63*0b0fa1d1SDarrick J. Wong 64*0b0fa1d1SDarrick J. Wong xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq, 65bde7cff6SChristoph Hellwig sizeof(struct xfs_disk_dquot)); 66c59d87c4SChristoph Hellwig } 67c59d87c4SChristoph Hellwig 68c59d87c4SChristoph Hellwig /* 69c59d87c4SChristoph Hellwig * Increment the pin count of the given dquot. 70c59d87c4SChristoph Hellwig */ 71c59d87c4SChristoph Hellwig STATIC void 72c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_pin( 73c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 74c59d87c4SChristoph Hellwig { 75c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 76c59d87c4SChristoph Hellwig 77c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 78c59d87c4SChristoph Hellwig atomic_inc(&dqp->q_pincount); 79c59d87c4SChristoph Hellwig } 80c59d87c4SChristoph Hellwig 81c59d87c4SChristoph Hellwig /* 82c59d87c4SChristoph Hellwig * Decrement the pin count of the given dquot, and wake up 83c59d87c4SChristoph Hellwig * anyone in xfs_dqwait_unpin() if the count goes to 0. The 84c59d87c4SChristoph Hellwig * dquot must have been previously pinned with a call to 85c59d87c4SChristoph Hellwig * xfs_qm_dquot_logitem_pin(). 86c59d87c4SChristoph Hellwig */ 87c59d87c4SChristoph Hellwig STATIC void 88c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_unpin( 89c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 90c59d87c4SChristoph Hellwig int remove) 91c59d87c4SChristoph Hellwig { 92c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 93c59d87c4SChristoph Hellwig 94c59d87c4SChristoph Hellwig ASSERT(atomic_read(&dqp->q_pincount) > 0); 95c59d87c4SChristoph Hellwig if (atomic_dec_and_test(&dqp->q_pincount)) 96c59d87c4SChristoph Hellwig wake_up(&dqp->q_pinwait); 97c59d87c4SChristoph Hellwig } 98c59d87c4SChristoph Hellwig 99c59d87c4SChristoph Hellwig /* 100c59d87c4SChristoph Hellwig * This is called to wait for the given dquot to be unpinned. 101c59d87c4SChristoph Hellwig * Most of these pin/unpin routines are plagiarized from inode code. 102c59d87c4SChristoph Hellwig */ 103c59d87c4SChristoph Hellwig void 104c59d87c4SChristoph Hellwig xfs_qm_dqunpin_wait( 105c59d87c4SChristoph Hellwig struct xfs_dquot *dqp) 106c59d87c4SChristoph Hellwig { 107c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 108c59d87c4SChristoph Hellwig if (atomic_read(&dqp->q_pincount) == 0) 109c59d87c4SChristoph Hellwig return; 110c59d87c4SChristoph Hellwig 111c59d87c4SChristoph Hellwig /* 112c59d87c4SChristoph Hellwig * Give the log a push so we don't wait here too long. 113c59d87c4SChristoph Hellwig */ 114c59d87c4SChristoph Hellwig xfs_log_force(dqp->q_mount, 0); 115c59d87c4SChristoph Hellwig wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); 116c59d87c4SChristoph Hellwig } 117c59d87c4SChristoph Hellwig 118c59d87c4SChristoph Hellwig STATIC uint 11943ff2122SChristoph Hellwig xfs_qm_dquot_logitem_push( 12043ff2122SChristoph Hellwig struct xfs_log_item *lip, 12157e80956SMatthew Wilcox struct list_head *buffer_list) 12257e80956SMatthew Wilcox __releases(&lip->li_ailp->ail_lock) 12357e80956SMatthew Wilcox __acquires(&lip->li_ailp->ail_lock) 124c59d87c4SChristoph Hellwig { 125c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 126373b0589SCarlos Maiolino struct xfs_buf *bp = lip->li_buf; 12743ff2122SChristoph Hellwig uint rval = XFS_ITEM_SUCCESS; 12843ff2122SChristoph Hellwig int error; 129c59d87c4SChristoph Hellwig 130c59d87c4SChristoph Hellwig if (atomic_read(&dqp->q_pincount) > 0) 131c59d87c4SChristoph Hellwig return XFS_ITEM_PINNED; 132c59d87c4SChristoph Hellwig 133800b484eSChristoph Hellwig if (!xfs_dqlock_nowait(dqp)) 134c59d87c4SChristoph Hellwig return XFS_ITEM_LOCKED; 135c59d87c4SChristoph Hellwig 136fe7257fdSChristoph Hellwig /* 137fe7257fdSChristoph Hellwig * Re-check the pincount now that we stabilized the value by 138fe7257fdSChristoph Hellwig * taking the quota lock. 139fe7257fdSChristoph Hellwig */ 140fe7257fdSChristoph Hellwig if (atomic_read(&dqp->q_pincount) > 0) { 14143ff2122SChristoph Hellwig rval = XFS_ITEM_PINNED; 14243ff2122SChristoph Hellwig goto out_unlock; 143fe7257fdSChristoph Hellwig } 144fe7257fdSChristoph Hellwig 145c59d87c4SChristoph Hellwig /* 14643ff2122SChristoph Hellwig * Someone else is already flushing the dquot. Nothing we can do 14743ff2122SChristoph Hellwig * here but wait for the flush to finish and remove the item from 14843ff2122SChristoph Hellwig * the AIL. 149c59d87c4SChristoph Hellwig */ 15043ff2122SChristoph Hellwig if (!xfs_dqflock_nowait(dqp)) { 15143ff2122SChristoph Hellwig rval = XFS_ITEM_FLUSHING; 15243ff2122SChristoph Hellwig goto out_unlock; 153c59d87c4SChristoph Hellwig } 154c59d87c4SChristoph Hellwig 15557e80956SMatthew Wilcox spin_unlock(&lip->li_ailp->ail_lock); 15643ff2122SChristoph Hellwig 15743ff2122SChristoph Hellwig error = xfs_qm_dqflush(dqp, &bp); 158609001bcSDarrick J. Wong if (!error) { 15943ff2122SChristoph Hellwig if (!xfs_buf_delwri_queue(bp, buffer_list)) 16043ff2122SChristoph Hellwig rval = XFS_ITEM_FLUSHING; 16143ff2122SChristoph Hellwig xfs_buf_relse(bp); 1628d3d7e2bSBrian Foster } else if (error == -EAGAIN) 1638d3d7e2bSBrian Foster rval = XFS_ITEM_LOCKED; 16443ff2122SChristoph Hellwig 16557e80956SMatthew Wilcox spin_lock(&lip->li_ailp->ail_lock); 16643ff2122SChristoph Hellwig out_unlock: 16743ff2122SChristoph Hellwig xfs_dqunlock(dqp); 16843ff2122SChristoph Hellwig return rval; 169c59d87c4SChristoph Hellwig } 170c59d87c4SChristoph Hellwig 171c59d87c4SChristoph Hellwig STATIC void 172ddf92053SChristoph Hellwig xfs_qm_dquot_logitem_release( 173c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 174c59d87c4SChristoph Hellwig { 175c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 176c59d87c4SChristoph Hellwig 177c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 178c59d87c4SChristoph Hellwig 179c59d87c4SChristoph Hellwig /* 180c59d87c4SChristoph Hellwig * dquots are never 'held' from getting unlocked at the end of 181c59d87c4SChristoph Hellwig * a transaction. Their locking and unlocking is hidden inside the 182c59d87c4SChristoph Hellwig * transaction layer, within trans_commit. Hence, no LI_HOLD flag 183c59d87c4SChristoph Hellwig * for the logitem. 184c59d87c4SChristoph Hellwig */ 185c59d87c4SChristoph Hellwig xfs_dqunlock(dqp); 186c59d87c4SChristoph Hellwig } 187c59d87c4SChristoph Hellwig 188ddf92053SChristoph Hellwig STATIC void 189ddf92053SChristoph Hellwig xfs_qm_dquot_logitem_committing( 190ddf92053SChristoph Hellwig struct xfs_log_item *lip, 191ddf92053SChristoph Hellwig xfs_lsn_t commit_lsn) 192ddf92053SChristoph Hellwig { 193ddf92053SChristoph Hellwig return xfs_qm_dquot_logitem_release(lip); 194ddf92053SChristoph Hellwig } 195ddf92053SChristoph Hellwig 196272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_dquot_item_ops = { 197c59d87c4SChristoph Hellwig .iop_size = xfs_qm_dquot_logitem_size, 198c59d87c4SChristoph Hellwig .iop_format = xfs_qm_dquot_logitem_format, 199c59d87c4SChristoph Hellwig .iop_pin = xfs_qm_dquot_logitem_pin, 200c59d87c4SChristoph Hellwig .iop_unpin = xfs_qm_dquot_logitem_unpin, 201ddf92053SChristoph Hellwig .iop_release = xfs_qm_dquot_logitem_release, 202ddf92053SChristoph Hellwig .iop_committing = xfs_qm_dquot_logitem_committing, 203c59d87c4SChristoph Hellwig .iop_push = xfs_qm_dquot_logitem_push, 204c59d87c4SChristoph Hellwig }; 205c59d87c4SChristoph Hellwig 206c59d87c4SChristoph Hellwig /* 207c59d87c4SChristoph Hellwig * Initialize the dquot log item for a newly allocated dquot. 208c59d87c4SChristoph Hellwig * The dquot isn't locked at this point, but it isn't on any of the lists 209c59d87c4SChristoph Hellwig * either, so we don't care. 210c59d87c4SChristoph Hellwig */ 211c59d87c4SChristoph Hellwig void 212c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_init( 213c59d87c4SChristoph Hellwig struct xfs_dquot *dqp) 214c59d87c4SChristoph Hellwig { 215c59d87c4SChristoph Hellwig struct xfs_dq_logitem *lp = &dqp->q_logitem; 216c59d87c4SChristoph Hellwig 217c59d87c4SChristoph Hellwig xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT, 218c59d87c4SChristoph Hellwig &xfs_dquot_item_ops); 219c59d87c4SChristoph Hellwig lp->qli_dquot = dqp; 220c59d87c4SChristoph Hellwig } 221c59d87c4SChristoph Hellwig 222c59d87c4SChristoph Hellwig /*------------------ QUOTAOFF LOG ITEMS -------------------*/ 223c59d87c4SChristoph Hellwig 224c59d87c4SChristoph Hellwig static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip) 225c59d87c4SChristoph Hellwig { 226c59d87c4SChristoph Hellwig return container_of(lip, struct xfs_qoff_logitem, qql_item); 227c59d87c4SChristoph Hellwig } 228c59d87c4SChristoph Hellwig 229c59d87c4SChristoph Hellwig 230c59d87c4SChristoph Hellwig /* 231c59d87c4SChristoph Hellwig * This returns the number of iovecs needed to log the given quotaoff item. 232c59d87c4SChristoph Hellwig * We only need 1 iovec for an quotaoff item. It just logs the 233c59d87c4SChristoph Hellwig * quotaoff_log_format structure. 234c59d87c4SChristoph Hellwig */ 235166d1368SDave Chinner STATIC void 236c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_size( 237166d1368SDave Chinner struct xfs_log_item *lip, 238166d1368SDave Chinner int *nvecs, 239166d1368SDave Chinner int *nbytes) 240c59d87c4SChristoph Hellwig { 241166d1368SDave Chinner *nvecs += 1; 242166d1368SDave Chinner *nbytes += sizeof(struct xfs_qoff_logitem); 243c59d87c4SChristoph Hellwig } 244c59d87c4SChristoph Hellwig 245c59d87c4SChristoph Hellwig STATIC void 246c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_format( 247c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 248bde7cff6SChristoph Hellwig struct xfs_log_vec *lv) 249c59d87c4SChristoph Hellwig { 250c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); 251bde7cff6SChristoph Hellwig struct xfs_log_iovec *vecp = NULL; 252ffda4e83SChristoph Hellwig struct xfs_qoff_logformat *qlf; 253c59d87c4SChristoph Hellwig 254ffda4e83SChristoph Hellwig qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF); 255ffda4e83SChristoph Hellwig qlf->qf_type = XFS_LI_QUOTAOFF; 256ffda4e83SChristoph Hellwig qlf->qf_size = 1; 257ffda4e83SChristoph Hellwig qlf->qf_flags = qflip->qql_flags; 258ffda4e83SChristoph Hellwig xlog_finish_iovec(lv, vecp, sizeof(struct xfs_qoff_logitem)); 259c59d87c4SChristoph Hellwig } 260c59d87c4SChristoph Hellwig 261c59d87c4SChristoph Hellwig /* 26243ff2122SChristoph Hellwig * There isn't much you can do to push a quotaoff item. It is simply 26343ff2122SChristoph Hellwig * stuck waiting for the log to be flushed to disk. 264c59d87c4SChristoph Hellwig */ 265c59d87c4SChristoph Hellwig STATIC uint 26643ff2122SChristoph Hellwig xfs_qm_qoff_logitem_push( 26743ff2122SChristoph Hellwig struct xfs_log_item *lip, 26843ff2122SChristoph Hellwig struct list_head *buffer_list) 269c59d87c4SChristoph Hellwig { 270c59d87c4SChristoph Hellwig return XFS_ITEM_LOCKED; 271c59d87c4SChristoph Hellwig } 272c59d87c4SChristoph Hellwig 273c59d87c4SChristoph Hellwig STATIC xfs_lsn_t 274c59d87c4SChristoph Hellwig xfs_qm_qoffend_logitem_committed( 275c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 276c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 277c59d87c4SChristoph Hellwig { 278c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip); 279c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qfs = qfe->qql_start_lip; 280c59d87c4SChristoph Hellwig 281854f82b1SBrian Foster xfs_qm_qoff_logitem_relse(qfs); 282c59d87c4SChristoph Hellwig 283b1c5ebb2SDave Chinner kmem_free(lip->li_lv_shadow); 284c59d87c4SChristoph Hellwig kmem_free(qfe); 285c59d87c4SChristoph Hellwig return (xfs_lsn_t)-1; 286c59d87c4SChristoph Hellwig } 287c59d87c4SChristoph Hellwig 2888a627143SBrian Foster STATIC void 2898a627143SBrian Foster xfs_qm_qoff_logitem_release( 2908a627143SBrian Foster struct xfs_log_item *lip) 2918a627143SBrian Foster { 2928a627143SBrian Foster struct xfs_qoff_logitem *qoff = QOFF_ITEM(lip); 2938a627143SBrian Foster 2948a627143SBrian Foster if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) { 2958a627143SBrian Foster if (qoff->qql_start_lip) 2968a627143SBrian Foster xfs_qm_qoff_logitem_relse(qoff->qql_start_lip); 2978a627143SBrian Foster xfs_qm_qoff_logitem_relse(qoff); 2988a627143SBrian Foster } 2998a627143SBrian Foster } 3008a627143SBrian Foster 301272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { 302c59d87c4SChristoph Hellwig .iop_size = xfs_qm_qoff_logitem_size, 303c59d87c4SChristoph Hellwig .iop_format = xfs_qm_qoff_logitem_format, 304c59d87c4SChristoph Hellwig .iop_committed = xfs_qm_qoffend_logitem_committed, 305c59d87c4SChristoph Hellwig .iop_push = xfs_qm_qoff_logitem_push, 3068a627143SBrian Foster .iop_release = xfs_qm_qoff_logitem_release, 307c59d87c4SChristoph Hellwig }; 308c59d87c4SChristoph Hellwig 309272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = { 310c59d87c4SChristoph Hellwig .iop_size = xfs_qm_qoff_logitem_size, 311c59d87c4SChristoph Hellwig .iop_format = xfs_qm_qoff_logitem_format, 312c59d87c4SChristoph Hellwig .iop_push = xfs_qm_qoff_logitem_push, 3138a627143SBrian Foster .iop_release = xfs_qm_qoff_logitem_release, 314c59d87c4SChristoph Hellwig }; 315c59d87c4SChristoph Hellwig 316c59d87c4SChristoph Hellwig /* 317854f82b1SBrian Foster * Delete the quotaoff intent from the AIL and free it. On success, 318854f82b1SBrian Foster * this should only be called for the start item. It can be used for 319854f82b1SBrian Foster * either on shutdown or abort. 320854f82b1SBrian Foster */ 321854f82b1SBrian Foster void 322854f82b1SBrian Foster xfs_qm_qoff_logitem_relse( 323854f82b1SBrian Foster struct xfs_qoff_logitem *qoff) 324854f82b1SBrian Foster { 325854f82b1SBrian Foster struct xfs_log_item *lip = &qoff->qql_item; 326854f82b1SBrian Foster 327854f82b1SBrian Foster ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags) || 328854f82b1SBrian Foster test_bit(XFS_LI_ABORTED, &lip->li_flags) || 329854f82b1SBrian Foster XFS_FORCED_SHUTDOWN(lip->li_mountp)); 3302b3cf093SBrian Foster xfs_trans_ail_delete(lip, 0); 331854f82b1SBrian Foster kmem_free(lip->li_lv_shadow); 332854f82b1SBrian Foster kmem_free(qoff); 333854f82b1SBrian Foster } 334854f82b1SBrian Foster 335854f82b1SBrian Foster /* 336c59d87c4SChristoph Hellwig * Allocate and initialize an quotaoff item of the correct quota type(s). 337c59d87c4SChristoph Hellwig */ 338c59d87c4SChristoph Hellwig struct xfs_qoff_logitem * 339c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_init( 340c59d87c4SChristoph Hellwig struct xfs_mount *mp, 341c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *start, 342c59d87c4SChristoph Hellwig uint flags) 343c59d87c4SChristoph Hellwig { 344c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qf; 345c59d87c4SChristoph Hellwig 346707e0ddaSTetsuo Handa qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), 0); 347c59d87c4SChristoph Hellwig 348c59d87c4SChristoph Hellwig xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ? 349c59d87c4SChristoph Hellwig &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops); 350c59d87c4SChristoph Hellwig qf->qql_item.li_mountp = mp; 351c59d87c4SChristoph Hellwig qf->qql_start_lip = start; 352ffda4e83SChristoph Hellwig qf->qql_flags = flags; 353c59d87c4SChristoph Hellwig return qf; 354c59d87c4SChristoph Hellwig } 355