1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2003 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_mount.h" 13 #include "xfs_inode.h" 14 #include "xfs_quota.h" 15 #include "xfs_trans.h" 16 #include "xfs_buf_item.h" 17 #include "xfs_trans_priv.h" 18 #include "xfs_qm.h" 19 #include "xfs_log.h" 20 21 static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip) 22 { 23 return container_of(lip, struct xfs_dq_logitem, qli_item); 24 } 25 26 /* 27 * returns the number of iovecs needed to log the given dquot item. 28 */ 29 STATIC void 30 xfs_qm_dquot_logitem_size( 31 struct xfs_log_item *lip, 32 int *nvecs, 33 int *nbytes) 34 { 35 *nvecs += 2; 36 *nbytes += sizeof(struct xfs_dq_logformat) + 37 sizeof(struct xfs_disk_dquot); 38 } 39 40 /* 41 * fills in the vector of log iovecs for the given dquot log item. 42 */ 43 STATIC void 44 xfs_qm_dquot_logitem_format( 45 struct xfs_log_item *lip, 46 struct xfs_log_vec *lv) 47 { 48 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); 49 struct xfs_log_iovec *vecp = NULL; 50 struct xfs_dq_logformat *qlf; 51 52 qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT); 53 qlf->qlf_type = XFS_LI_DQUOT; 54 qlf->qlf_size = 2; 55 qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id); 56 qlf->qlf_blkno = qlip->qli_dquot->q_blkno; 57 qlf->qlf_len = 1; 58 qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; 59 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat)); 60 61 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, 62 &qlip->qli_dquot->q_core, 63 sizeof(struct xfs_disk_dquot)); 64 } 65 66 /* 67 * Increment the pin count of the given dquot. 68 */ 69 STATIC void 70 xfs_qm_dquot_logitem_pin( 71 struct xfs_log_item *lip) 72 { 73 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 74 75 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 76 atomic_inc(&dqp->q_pincount); 77 } 78 79 /* 80 * Decrement the pin count of the given dquot, and wake up 81 * anyone in xfs_dqwait_unpin() if the count goes to 0. The 82 * dquot must have been previously pinned with a call to 83 * xfs_qm_dquot_logitem_pin(). 84 */ 85 STATIC void 86 xfs_qm_dquot_logitem_unpin( 87 struct xfs_log_item *lip, 88 int remove) 89 { 90 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 91 92 ASSERT(atomic_read(&dqp->q_pincount) > 0); 93 if (atomic_dec_and_test(&dqp->q_pincount)) 94 wake_up(&dqp->q_pinwait); 95 } 96 97 /* 98 * This is called to wait for the given dquot to be unpinned. 99 * Most of these pin/unpin routines are plagiarized from inode code. 100 */ 101 void 102 xfs_qm_dqunpin_wait( 103 struct xfs_dquot *dqp) 104 { 105 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 106 if (atomic_read(&dqp->q_pincount) == 0) 107 return; 108 109 /* 110 * Give the log a push so we don't wait here too long. 111 */ 112 xfs_log_force(dqp->q_mount, 0); 113 wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); 114 } 115 116 /* 117 * Callback used to mark a buffer with XFS_LI_FAILED when items in the buffer 118 * have been failed during writeback 119 * 120 * this informs the AIL that the dquot is already flush locked on the next push, 121 * and acquires a hold on the buffer to ensure that it isn't reclaimed before 122 * dirty data makes it to disk. 123 */ 124 STATIC void 125 xfs_dquot_item_error( 126 struct xfs_log_item *lip, 127 struct xfs_buf *bp) 128 { 129 ASSERT(!completion_done(&DQUOT_ITEM(lip)->qli_dquot->q_flush)); 130 xfs_set_li_failed(lip, bp); 131 } 132 133 STATIC uint 134 xfs_qm_dquot_logitem_push( 135 struct xfs_log_item *lip, 136 struct list_head *buffer_list) 137 __releases(&lip->li_ailp->ail_lock) 138 __acquires(&lip->li_ailp->ail_lock) 139 { 140 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 141 struct xfs_buf *bp = lip->li_buf; 142 uint rval = XFS_ITEM_SUCCESS; 143 int error; 144 145 if (atomic_read(&dqp->q_pincount) > 0) 146 return XFS_ITEM_PINNED; 147 148 /* 149 * The buffer containing this item failed to be written back 150 * previously. Resubmit the buffer for IO 151 */ 152 if (test_bit(XFS_LI_FAILED, &lip->li_flags)) { 153 if (!xfs_buf_trylock(bp)) 154 return XFS_ITEM_LOCKED; 155 156 if (!xfs_buf_resubmit_failed_buffers(bp, buffer_list)) 157 rval = XFS_ITEM_FLUSHING; 158 159 xfs_buf_unlock(bp); 160 return rval; 161 } 162 163 if (!xfs_dqlock_nowait(dqp)) 164 return XFS_ITEM_LOCKED; 165 166 /* 167 * Re-check the pincount now that we stabilized the value by 168 * taking the quota lock. 169 */ 170 if (atomic_read(&dqp->q_pincount) > 0) { 171 rval = XFS_ITEM_PINNED; 172 goto out_unlock; 173 } 174 175 /* 176 * Someone else is already flushing the dquot. Nothing we can do 177 * here but wait for the flush to finish and remove the item from 178 * the AIL. 179 */ 180 if (!xfs_dqflock_nowait(dqp)) { 181 rval = XFS_ITEM_FLUSHING; 182 goto out_unlock; 183 } 184 185 spin_unlock(&lip->li_ailp->ail_lock); 186 187 error = xfs_qm_dqflush(dqp, &bp); 188 if (!error) { 189 if (!xfs_buf_delwri_queue(bp, buffer_list)) 190 rval = XFS_ITEM_FLUSHING; 191 xfs_buf_relse(bp); 192 } else if (error == -EAGAIN) 193 rval = XFS_ITEM_LOCKED; 194 195 spin_lock(&lip->li_ailp->ail_lock); 196 out_unlock: 197 xfs_dqunlock(dqp); 198 return rval; 199 } 200 201 STATIC void 202 xfs_qm_dquot_logitem_release( 203 struct xfs_log_item *lip) 204 { 205 struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; 206 207 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 208 209 /* 210 * dquots are never 'held' from getting unlocked at the end of 211 * a transaction. Their locking and unlocking is hidden inside the 212 * transaction layer, within trans_commit. Hence, no LI_HOLD flag 213 * for the logitem. 214 */ 215 xfs_dqunlock(dqp); 216 } 217 218 STATIC void 219 xfs_qm_dquot_logitem_committing( 220 struct xfs_log_item *lip, 221 xfs_lsn_t commit_lsn) 222 { 223 return xfs_qm_dquot_logitem_release(lip); 224 } 225 226 static const struct xfs_item_ops xfs_dquot_item_ops = { 227 .iop_size = xfs_qm_dquot_logitem_size, 228 .iop_format = xfs_qm_dquot_logitem_format, 229 .iop_pin = xfs_qm_dquot_logitem_pin, 230 .iop_unpin = xfs_qm_dquot_logitem_unpin, 231 .iop_release = xfs_qm_dquot_logitem_release, 232 .iop_committing = xfs_qm_dquot_logitem_committing, 233 .iop_push = xfs_qm_dquot_logitem_push, 234 .iop_error = xfs_dquot_item_error 235 }; 236 237 /* 238 * Initialize the dquot log item for a newly allocated dquot. 239 * The dquot isn't locked at this point, but it isn't on any of the lists 240 * either, so we don't care. 241 */ 242 void 243 xfs_qm_dquot_logitem_init( 244 struct xfs_dquot *dqp) 245 { 246 struct xfs_dq_logitem *lp = &dqp->q_logitem; 247 248 xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT, 249 &xfs_dquot_item_ops); 250 lp->qli_dquot = dqp; 251 } 252 253 /*------------------ QUOTAOFF LOG ITEMS -------------------*/ 254 255 static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip) 256 { 257 return container_of(lip, struct xfs_qoff_logitem, qql_item); 258 } 259 260 261 /* 262 * This returns the number of iovecs needed to log the given quotaoff item. 263 * We only need 1 iovec for an quotaoff item. It just logs the 264 * quotaoff_log_format structure. 265 */ 266 STATIC void 267 xfs_qm_qoff_logitem_size( 268 struct xfs_log_item *lip, 269 int *nvecs, 270 int *nbytes) 271 { 272 *nvecs += 1; 273 *nbytes += sizeof(struct xfs_qoff_logitem); 274 } 275 276 STATIC void 277 xfs_qm_qoff_logitem_format( 278 struct xfs_log_item *lip, 279 struct xfs_log_vec *lv) 280 { 281 struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); 282 struct xfs_log_iovec *vecp = NULL; 283 struct xfs_qoff_logformat *qlf; 284 285 qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF); 286 qlf->qf_type = XFS_LI_QUOTAOFF; 287 qlf->qf_size = 1; 288 qlf->qf_flags = qflip->qql_flags; 289 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_qoff_logitem)); 290 } 291 292 /* 293 * There isn't much you can do to push a quotaoff item. It is simply 294 * stuck waiting for the log to be flushed to disk. 295 */ 296 STATIC uint 297 xfs_qm_qoff_logitem_push( 298 struct xfs_log_item *lip, 299 struct list_head *buffer_list) 300 { 301 return XFS_ITEM_LOCKED; 302 } 303 304 STATIC xfs_lsn_t 305 xfs_qm_qoffend_logitem_committed( 306 struct xfs_log_item *lip, 307 xfs_lsn_t lsn) 308 { 309 struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip); 310 struct xfs_qoff_logitem *qfs = qfe->qql_start_lip; 311 312 xfs_qm_qoff_logitem_relse(qfs); 313 314 kmem_free(lip->li_lv_shadow); 315 kmem_free(qfe); 316 return (xfs_lsn_t)-1; 317 } 318 319 STATIC void 320 xfs_qm_qoff_logitem_release( 321 struct xfs_log_item *lip) 322 { 323 struct xfs_qoff_logitem *qoff = QOFF_ITEM(lip); 324 325 if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) { 326 if (qoff->qql_start_lip) 327 xfs_qm_qoff_logitem_relse(qoff->qql_start_lip); 328 xfs_qm_qoff_logitem_relse(qoff); 329 } 330 } 331 332 static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { 333 .iop_size = xfs_qm_qoff_logitem_size, 334 .iop_format = xfs_qm_qoff_logitem_format, 335 .iop_committed = xfs_qm_qoffend_logitem_committed, 336 .iop_push = xfs_qm_qoff_logitem_push, 337 .iop_release = xfs_qm_qoff_logitem_release, 338 }; 339 340 static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = { 341 .iop_size = xfs_qm_qoff_logitem_size, 342 .iop_format = xfs_qm_qoff_logitem_format, 343 .iop_push = xfs_qm_qoff_logitem_push, 344 .iop_release = xfs_qm_qoff_logitem_release, 345 }; 346 347 /* 348 * Delete the quotaoff intent from the AIL and free it. On success, 349 * this should only be called for the start item. It can be used for 350 * either on shutdown or abort. 351 */ 352 void 353 xfs_qm_qoff_logitem_relse( 354 struct xfs_qoff_logitem *qoff) 355 { 356 struct xfs_log_item *lip = &qoff->qql_item; 357 358 ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags) || 359 test_bit(XFS_LI_ABORTED, &lip->li_flags) || 360 XFS_FORCED_SHUTDOWN(lip->li_mountp)); 361 xfs_trans_ail_remove(lip, SHUTDOWN_LOG_IO_ERROR); 362 kmem_free(lip->li_lv_shadow); 363 kmem_free(qoff); 364 } 365 366 /* 367 * Allocate and initialize an quotaoff item of the correct quota type(s). 368 */ 369 struct xfs_qoff_logitem * 370 xfs_qm_qoff_logitem_init( 371 struct xfs_mount *mp, 372 struct xfs_qoff_logitem *start, 373 uint flags) 374 { 375 struct xfs_qoff_logitem *qf; 376 377 qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), 0); 378 379 xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ? 380 &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops); 381 qf->qql_item.li_mountp = mp; 382 qf->qql_start_lip = start; 383 qf->qql_flags = flags; 384 return qf; 385 } 386