1c59d87c4SChristoph Hellwig /* 2c59d87c4SChristoph Hellwig * Copyright (c) 2000-2003 Silicon Graphics, Inc. 3c59d87c4SChristoph Hellwig * All Rights Reserved. 4c59d87c4SChristoph Hellwig * 5c59d87c4SChristoph Hellwig * This program is free software; you can redistribute it and/or 6c59d87c4SChristoph Hellwig * modify it under the terms of the GNU General Public License as 7c59d87c4SChristoph Hellwig * published by the Free Software Foundation. 8c59d87c4SChristoph Hellwig * 9c59d87c4SChristoph Hellwig * This program is distributed in the hope that it would be useful, 10c59d87c4SChristoph Hellwig * but WITHOUT ANY WARRANTY; without even the implied warranty of 11c59d87c4SChristoph Hellwig * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12c59d87c4SChristoph Hellwig * GNU General Public License for more details. 13c59d87c4SChristoph Hellwig * 14c59d87c4SChristoph Hellwig * You should have received a copy of the GNU General Public License 15c59d87c4SChristoph Hellwig * along with this program; if not, write the Free Software Foundation, 16c59d87c4SChristoph Hellwig * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17c59d87c4SChristoph Hellwig */ 18c59d87c4SChristoph Hellwig #include "xfs.h" 19c59d87c4SChristoph Hellwig #include "xfs_fs.h" 206ca1c906SDave Chinner #include "xfs_format.h" 21239880efSDave Chinner #include "xfs_log_format.h" 22239880efSDave Chinner #include "xfs_trans_resv.h" 23c59d87c4SChristoph Hellwig #include "xfs_sb.h" 24c59d87c4SChristoph Hellwig #include "xfs_ag.h" 25c59d87c4SChristoph Hellwig #include "xfs_mount.h" 26c59d87c4SChristoph Hellwig #include "xfs_inode.h" 27a4fbe6abSDave Chinner #include "xfs_quota.h" 28c59d87c4SChristoph Hellwig #include "xfs_error.h" 29239880efSDave Chinner #include "xfs_trans.h" 30c59d87c4SChristoph Hellwig #include "xfs_buf_item.h" 31c59d87c4SChristoph Hellwig #include "xfs_trans_priv.h" 32c59d87c4SChristoph Hellwig #include "xfs_qm.h" 33239880efSDave Chinner #include "xfs_log.h" 34c59d87c4SChristoph Hellwig 35c59d87c4SChristoph Hellwig static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip) 36c59d87c4SChristoph Hellwig { 37c59d87c4SChristoph Hellwig return container_of(lip, struct xfs_dq_logitem, qli_item); 38c59d87c4SChristoph Hellwig } 39c59d87c4SChristoph Hellwig 40c59d87c4SChristoph Hellwig /* 41c59d87c4SChristoph Hellwig * returns the number of iovecs needed to log the given dquot item. 42c59d87c4SChristoph Hellwig */ 43166d1368SDave Chinner STATIC void 44c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_size( 45166d1368SDave Chinner struct xfs_log_item *lip, 46166d1368SDave Chinner int *nvecs, 47166d1368SDave Chinner int *nbytes) 48c59d87c4SChristoph Hellwig { 49166d1368SDave Chinner *nvecs += 2; 50166d1368SDave Chinner *nbytes += sizeof(struct xfs_dq_logformat) + 51166d1368SDave Chinner sizeof(struct xfs_disk_dquot); 52c59d87c4SChristoph Hellwig } 53c59d87c4SChristoph Hellwig 54c59d87c4SChristoph Hellwig /* 55c59d87c4SChristoph Hellwig * fills in the vector of log iovecs for the given dquot log item. 56c59d87c4SChristoph Hellwig */ 57c59d87c4SChristoph Hellwig STATIC void 58c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_format( 59c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 60bde7cff6SChristoph Hellwig struct xfs_log_vec *lv) 61c59d87c4SChristoph Hellwig { 62c59d87c4SChristoph Hellwig struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); 63bde7cff6SChristoph Hellwig struct xfs_log_iovec *vecp = NULL; 64*ce8e9629SChristoph Hellwig struct xfs_dq_logformat *qlf; 65c59d87c4SChristoph Hellwig 66*ce8e9629SChristoph Hellwig qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT); 67*ce8e9629SChristoph Hellwig qlf->qlf_type = XFS_LI_DQUOT; 68*ce8e9629SChristoph Hellwig qlf->qlf_size = 2; 69*ce8e9629SChristoph Hellwig qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id); 70*ce8e9629SChristoph Hellwig qlf->qlf_blkno = qlip->qli_dquot->q_blkno; 71*ce8e9629SChristoph Hellwig qlf->qlf_len = 1; 72*ce8e9629SChristoph Hellwig qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; 73*ce8e9629SChristoph Hellwig xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat)); 74bde7cff6SChristoph Hellwig 75bde7cff6SChristoph Hellwig xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, 76bde7cff6SChristoph Hellwig &qlip->qli_dquot->q_core, 77bde7cff6SChristoph Hellwig sizeof(struct xfs_disk_dquot)); 78c59d87c4SChristoph Hellwig } 79c59d87c4SChristoph Hellwig 80c59d87c4SChristoph Hellwig /* 81c59d87c4SChristoph Hellwig * Increment the pin count of the given dquot. 82c59d87c4SChristoph Hellwig */ 83c59d87c4SChristoph Hellwig STATIC void 84c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_pin( 85c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 86c59d87c4SChristoph Hellwig { 87c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 88c59d87c4SChristoph Hellwig 89c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 90c59d87c4SChristoph Hellwig atomic_inc(&dqp->q_pincount); 91c59d87c4SChristoph Hellwig } 92c59d87c4SChristoph Hellwig 93c59d87c4SChristoph Hellwig /* 94c59d87c4SChristoph Hellwig * Decrement the pin count of the given dquot, and wake up 95c59d87c4SChristoph Hellwig * anyone in xfs_dqwait_unpin() if the count goes to 0. The 96c59d87c4SChristoph Hellwig * dquot must have been previously pinned with a call to 97c59d87c4SChristoph Hellwig * xfs_qm_dquot_logitem_pin(). 98c59d87c4SChristoph Hellwig */ 99c59d87c4SChristoph Hellwig STATIC void 100c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_unpin( 101c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 102c59d87c4SChristoph Hellwig int remove) 103c59d87c4SChristoph Hellwig { 104c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 105c59d87c4SChristoph Hellwig 106c59d87c4SChristoph Hellwig ASSERT(atomic_read(&dqp->q_pincount) > 0); 107c59d87c4SChristoph Hellwig if (atomic_dec_and_test(&dqp->q_pincount)) 108c59d87c4SChristoph Hellwig wake_up(&dqp->q_pinwait); 109c59d87c4SChristoph Hellwig } 110c59d87c4SChristoph Hellwig 111c59d87c4SChristoph Hellwig STATIC xfs_lsn_t 112c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_committed( 113c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 114c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 115c59d87c4SChristoph Hellwig { 116c59d87c4SChristoph Hellwig /* 117c59d87c4SChristoph Hellwig * We always re-log the entire dquot when it becomes dirty, 118c59d87c4SChristoph Hellwig * so, the latest copy _is_ the only one that matters. 119c59d87c4SChristoph Hellwig */ 120c59d87c4SChristoph Hellwig return lsn; 121c59d87c4SChristoph Hellwig } 122c59d87c4SChristoph Hellwig 123c59d87c4SChristoph Hellwig /* 124c59d87c4SChristoph Hellwig * This is called to wait for the given dquot to be unpinned. 125c59d87c4SChristoph Hellwig * Most of these pin/unpin routines are plagiarized from inode code. 126c59d87c4SChristoph Hellwig */ 127c59d87c4SChristoph Hellwig void 128c59d87c4SChristoph Hellwig xfs_qm_dqunpin_wait( 129c59d87c4SChristoph Hellwig struct xfs_dquot *dqp) 130c59d87c4SChristoph Hellwig { 131c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 132c59d87c4SChristoph Hellwig if (atomic_read(&dqp->q_pincount) == 0) 133c59d87c4SChristoph Hellwig return; 134c59d87c4SChristoph Hellwig 135c59d87c4SChristoph Hellwig /* 136c59d87c4SChristoph Hellwig * Give the log a push so we don't wait here too long. 137c59d87c4SChristoph Hellwig */ 138c59d87c4SChristoph Hellwig xfs_log_force(dqp->q_mount, 0); 139c59d87c4SChristoph Hellwig wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); 140c59d87c4SChristoph Hellwig } 141c59d87c4SChristoph Hellwig 142c59d87c4SChristoph Hellwig STATIC uint 14343ff2122SChristoph Hellwig xfs_qm_dquot_logitem_push( 14443ff2122SChristoph Hellwig struct xfs_log_item *lip, 145a30b0367SDave Chinner struct list_head *buffer_list) __releases(&lip->li_ailp->xa_lock) 146a30b0367SDave Chinner __acquires(&lip->li_ailp->xa_lock) 147c59d87c4SChristoph Hellwig { 148c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 14943ff2122SChristoph Hellwig struct xfs_buf *bp = NULL; 15043ff2122SChristoph Hellwig uint rval = XFS_ITEM_SUCCESS; 15143ff2122SChristoph Hellwig int error; 152c59d87c4SChristoph Hellwig 153c59d87c4SChristoph Hellwig if (atomic_read(&dqp->q_pincount) > 0) 154c59d87c4SChristoph Hellwig return XFS_ITEM_PINNED; 155c59d87c4SChristoph Hellwig 156800b484eSChristoph Hellwig if (!xfs_dqlock_nowait(dqp)) 157c59d87c4SChristoph Hellwig return XFS_ITEM_LOCKED; 158c59d87c4SChristoph Hellwig 159fe7257fdSChristoph Hellwig /* 160fe7257fdSChristoph Hellwig * Re-check the pincount now that we stabilized the value by 161fe7257fdSChristoph Hellwig * taking the quota lock. 162fe7257fdSChristoph Hellwig */ 163fe7257fdSChristoph Hellwig if (atomic_read(&dqp->q_pincount) > 0) { 16443ff2122SChristoph Hellwig rval = XFS_ITEM_PINNED; 16543ff2122SChristoph Hellwig goto out_unlock; 166fe7257fdSChristoph Hellwig } 167fe7257fdSChristoph Hellwig 168c59d87c4SChristoph Hellwig /* 16943ff2122SChristoph Hellwig * Someone else is already flushing the dquot. Nothing we can do 17043ff2122SChristoph Hellwig * here but wait for the flush to finish and remove the item from 17143ff2122SChristoph Hellwig * the AIL. 172c59d87c4SChristoph Hellwig */ 17343ff2122SChristoph Hellwig if (!xfs_dqflock_nowait(dqp)) { 17443ff2122SChristoph Hellwig rval = XFS_ITEM_FLUSHING; 17543ff2122SChristoph Hellwig goto out_unlock; 176c59d87c4SChristoph Hellwig } 177c59d87c4SChristoph Hellwig 17843ff2122SChristoph Hellwig spin_unlock(&lip->li_ailp->xa_lock); 17943ff2122SChristoph Hellwig 18043ff2122SChristoph Hellwig error = xfs_qm_dqflush(dqp, &bp); 18143ff2122SChristoph Hellwig if (error) { 18243ff2122SChristoph Hellwig xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p", 18343ff2122SChristoph Hellwig __func__, error, dqp); 18443ff2122SChristoph Hellwig } else { 18543ff2122SChristoph Hellwig if (!xfs_buf_delwri_queue(bp, buffer_list)) 18643ff2122SChristoph Hellwig rval = XFS_ITEM_FLUSHING; 18743ff2122SChristoph Hellwig xfs_buf_relse(bp); 18843ff2122SChristoph Hellwig } 18943ff2122SChristoph Hellwig 19043ff2122SChristoph Hellwig spin_lock(&lip->li_ailp->xa_lock); 19143ff2122SChristoph Hellwig out_unlock: 19243ff2122SChristoph Hellwig xfs_dqunlock(dqp); 19343ff2122SChristoph Hellwig return rval; 194c59d87c4SChristoph Hellwig } 195c59d87c4SChristoph Hellwig 196c59d87c4SChristoph Hellwig /* 197c59d87c4SChristoph Hellwig * Unlock the dquot associated with the log item. 198c59d87c4SChristoph Hellwig * Clear the fields of the dquot and dquot log item that 199c59d87c4SChristoph Hellwig * are specific to the current transaction. If the 200c59d87c4SChristoph Hellwig * hold flags is set, do not unlock the dquot. 201c59d87c4SChristoph Hellwig */ 202c59d87c4SChristoph Hellwig STATIC void 203c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_unlock( 204c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 205c59d87c4SChristoph Hellwig { 206c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 207c59d87c4SChristoph Hellwig 208c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 209c59d87c4SChristoph Hellwig 210c59d87c4SChristoph Hellwig /* 211c59d87c4SChristoph Hellwig * Clear the transaction pointer in the dquot 212c59d87c4SChristoph Hellwig */ 213c59d87c4SChristoph Hellwig dqp->q_transp = NULL; 214c59d87c4SChristoph Hellwig 215c59d87c4SChristoph Hellwig /* 216c59d87c4SChristoph Hellwig * dquots are never 'held' from getting unlocked at the end of 217c59d87c4SChristoph Hellwig * a transaction. Their locking and unlocking is hidden inside the 218c59d87c4SChristoph Hellwig * transaction layer, within trans_commit. Hence, no LI_HOLD flag 219c59d87c4SChristoph Hellwig * for the logitem. 220c59d87c4SChristoph Hellwig */ 221c59d87c4SChristoph Hellwig xfs_dqunlock(dqp); 222c59d87c4SChristoph Hellwig } 223c59d87c4SChristoph Hellwig 224c59d87c4SChristoph Hellwig /* 225c59d87c4SChristoph Hellwig * this needs to stamp an lsn into the dquot, I think. 226c59d87c4SChristoph Hellwig * rpc's that look at user dquot's would then have to 227c59d87c4SChristoph Hellwig * push on the dependency recorded in the dquot 228c59d87c4SChristoph Hellwig */ 229c59d87c4SChristoph Hellwig STATIC void 230c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_committing( 231c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 232c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 233c59d87c4SChristoph Hellwig { 234c59d87c4SChristoph Hellwig } 235c59d87c4SChristoph Hellwig 236c59d87c4SChristoph Hellwig /* 237c59d87c4SChristoph Hellwig * This is the ops vector for dquots 238c59d87c4SChristoph Hellwig */ 239272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_dquot_item_ops = { 240c59d87c4SChristoph Hellwig .iop_size = xfs_qm_dquot_logitem_size, 241c59d87c4SChristoph Hellwig .iop_format = xfs_qm_dquot_logitem_format, 242c59d87c4SChristoph Hellwig .iop_pin = xfs_qm_dquot_logitem_pin, 243c59d87c4SChristoph Hellwig .iop_unpin = xfs_qm_dquot_logitem_unpin, 244c59d87c4SChristoph Hellwig .iop_unlock = xfs_qm_dquot_logitem_unlock, 245c59d87c4SChristoph Hellwig .iop_committed = xfs_qm_dquot_logitem_committed, 246c59d87c4SChristoph Hellwig .iop_push = xfs_qm_dquot_logitem_push, 247c59d87c4SChristoph Hellwig .iop_committing = xfs_qm_dquot_logitem_committing 248c59d87c4SChristoph Hellwig }; 249c59d87c4SChristoph Hellwig 250c59d87c4SChristoph Hellwig /* 251c59d87c4SChristoph Hellwig * Initialize the dquot log item for a newly allocated dquot. 252c59d87c4SChristoph Hellwig * The dquot isn't locked at this point, but it isn't on any of the lists 253c59d87c4SChristoph Hellwig * either, so we don't care. 254c59d87c4SChristoph Hellwig */ 255c59d87c4SChristoph Hellwig void 256c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_init( 257c59d87c4SChristoph Hellwig struct xfs_dquot *dqp) 258c59d87c4SChristoph Hellwig { 259c59d87c4SChristoph Hellwig struct xfs_dq_logitem *lp = &dqp->q_logitem; 260c59d87c4SChristoph Hellwig 261c59d87c4SChristoph Hellwig xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT, 262c59d87c4SChristoph Hellwig &xfs_dquot_item_ops); 263c59d87c4SChristoph Hellwig lp->qli_dquot = dqp; 264c59d87c4SChristoph Hellwig } 265c59d87c4SChristoph Hellwig 266c59d87c4SChristoph Hellwig /*------------------ QUOTAOFF LOG ITEMS -------------------*/ 267c59d87c4SChristoph Hellwig 268c59d87c4SChristoph Hellwig static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip) 269c59d87c4SChristoph Hellwig { 270c59d87c4SChristoph Hellwig return container_of(lip, struct xfs_qoff_logitem, qql_item); 271c59d87c4SChristoph Hellwig } 272c59d87c4SChristoph Hellwig 273c59d87c4SChristoph Hellwig 274c59d87c4SChristoph Hellwig /* 275c59d87c4SChristoph Hellwig * This returns the number of iovecs needed to log the given quotaoff item. 276c59d87c4SChristoph Hellwig * We only need 1 iovec for an quotaoff item. It just logs the 277c59d87c4SChristoph Hellwig * quotaoff_log_format structure. 278c59d87c4SChristoph Hellwig */ 279166d1368SDave Chinner STATIC void 280c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_size( 281166d1368SDave Chinner struct xfs_log_item *lip, 282166d1368SDave Chinner int *nvecs, 283166d1368SDave Chinner int *nbytes) 284c59d87c4SChristoph Hellwig { 285166d1368SDave Chinner *nvecs += 1; 286166d1368SDave Chinner *nbytes += sizeof(struct xfs_qoff_logitem); 287c59d87c4SChristoph Hellwig } 288c59d87c4SChristoph Hellwig 289c59d87c4SChristoph Hellwig /* 290c59d87c4SChristoph Hellwig * This is called to fill in the vector of log iovecs for the 291c59d87c4SChristoph Hellwig * given quotaoff log item. We use only 1 iovec, and we point that 292c59d87c4SChristoph Hellwig * at the quotaoff_log_format structure embedded in the quotaoff item. 293c59d87c4SChristoph Hellwig * It is at this point that we assert that all of the extent 294c59d87c4SChristoph Hellwig * slots in the quotaoff item have been filled. 295c59d87c4SChristoph Hellwig */ 296c59d87c4SChristoph Hellwig STATIC void 297c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_format( 298c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 299bde7cff6SChristoph Hellwig struct xfs_log_vec *lv) 300c59d87c4SChristoph Hellwig { 301c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); 302bde7cff6SChristoph Hellwig struct xfs_log_iovec *vecp = NULL; 303c59d87c4SChristoph Hellwig 304c59d87c4SChristoph Hellwig ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF); 305bde7cff6SChristoph Hellwig qflip->qql_format.qf_size = 1; 306c59d87c4SChristoph Hellwig 307bde7cff6SChristoph Hellwig xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF, 3081234351cSChristoph Hellwig &qflip->qql_format, 3091234351cSChristoph Hellwig sizeof(struct xfs_qoff_logitem)); 310c59d87c4SChristoph Hellwig } 311c59d87c4SChristoph Hellwig 312c59d87c4SChristoph Hellwig /* 313c59d87c4SChristoph Hellwig * Pinning has no meaning for an quotaoff item, so just return. 314c59d87c4SChristoph Hellwig */ 315c59d87c4SChristoph Hellwig STATIC void 316c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_pin( 317c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 318c59d87c4SChristoph Hellwig { 319c59d87c4SChristoph Hellwig } 320c59d87c4SChristoph Hellwig 321c59d87c4SChristoph Hellwig /* 322c59d87c4SChristoph Hellwig * Since pinning has no meaning for an quotaoff item, unpinning does 323c59d87c4SChristoph Hellwig * not either. 324c59d87c4SChristoph Hellwig */ 325c59d87c4SChristoph Hellwig STATIC void 326c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_unpin( 327c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 328c59d87c4SChristoph Hellwig int remove) 329c59d87c4SChristoph Hellwig { 330c59d87c4SChristoph Hellwig } 331c59d87c4SChristoph Hellwig 332c59d87c4SChristoph Hellwig /* 33343ff2122SChristoph Hellwig * There isn't much you can do to push a quotaoff item. It is simply 33443ff2122SChristoph Hellwig * stuck waiting for the log to be flushed to disk. 335c59d87c4SChristoph Hellwig */ 336c59d87c4SChristoph Hellwig STATIC uint 33743ff2122SChristoph Hellwig xfs_qm_qoff_logitem_push( 33843ff2122SChristoph Hellwig struct xfs_log_item *lip, 33943ff2122SChristoph Hellwig struct list_head *buffer_list) 340c59d87c4SChristoph Hellwig { 341c59d87c4SChristoph Hellwig return XFS_ITEM_LOCKED; 342c59d87c4SChristoph Hellwig } 343c59d87c4SChristoph Hellwig 344c59d87c4SChristoph Hellwig /* 345c59d87c4SChristoph Hellwig * Quotaoff items have no locking or pushing, so return failure 346c59d87c4SChristoph Hellwig * so that the caller doesn't bother with us. 347c59d87c4SChristoph Hellwig */ 348c59d87c4SChristoph Hellwig STATIC void 349c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_unlock( 350c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 351c59d87c4SChristoph Hellwig { 352c59d87c4SChristoph Hellwig } 353c59d87c4SChristoph Hellwig 354c59d87c4SChristoph Hellwig /* 355c59d87c4SChristoph Hellwig * The quotaoff-start-item is logged only once and cannot be moved in the log, 356c59d87c4SChristoph Hellwig * so simply return the lsn at which it's been logged. 357c59d87c4SChristoph Hellwig */ 358c59d87c4SChristoph Hellwig STATIC xfs_lsn_t 359c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_committed( 360c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 361c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 362c59d87c4SChristoph Hellwig { 363c59d87c4SChristoph Hellwig return lsn; 364c59d87c4SChristoph Hellwig } 365c59d87c4SChristoph Hellwig 366c59d87c4SChristoph Hellwig STATIC xfs_lsn_t 367c59d87c4SChristoph Hellwig xfs_qm_qoffend_logitem_committed( 368c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 369c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 370c59d87c4SChristoph Hellwig { 371c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip); 372c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qfs = qfe->qql_start_lip; 373c59d87c4SChristoph Hellwig struct xfs_ail *ailp = qfs->qql_item.li_ailp; 374c59d87c4SChristoph Hellwig 375c59d87c4SChristoph Hellwig /* 376c59d87c4SChristoph Hellwig * Delete the qoff-start logitem from the AIL. 377c59d87c4SChristoph Hellwig * xfs_trans_ail_delete() drops the AIL lock. 378c59d87c4SChristoph Hellwig */ 379c59d87c4SChristoph Hellwig spin_lock(&ailp->xa_lock); 38004913fddSDave Chinner xfs_trans_ail_delete(ailp, &qfs->qql_item, SHUTDOWN_LOG_IO_ERROR); 381c59d87c4SChristoph Hellwig 382c59d87c4SChristoph Hellwig kmem_free(qfs); 383c59d87c4SChristoph Hellwig kmem_free(qfe); 384c59d87c4SChristoph Hellwig return (xfs_lsn_t)-1; 385c59d87c4SChristoph Hellwig } 386c59d87c4SChristoph Hellwig 387c59d87c4SChristoph Hellwig /* 388c59d87c4SChristoph Hellwig * XXX rcc - don't know quite what to do with this. I think we can 389c59d87c4SChristoph Hellwig * just ignore it. The only time that isn't the case is if we allow 390c59d87c4SChristoph Hellwig * the client to somehow see that quotas have been turned off in which 391c59d87c4SChristoph Hellwig * we can't allow that to get back until the quotaoff hits the disk. 392c59d87c4SChristoph Hellwig * So how would that happen? Also, do we need different routines for 393c59d87c4SChristoph Hellwig * quotaoff start and quotaoff end? I suspect the answer is yes but 394c59d87c4SChristoph Hellwig * to be sure, I need to look at the recovery code and see how quota off 395c59d87c4SChristoph Hellwig * recovery is handled (do we roll forward or back or do something else). 396c59d87c4SChristoph Hellwig * If we roll forwards or backwards, then we need two separate routines, 397c59d87c4SChristoph Hellwig * one that does nothing and one that stamps in the lsn that matters 398c59d87c4SChristoph Hellwig * (truly makes the quotaoff irrevocable). If we do something else, 399c59d87c4SChristoph Hellwig * then maybe we don't need two. 400c59d87c4SChristoph Hellwig */ 401c59d87c4SChristoph Hellwig STATIC void 402c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_committing( 403c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 404c59d87c4SChristoph Hellwig xfs_lsn_t commit_lsn) 405c59d87c4SChristoph Hellwig { 406c59d87c4SChristoph Hellwig } 407c59d87c4SChristoph Hellwig 408272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { 409c59d87c4SChristoph Hellwig .iop_size = xfs_qm_qoff_logitem_size, 410c59d87c4SChristoph Hellwig .iop_format = xfs_qm_qoff_logitem_format, 411c59d87c4SChristoph Hellwig .iop_pin = xfs_qm_qoff_logitem_pin, 412c59d87c4SChristoph Hellwig .iop_unpin = xfs_qm_qoff_logitem_unpin, 413c59d87c4SChristoph Hellwig .iop_unlock = xfs_qm_qoff_logitem_unlock, 414c59d87c4SChristoph Hellwig .iop_committed = xfs_qm_qoffend_logitem_committed, 415c59d87c4SChristoph Hellwig .iop_push = xfs_qm_qoff_logitem_push, 416c59d87c4SChristoph Hellwig .iop_committing = xfs_qm_qoff_logitem_committing 417c59d87c4SChristoph Hellwig }; 418c59d87c4SChristoph Hellwig 419c59d87c4SChristoph Hellwig /* 420c59d87c4SChristoph Hellwig * This is the ops vector shared by all quotaoff-start log items. 421c59d87c4SChristoph Hellwig */ 422272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = { 423c59d87c4SChristoph Hellwig .iop_size = xfs_qm_qoff_logitem_size, 424c59d87c4SChristoph Hellwig .iop_format = xfs_qm_qoff_logitem_format, 425c59d87c4SChristoph Hellwig .iop_pin = xfs_qm_qoff_logitem_pin, 426c59d87c4SChristoph Hellwig .iop_unpin = xfs_qm_qoff_logitem_unpin, 427c59d87c4SChristoph Hellwig .iop_unlock = xfs_qm_qoff_logitem_unlock, 428c59d87c4SChristoph Hellwig .iop_committed = xfs_qm_qoff_logitem_committed, 429c59d87c4SChristoph Hellwig .iop_push = xfs_qm_qoff_logitem_push, 430c59d87c4SChristoph Hellwig .iop_committing = xfs_qm_qoff_logitem_committing 431c59d87c4SChristoph Hellwig }; 432c59d87c4SChristoph Hellwig 433c59d87c4SChristoph Hellwig /* 434c59d87c4SChristoph Hellwig * Allocate and initialize an quotaoff item of the correct quota type(s). 435c59d87c4SChristoph Hellwig */ 436c59d87c4SChristoph Hellwig struct xfs_qoff_logitem * 437c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_init( 438c59d87c4SChristoph Hellwig struct xfs_mount *mp, 439c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *start, 440c59d87c4SChristoph Hellwig uint flags) 441c59d87c4SChristoph Hellwig { 442c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qf; 443c59d87c4SChristoph Hellwig 444c59d87c4SChristoph Hellwig qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), KM_SLEEP); 445c59d87c4SChristoph Hellwig 446c59d87c4SChristoph Hellwig xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ? 447c59d87c4SChristoph Hellwig &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops); 448c59d87c4SChristoph Hellwig qf->qql_item.li_mountp = mp; 449c59d87c4SChristoph Hellwig qf->qql_format.qf_type = XFS_LI_QUOTAOFF; 450c59d87c4SChristoph Hellwig qf->qql_format.qf_flags = flags; 451c59d87c4SChristoph Hellwig qf->qql_start_lip = start; 452c59d87c4SChristoph Hellwig return qf; 453c59d87c4SChristoph Hellwig } 454