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" 8*5467b34bSDarrick 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" 15c59d87c4SChristoph Hellwig #include "xfs_error.h" 16239880efSDave Chinner #include "xfs_trans.h" 17c59d87c4SChristoph Hellwig #include "xfs_buf_item.h" 18c59d87c4SChristoph Hellwig #include "xfs_trans_priv.h" 19c59d87c4SChristoph Hellwig #include "xfs_qm.h" 20239880efSDave Chinner #include "xfs_log.h" 21c59d87c4SChristoph Hellwig 22c59d87c4SChristoph Hellwig static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip) 23c59d87c4SChristoph Hellwig { 24c59d87c4SChristoph Hellwig return container_of(lip, struct xfs_dq_logitem, qli_item); 25c59d87c4SChristoph Hellwig } 26c59d87c4SChristoph Hellwig 27c59d87c4SChristoph Hellwig /* 28c59d87c4SChristoph Hellwig * returns the number of iovecs needed to log the given dquot item. 29c59d87c4SChristoph Hellwig */ 30166d1368SDave Chinner STATIC void 31c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_size( 32166d1368SDave Chinner struct xfs_log_item *lip, 33166d1368SDave Chinner int *nvecs, 34166d1368SDave Chinner int *nbytes) 35c59d87c4SChristoph Hellwig { 36166d1368SDave Chinner *nvecs += 2; 37166d1368SDave Chinner *nbytes += sizeof(struct xfs_dq_logformat) + 38166d1368SDave Chinner sizeof(struct xfs_disk_dquot); 39c59d87c4SChristoph Hellwig } 40c59d87c4SChristoph Hellwig 41c59d87c4SChristoph Hellwig /* 42c59d87c4SChristoph Hellwig * fills in the vector of log iovecs for the given dquot log item. 43c59d87c4SChristoph Hellwig */ 44c59d87c4SChristoph Hellwig STATIC void 45c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_format( 46c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 47bde7cff6SChristoph Hellwig struct xfs_log_vec *lv) 48c59d87c4SChristoph Hellwig { 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 62bde7cff6SChristoph Hellwig xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, 63bde7cff6SChristoph Hellwig &qlip->qli_dquot->q_core, 64bde7cff6SChristoph Hellwig sizeof(struct xfs_disk_dquot)); 65c59d87c4SChristoph Hellwig } 66c59d87c4SChristoph Hellwig 67c59d87c4SChristoph Hellwig /* 68c59d87c4SChristoph Hellwig * Increment the pin count of the given dquot. 69c59d87c4SChristoph Hellwig */ 70c59d87c4SChristoph Hellwig STATIC void 71c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_pin( 72c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 73c59d87c4SChristoph Hellwig { 74c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 75c59d87c4SChristoph Hellwig 76c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 77c59d87c4SChristoph Hellwig atomic_inc(&dqp->q_pincount); 78c59d87c4SChristoph Hellwig } 79c59d87c4SChristoph Hellwig 80c59d87c4SChristoph Hellwig /* 81c59d87c4SChristoph Hellwig * Decrement the pin count of the given dquot, and wake up 82c59d87c4SChristoph Hellwig * anyone in xfs_dqwait_unpin() if the count goes to 0. The 83c59d87c4SChristoph Hellwig * dquot must have been previously pinned with a call to 84c59d87c4SChristoph Hellwig * xfs_qm_dquot_logitem_pin(). 85c59d87c4SChristoph Hellwig */ 86c59d87c4SChristoph Hellwig STATIC void 87c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_unpin( 88c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 89c59d87c4SChristoph Hellwig int remove) 90c59d87c4SChristoph Hellwig { 91c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 92c59d87c4SChristoph Hellwig 93c59d87c4SChristoph Hellwig ASSERT(atomic_read(&dqp->q_pincount) > 0); 94c59d87c4SChristoph Hellwig if (atomic_dec_and_test(&dqp->q_pincount)) 95c59d87c4SChristoph Hellwig wake_up(&dqp->q_pinwait); 96c59d87c4SChristoph Hellwig } 97c59d87c4SChristoph Hellwig 98c59d87c4SChristoph Hellwig STATIC xfs_lsn_t 99c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_committed( 100c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 101c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 102c59d87c4SChristoph Hellwig { 103c59d87c4SChristoph Hellwig /* 104c59d87c4SChristoph Hellwig * We always re-log the entire dquot when it becomes dirty, 105c59d87c4SChristoph Hellwig * so, the latest copy _is_ the only one that matters. 106c59d87c4SChristoph Hellwig */ 107c59d87c4SChristoph Hellwig return lsn; 108c59d87c4SChristoph Hellwig } 109c59d87c4SChristoph Hellwig 110c59d87c4SChristoph Hellwig /* 111c59d87c4SChristoph Hellwig * This is called to wait for the given dquot to be unpinned. 112c59d87c4SChristoph Hellwig * Most of these pin/unpin routines are plagiarized from inode code. 113c59d87c4SChristoph Hellwig */ 114c59d87c4SChristoph Hellwig void 115c59d87c4SChristoph Hellwig xfs_qm_dqunpin_wait( 116c59d87c4SChristoph Hellwig struct xfs_dquot *dqp) 117c59d87c4SChristoph Hellwig { 118c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 119c59d87c4SChristoph Hellwig if (atomic_read(&dqp->q_pincount) == 0) 120c59d87c4SChristoph Hellwig return; 121c59d87c4SChristoph Hellwig 122c59d87c4SChristoph Hellwig /* 123c59d87c4SChristoph Hellwig * Give the log a push so we don't wait here too long. 124c59d87c4SChristoph Hellwig */ 125c59d87c4SChristoph Hellwig xfs_log_force(dqp->q_mount, 0); 126c59d87c4SChristoph Hellwig wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); 127c59d87c4SChristoph Hellwig } 128c59d87c4SChristoph Hellwig 129373b0589SCarlos Maiolino /* 130373b0589SCarlos Maiolino * Callback used to mark a buffer with XFS_LI_FAILED when items in the buffer 131373b0589SCarlos Maiolino * have been failed during writeback 132373b0589SCarlos Maiolino * 133373b0589SCarlos Maiolino * this informs the AIL that the dquot is already flush locked on the next push, 134373b0589SCarlos Maiolino * and acquires a hold on the buffer to ensure that it isn't reclaimed before 135373b0589SCarlos Maiolino * dirty data makes it to disk. 136373b0589SCarlos Maiolino */ 137373b0589SCarlos Maiolino STATIC void 138373b0589SCarlos Maiolino xfs_dquot_item_error( 139373b0589SCarlos Maiolino struct xfs_log_item *lip, 140373b0589SCarlos Maiolino struct xfs_buf *bp) 141373b0589SCarlos Maiolino { 14275d4a13bSDarrick J. Wong ASSERT(!completion_done(&DQUOT_ITEM(lip)->qli_dquot->q_flush)); 143373b0589SCarlos Maiolino xfs_set_li_failed(lip, bp); 144373b0589SCarlos Maiolino } 145373b0589SCarlos Maiolino 146c59d87c4SChristoph Hellwig STATIC uint 14743ff2122SChristoph Hellwig xfs_qm_dquot_logitem_push( 14843ff2122SChristoph Hellwig struct xfs_log_item *lip, 14957e80956SMatthew Wilcox struct list_head *buffer_list) 15057e80956SMatthew Wilcox __releases(&lip->li_ailp->ail_lock) 15157e80956SMatthew Wilcox __acquires(&lip->li_ailp->ail_lock) 152c59d87c4SChristoph Hellwig { 153c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 154373b0589SCarlos Maiolino struct xfs_buf *bp = lip->li_buf; 15543ff2122SChristoph Hellwig uint rval = XFS_ITEM_SUCCESS; 15643ff2122SChristoph Hellwig int error; 157c59d87c4SChristoph Hellwig 158c59d87c4SChristoph Hellwig if (atomic_read(&dqp->q_pincount) > 0) 159c59d87c4SChristoph Hellwig return XFS_ITEM_PINNED; 160c59d87c4SChristoph Hellwig 161373b0589SCarlos Maiolino /* 162373b0589SCarlos Maiolino * The buffer containing this item failed to be written back 163373b0589SCarlos Maiolino * previously. Resubmit the buffer for IO 164373b0589SCarlos Maiolino */ 16522525c17SDave Chinner if (test_bit(XFS_LI_FAILED, &lip->li_flags)) { 166373b0589SCarlos Maiolino if (!xfs_buf_trylock(bp)) 167373b0589SCarlos Maiolino return XFS_ITEM_LOCKED; 168373b0589SCarlos Maiolino 169643c8c05SCarlos Maiolino if (!xfs_buf_resubmit_failed_buffers(bp, buffer_list)) 170373b0589SCarlos Maiolino rval = XFS_ITEM_FLUSHING; 171373b0589SCarlos Maiolino 172373b0589SCarlos Maiolino xfs_buf_unlock(bp); 173373b0589SCarlos Maiolino return rval; 174373b0589SCarlos Maiolino } 175373b0589SCarlos Maiolino 176800b484eSChristoph Hellwig if (!xfs_dqlock_nowait(dqp)) 177c59d87c4SChristoph Hellwig return XFS_ITEM_LOCKED; 178c59d87c4SChristoph Hellwig 179fe7257fdSChristoph Hellwig /* 180fe7257fdSChristoph Hellwig * Re-check the pincount now that we stabilized the value by 181fe7257fdSChristoph Hellwig * taking the quota lock. 182fe7257fdSChristoph Hellwig */ 183fe7257fdSChristoph Hellwig if (atomic_read(&dqp->q_pincount) > 0) { 18443ff2122SChristoph Hellwig rval = XFS_ITEM_PINNED; 18543ff2122SChristoph Hellwig goto out_unlock; 186fe7257fdSChristoph Hellwig } 187fe7257fdSChristoph Hellwig 188c59d87c4SChristoph Hellwig /* 18943ff2122SChristoph Hellwig * Someone else is already flushing the dquot. Nothing we can do 19043ff2122SChristoph Hellwig * here but wait for the flush to finish and remove the item from 19143ff2122SChristoph Hellwig * the AIL. 192c59d87c4SChristoph Hellwig */ 19343ff2122SChristoph Hellwig if (!xfs_dqflock_nowait(dqp)) { 19443ff2122SChristoph Hellwig rval = XFS_ITEM_FLUSHING; 19543ff2122SChristoph Hellwig goto out_unlock; 196c59d87c4SChristoph Hellwig } 197c59d87c4SChristoph Hellwig 19857e80956SMatthew Wilcox spin_unlock(&lip->li_ailp->ail_lock); 19943ff2122SChristoph Hellwig 20043ff2122SChristoph Hellwig error = xfs_qm_dqflush(dqp, &bp); 201609001bcSDarrick J. Wong if (!error) { 20243ff2122SChristoph Hellwig if (!xfs_buf_delwri_queue(bp, buffer_list)) 20343ff2122SChristoph Hellwig rval = XFS_ITEM_FLUSHING; 20443ff2122SChristoph Hellwig xfs_buf_relse(bp); 20543ff2122SChristoph Hellwig } 20643ff2122SChristoph Hellwig 20757e80956SMatthew Wilcox spin_lock(&lip->li_ailp->ail_lock); 20843ff2122SChristoph Hellwig out_unlock: 20943ff2122SChristoph Hellwig xfs_dqunlock(dqp); 21043ff2122SChristoph Hellwig return rval; 211c59d87c4SChristoph Hellwig } 212c59d87c4SChristoph Hellwig 213c59d87c4SChristoph Hellwig /* 214c59d87c4SChristoph Hellwig * Unlock the dquot associated with the log item. 215c59d87c4SChristoph Hellwig * Clear the fields of the dquot and dquot log item that 216c59d87c4SChristoph Hellwig * are specific to the current transaction. If the 217c59d87c4SChristoph Hellwig * hold flags is set, do not unlock the dquot. 218c59d87c4SChristoph Hellwig */ 219c59d87c4SChristoph Hellwig STATIC void 220c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_unlock( 221c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 222c59d87c4SChristoph Hellwig { 223c59d87c4SChristoph Hellwig struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 224c59d87c4SChristoph Hellwig 225c59d87c4SChristoph Hellwig ASSERT(XFS_DQ_IS_LOCKED(dqp)); 226c59d87c4SChristoph Hellwig 227c59d87c4SChristoph Hellwig /* 228c59d87c4SChristoph Hellwig * dquots are never 'held' from getting unlocked at the end of 229c59d87c4SChristoph Hellwig * a transaction. Their locking and unlocking is hidden inside the 230c59d87c4SChristoph Hellwig * transaction layer, within trans_commit. Hence, no LI_HOLD flag 231c59d87c4SChristoph Hellwig * for the logitem. 232c59d87c4SChristoph Hellwig */ 233c59d87c4SChristoph Hellwig xfs_dqunlock(dqp); 234c59d87c4SChristoph Hellwig } 235c59d87c4SChristoph Hellwig 236c59d87c4SChristoph Hellwig /* 237c59d87c4SChristoph Hellwig * this needs to stamp an lsn into the dquot, I think. 238c59d87c4SChristoph Hellwig * rpc's that look at user dquot's would then have to 239c59d87c4SChristoph Hellwig * push on the dependency recorded in the dquot 240c59d87c4SChristoph Hellwig */ 241c59d87c4SChristoph Hellwig STATIC void 242c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_committing( 243c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 244c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 245c59d87c4SChristoph Hellwig { 246c59d87c4SChristoph Hellwig } 247c59d87c4SChristoph Hellwig 248c59d87c4SChristoph Hellwig /* 249c59d87c4SChristoph Hellwig * This is the ops vector for dquots 250c59d87c4SChristoph Hellwig */ 251272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_dquot_item_ops = { 252c59d87c4SChristoph Hellwig .iop_size = xfs_qm_dquot_logitem_size, 253c59d87c4SChristoph Hellwig .iop_format = xfs_qm_dquot_logitem_format, 254c59d87c4SChristoph Hellwig .iop_pin = xfs_qm_dquot_logitem_pin, 255c59d87c4SChristoph Hellwig .iop_unpin = xfs_qm_dquot_logitem_unpin, 256c59d87c4SChristoph Hellwig .iop_unlock = xfs_qm_dquot_logitem_unlock, 257c59d87c4SChristoph Hellwig .iop_committed = xfs_qm_dquot_logitem_committed, 258c59d87c4SChristoph Hellwig .iop_push = xfs_qm_dquot_logitem_push, 259373b0589SCarlos Maiolino .iop_committing = xfs_qm_dquot_logitem_committing, 260373b0589SCarlos Maiolino .iop_error = xfs_dquot_item_error 261c59d87c4SChristoph Hellwig }; 262c59d87c4SChristoph Hellwig 263c59d87c4SChristoph Hellwig /* 264c59d87c4SChristoph Hellwig * Initialize the dquot log item for a newly allocated dquot. 265c59d87c4SChristoph Hellwig * The dquot isn't locked at this point, but it isn't on any of the lists 266c59d87c4SChristoph Hellwig * either, so we don't care. 267c59d87c4SChristoph Hellwig */ 268c59d87c4SChristoph Hellwig void 269c59d87c4SChristoph Hellwig xfs_qm_dquot_logitem_init( 270c59d87c4SChristoph Hellwig struct xfs_dquot *dqp) 271c59d87c4SChristoph Hellwig { 272c59d87c4SChristoph Hellwig struct xfs_dq_logitem *lp = &dqp->q_logitem; 273c59d87c4SChristoph Hellwig 274c59d87c4SChristoph Hellwig xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT, 275c59d87c4SChristoph Hellwig &xfs_dquot_item_ops); 276c59d87c4SChristoph Hellwig lp->qli_dquot = dqp; 277c59d87c4SChristoph Hellwig } 278c59d87c4SChristoph Hellwig 279c59d87c4SChristoph Hellwig /*------------------ QUOTAOFF LOG ITEMS -------------------*/ 280c59d87c4SChristoph Hellwig 281c59d87c4SChristoph Hellwig static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip) 282c59d87c4SChristoph Hellwig { 283c59d87c4SChristoph Hellwig return container_of(lip, struct xfs_qoff_logitem, qql_item); 284c59d87c4SChristoph Hellwig } 285c59d87c4SChristoph Hellwig 286c59d87c4SChristoph Hellwig 287c59d87c4SChristoph Hellwig /* 288c59d87c4SChristoph Hellwig * This returns the number of iovecs needed to log the given quotaoff item. 289c59d87c4SChristoph Hellwig * We only need 1 iovec for an quotaoff item. It just logs the 290c59d87c4SChristoph Hellwig * quotaoff_log_format structure. 291c59d87c4SChristoph Hellwig */ 292166d1368SDave Chinner STATIC void 293c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_size( 294166d1368SDave Chinner struct xfs_log_item *lip, 295166d1368SDave Chinner int *nvecs, 296166d1368SDave Chinner int *nbytes) 297c59d87c4SChristoph Hellwig { 298166d1368SDave Chinner *nvecs += 1; 299166d1368SDave Chinner *nbytes += sizeof(struct xfs_qoff_logitem); 300c59d87c4SChristoph Hellwig } 301c59d87c4SChristoph Hellwig 302c59d87c4SChristoph Hellwig STATIC void 303c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_format( 304c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 305bde7cff6SChristoph Hellwig struct xfs_log_vec *lv) 306c59d87c4SChristoph Hellwig { 307c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); 308bde7cff6SChristoph Hellwig struct xfs_log_iovec *vecp = NULL; 309ffda4e83SChristoph Hellwig struct xfs_qoff_logformat *qlf; 310c59d87c4SChristoph Hellwig 311ffda4e83SChristoph Hellwig qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF); 312ffda4e83SChristoph Hellwig qlf->qf_type = XFS_LI_QUOTAOFF; 313ffda4e83SChristoph Hellwig qlf->qf_size = 1; 314ffda4e83SChristoph Hellwig qlf->qf_flags = qflip->qql_flags; 315ffda4e83SChristoph Hellwig xlog_finish_iovec(lv, vecp, sizeof(struct xfs_qoff_logitem)); 316c59d87c4SChristoph Hellwig } 317c59d87c4SChristoph Hellwig 318c59d87c4SChristoph Hellwig /* 319c59d87c4SChristoph Hellwig * Pinning has no meaning for an quotaoff item, so just return. 320c59d87c4SChristoph Hellwig */ 321c59d87c4SChristoph Hellwig STATIC void 322c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_pin( 323c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 324c59d87c4SChristoph Hellwig { 325c59d87c4SChristoph Hellwig } 326c59d87c4SChristoph Hellwig 327c59d87c4SChristoph Hellwig /* 328c59d87c4SChristoph Hellwig * Since pinning has no meaning for an quotaoff item, unpinning does 329c59d87c4SChristoph Hellwig * not either. 330c59d87c4SChristoph Hellwig */ 331c59d87c4SChristoph Hellwig STATIC void 332c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_unpin( 333c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 334c59d87c4SChristoph Hellwig int remove) 335c59d87c4SChristoph Hellwig { 336c59d87c4SChristoph Hellwig } 337c59d87c4SChristoph Hellwig 338c59d87c4SChristoph Hellwig /* 33943ff2122SChristoph Hellwig * There isn't much you can do to push a quotaoff item. It is simply 34043ff2122SChristoph Hellwig * stuck waiting for the log to be flushed to disk. 341c59d87c4SChristoph Hellwig */ 342c59d87c4SChristoph Hellwig STATIC uint 34343ff2122SChristoph Hellwig xfs_qm_qoff_logitem_push( 34443ff2122SChristoph Hellwig struct xfs_log_item *lip, 34543ff2122SChristoph Hellwig struct list_head *buffer_list) 346c59d87c4SChristoph Hellwig { 347c59d87c4SChristoph Hellwig return XFS_ITEM_LOCKED; 348c59d87c4SChristoph Hellwig } 349c59d87c4SChristoph Hellwig 350c59d87c4SChristoph Hellwig /* 351c59d87c4SChristoph Hellwig * Quotaoff items have no locking or pushing, so return failure 352c59d87c4SChristoph Hellwig * so that the caller doesn't bother with us. 353c59d87c4SChristoph Hellwig */ 354c59d87c4SChristoph Hellwig STATIC void 355c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_unlock( 356c59d87c4SChristoph Hellwig struct xfs_log_item *lip) 357c59d87c4SChristoph Hellwig { 358c59d87c4SChristoph Hellwig } 359c59d87c4SChristoph Hellwig 360c59d87c4SChristoph Hellwig /* 361c59d87c4SChristoph Hellwig * The quotaoff-start-item is logged only once and cannot be moved in the log, 362c59d87c4SChristoph Hellwig * so simply return the lsn at which it's been logged. 363c59d87c4SChristoph Hellwig */ 364c59d87c4SChristoph Hellwig STATIC xfs_lsn_t 365c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_committed( 366c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 367c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 368c59d87c4SChristoph Hellwig { 369c59d87c4SChristoph Hellwig return lsn; 370c59d87c4SChristoph Hellwig } 371c59d87c4SChristoph Hellwig 372c59d87c4SChristoph Hellwig STATIC xfs_lsn_t 373c59d87c4SChristoph Hellwig xfs_qm_qoffend_logitem_committed( 374c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 375c59d87c4SChristoph Hellwig xfs_lsn_t lsn) 376c59d87c4SChristoph Hellwig { 377c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip); 378c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qfs = qfe->qql_start_lip; 379c59d87c4SChristoph Hellwig struct xfs_ail *ailp = qfs->qql_item.li_ailp; 380c59d87c4SChristoph Hellwig 381c59d87c4SChristoph Hellwig /* 382c59d87c4SChristoph Hellwig * Delete the qoff-start logitem from the AIL. 383c59d87c4SChristoph Hellwig * xfs_trans_ail_delete() drops the AIL lock. 384c59d87c4SChristoph Hellwig */ 38557e80956SMatthew Wilcox spin_lock(&ailp->ail_lock); 38604913fddSDave Chinner xfs_trans_ail_delete(ailp, &qfs->qql_item, SHUTDOWN_LOG_IO_ERROR); 387c59d87c4SChristoph Hellwig 388b1c5ebb2SDave Chinner kmem_free(qfs->qql_item.li_lv_shadow); 389b1c5ebb2SDave Chinner kmem_free(lip->li_lv_shadow); 390c59d87c4SChristoph Hellwig kmem_free(qfs); 391c59d87c4SChristoph Hellwig kmem_free(qfe); 392c59d87c4SChristoph Hellwig return (xfs_lsn_t)-1; 393c59d87c4SChristoph Hellwig } 394c59d87c4SChristoph Hellwig 395c59d87c4SChristoph Hellwig /* 396c59d87c4SChristoph Hellwig * XXX rcc - don't know quite what to do with this. I think we can 397c59d87c4SChristoph Hellwig * just ignore it. The only time that isn't the case is if we allow 398c59d87c4SChristoph Hellwig * the client to somehow see that quotas have been turned off in which 399c59d87c4SChristoph Hellwig * we can't allow that to get back until the quotaoff hits the disk. 400c59d87c4SChristoph Hellwig * So how would that happen? Also, do we need different routines for 401c59d87c4SChristoph Hellwig * quotaoff start and quotaoff end? I suspect the answer is yes but 402c59d87c4SChristoph Hellwig * to be sure, I need to look at the recovery code and see how quota off 403c59d87c4SChristoph Hellwig * recovery is handled (do we roll forward or back or do something else). 404c59d87c4SChristoph Hellwig * If we roll forwards or backwards, then we need two separate routines, 405c59d87c4SChristoph Hellwig * one that does nothing and one that stamps in the lsn that matters 406c59d87c4SChristoph Hellwig * (truly makes the quotaoff irrevocable). If we do something else, 407c59d87c4SChristoph Hellwig * then maybe we don't need two. 408c59d87c4SChristoph Hellwig */ 409c59d87c4SChristoph Hellwig STATIC void 410c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_committing( 411c59d87c4SChristoph Hellwig struct xfs_log_item *lip, 412c59d87c4SChristoph Hellwig xfs_lsn_t commit_lsn) 413c59d87c4SChristoph Hellwig { 414c59d87c4SChristoph Hellwig } 415c59d87c4SChristoph Hellwig 416272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { 417c59d87c4SChristoph Hellwig .iop_size = xfs_qm_qoff_logitem_size, 418c59d87c4SChristoph Hellwig .iop_format = xfs_qm_qoff_logitem_format, 419c59d87c4SChristoph Hellwig .iop_pin = xfs_qm_qoff_logitem_pin, 420c59d87c4SChristoph Hellwig .iop_unpin = xfs_qm_qoff_logitem_unpin, 421c59d87c4SChristoph Hellwig .iop_unlock = xfs_qm_qoff_logitem_unlock, 422c59d87c4SChristoph Hellwig .iop_committed = xfs_qm_qoffend_logitem_committed, 423c59d87c4SChristoph Hellwig .iop_push = xfs_qm_qoff_logitem_push, 424c59d87c4SChristoph Hellwig .iop_committing = xfs_qm_qoff_logitem_committing 425c59d87c4SChristoph Hellwig }; 426c59d87c4SChristoph Hellwig 427c59d87c4SChristoph Hellwig /* 428c59d87c4SChristoph Hellwig * This is the ops vector shared by all quotaoff-start log items. 429c59d87c4SChristoph Hellwig */ 430272e42b2SChristoph Hellwig static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = { 431c59d87c4SChristoph Hellwig .iop_size = xfs_qm_qoff_logitem_size, 432c59d87c4SChristoph Hellwig .iop_format = xfs_qm_qoff_logitem_format, 433c59d87c4SChristoph Hellwig .iop_pin = xfs_qm_qoff_logitem_pin, 434c59d87c4SChristoph Hellwig .iop_unpin = xfs_qm_qoff_logitem_unpin, 435c59d87c4SChristoph Hellwig .iop_unlock = xfs_qm_qoff_logitem_unlock, 436c59d87c4SChristoph Hellwig .iop_committed = xfs_qm_qoff_logitem_committed, 437c59d87c4SChristoph Hellwig .iop_push = xfs_qm_qoff_logitem_push, 438c59d87c4SChristoph Hellwig .iop_committing = xfs_qm_qoff_logitem_committing 439c59d87c4SChristoph Hellwig }; 440c59d87c4SChristoph Hellwig 441c59d87c4SChristoph Hellwig /* 442c59d87c4SChristoph Hellwig * Allocate and initialize an quotaoff item of the correct quota type(s). 443c59d87c4SChristoph Hellwig */ 444c59d87c4SChristoph Hellwig struct xfs_qoff_logitem * 445c59d87c4SChristoph Hellwig xfs_qm_qoff_logitem_init( 446c59d87c4SChristoph Hellwig struct xfs_mount *mp, 447c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *start, 448c59d87c4SChristoph Hellwig uint flags) 449c59d87c4SChristoph Hellwig { 450c59d87c4SChristoph Hellwig struct xfs_qoff_logitem *qf; 451c59d87c4SChristoph Hellwig 452c59d87c4SChristoph Hellwig qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), KM_SLEEP); 453c59d87c4SChristoph Hellwig 454c59d87c4SChristoph Hellwig xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ? 455c59d87c4SChristoph Hellwig &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops); 456c59d87c4SChristoph Hellwig qf->qql_item.li_mountp = mp; 457c59d87c4SChristoph Hellwig qf->qql_start_lip = start; 458ffda4e83SChristoph Hellwig qf->qql_flags = flags; 459c59d87c4SChristoph Hellwig return qf; 460c59d87c4SChristoph Hellwig } 461