10b61f8a4SDave Chinner // SPDX-License-Identifier: GPL-2.0 21da177e4SLinus Torvalds /* 37b718769SNathan Scott * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 4e98c414fSChristoph Hellwig * Copyright (C) 2010 Red Hat, Inc. 57b718769SNathan Scott * All Rights Reserved. 61da177e4SLinus Torvalds */ 71da177e4SLinus Torvalds #include "xfs.h" 8a844f451SNathan Scott #include "xfs_fs.h" 970a9883cSDave Chinner #include "xfs_shared.h" 10239880efSDave Chinner #include "xfs_format.h" 11239880efSDave Chinner #include "xfs_log_format.h" 12dd401770SDave Chinner #include "xfs_log_priv.h" 13239880efSDave Chinner #include "xfs_trans_resv.h" 141da177e4SLinus Torvalds #include "xfs_mount.h" 15efc27b52SDave Chinner #include "xfs_extent_busy.h" 161da177e4SLinus Torvalds #include "xfs_quota.h" 17239880efSDave Chinner #include "xfs_trans.h" 18a844f451SNathan Scott #include "xfs_trans_priv.h" 19239880efSDave Chinner #include "xfs_log.h" 20ed3b4d6cSDave Chinner #include "xfs_trace.h" 21a4fbe6abSDave Chinner #include "xfs_error.h" 22f8f2835aSBrian Foster #include "xfs_defer.h" 233a1af6c3SDarrick J. Wong #include "xfs_inode.h" 24f2f7b9ffSDarrick J. Wong #include "xfs_dquot_item.h" 25f2f7b9ffSDarrick J. Wong #include "xfs_dquot.h" 26766aabd5SDarrick J. Wong #include "xfs_icache.h" 271da177e4SLinus Torvalds 281da177e4SLinus Torvalds kmem_zone_t *xfs_trans_zone; 291da177e4SLinus Torvalds 30b872af2cSDarrick J. Wong #if defined(CONFIG_TRACEPOINTS) 31b872af2cSDarrick J. Wong static void 32b872af2cSDarrick J. Wong xfs_trans_trace_reservations( 33b872af2cSDarrick J. Wong struct xfs_mount *mp) 34b872af2cSDarrick J. Wong { 35b872af2cSDarrick J. Wong struct xfs_trans_res resv; 36b872af2cSDarrick J. Wong struct xfs_trans_res *res; 37b872af2cSDarrick J. Wong struct xfs_trans_res *end_res; 38b872af2cSDarrick J. Wong int i; 39b872af2cSDarrick J. Wong 40b872af2cSDarrick J. Wong res = (struct xfs_trans_res *)M_RES(mp); 41b872af2cSDarrick J. Wong end_res = (struct xfs_trans_res *)(M_RES(mp) + 1); 42b872af2cSDarrick J. Wong for (i = 0; res < end_res; i++, res++) 43b872af2cSDarrick J. Wong trace_xfs_trans_resv_calc(mp, i, res); 44b872af2cSDarrick J. Wong xfs_log_get_max_trans_res(mp, &resv); 45b872af2cSDarrick J. Wong trace_xfs_trans_resv_calc(mp, -1, &resv); 46b872af2cSDarrick J. Wong } 47b872af2cSDarrick J. Wong #else 48b872af2cSDarrick J. Wong # define xfs_trans_trace_reservations(mp) 49b872af2cSDarrick J. Wong #endif 50b872af2cSDarrick J. Wong 514f3b5783SJeff Liu /* 521da177e4SLinus Torvalds * Initialize the precomputed transaction reservation values 531da177e4SLinus Torvalds * in the mount structure. 541da177e4SLinus Torvalds */ 551da177e4SLinus Torvalds void 561da177e4SLinus Torvalds xfs_trans_init( 57025101dcSChristoph Hellwig struct xfs_mount *mp) 581da177e4SLinus Torvalds { 593d3c8b52SJie Liu xfs_trans_resv_calc(mp, M_RES(mp)); 60b872af2cSDarrick J. Wong xfs_trans_trace_reservations(mp); 611da177e4SLinus Torvalds } 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds /* 64b1c1b5b6SDave Chinner * Free the transaction structure. If there is more clean up 65b1c1b5b6SDave Chinner * to do when the structure is freed, add it here. 66b1c1b5b6SDave Chinner */ 67b1c1b5b6SDave Chinner STATIC void 68b1c1b5b6SDave Chinner xfs_trans_free( 69ed3b4d6cSDave Chinner struct xfs_trans *tp) 70b1c1b5b6SDave Chinner { 714ecbfe63SDave Chinner xfs_extent_busy_sort(&tp->t_busy); 724ecbfe63SDave Chinner xfs_extent_busy_clear(tp->t_mountp, &tp->t_busy, false); 73ed3b4d6cSDave Chinner 74ba18781bSDave Chinner trace_xfs_trans_free(tp, _RET_IP_); 75756b1c34SDave Chinner xfs_trans_clear_context(tp); 76253f4911SChristoph Hellwig if (!(tp->t_flags & XFS_TRANS_NO_WRITECOUNT)) 77d9457dc0SJan Kara sb_end_intwrite(tp->t_mountp->m_super); 78b1c1b5b6SDave Chinner xfs_trans_free_dqinfo(tp); 79377bcd5fSCarlos Maiolino kmem_cache_free(xfs_trans_zone, tp); 80b1c1b5b6SDave Chinner } 81b1c1b5b6SDave Chinner 82b1c1b5b6SDave Chinner /* 831da177e4SLinus Torvalds * This is called to create a new transaction which will share the 841da177e4SLinus Torvalds * permanent log reservation of the given transaction. The remaining 851da177e4SLinus Torvalds * unused block and rt extent reservations are also inherited. This 861da177e4SLinus Torvalds * implies that the original transaction is no longer allowed to allocate 871da177e4SLinus Torvalds * blocks. Locks and log items, however, are no inherited. They must 881da177e4SLinus Torvalds * be added to the new transaction explicitly. 891da177e4SLinus Torvalds */ 90f8f2835aSBrian Foster STATIC struct xfs_trans * 911da177e4SLinus Torvalds xfs_trans_dup( 92f8f2835aSBrian Foster struct xfs_trans *tp) 931da177e4SLinus Torvalds { 94f8f2835aSBrian Foster struct xfs_trans *ntp; 951da177e4SLinus Torvalds 96ba18781bSDave Chinner trace_xfs_trans_dup(tp, _RET_IP_); 97ba18781bSDave Chinner 9832a2b11fSCarlos Maiolino ntp = kmem_cache_zalloc(xfs_trans_zone, GFP_KERNEL | __GFP_NOFAIL); 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds /* 1011da177e4SLinus Torvalds * Initialize the new transaction structure. 1021da177e4SLinus Torvalds */ 1032a3c0accSDave Chinner ntp->t_magic = XFS_TRANS_HEADER_MAGIC; 1041da177e4SLinus Torvalds ntp->t_mountp = tp->t_mountp; 105e98c414fSChristoph Hellwig INIT_LIST_HEAD(&ntp->t_items); 106ed3b4d6cSDave Chinner INIT_LIST_HEAD(&ntp->t_busy); 1079d9e6233SBrian Foster INIT_LIST_HEAD(&ntp->t_dfops); 108bba59c5eSBrian Foster ntp->t_firstblock = NULLFSBLOCK; 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); 1111da177e4SLinus Torvalds ASSERT(tp->t_ticket != NULL); 112cfcbbbd0SNathan Scott 113d9457dc0SJan Kara ntp->t_flags = XFS_TRANS_PERM_LOG_RES | 114d9457dc0SJan Kara (tp->t_flags & XFS_TRANS_RESERVE) | 115f74681baSBrian Foster (tp->t_flags & XFS_TRANS_NO_WRITECOUNT) | 116f74681baSBrian Foster (tp->t_flags & XFS_TRANS_RES_FDBLKS); 117d9457dc0SJan Kara /* We gave our writer reference to the new transaction */ 118253f4911SChristoph Hellwig tp->t_flags |= XFS_TRANS_NO_WRITECOUNT; 119cc09c0dcSDave Chinner ntp->t_ticket = xfs_log_ticket_get(tp->t_ticket); 1203e78b9a4SBrian Foster 1213e78b9a4SBrian Foster ASSERT(tp->t_blk_res >= tp->t_blk_res_used); 1221da177e4SLinus Torvalds ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used; 1231da177e4SLinus Torvalds tp->t_blk_res = tp->t_blk_res_used; 1243e78b9a4SBrian Foster 1251da177e4SLinus Torvalds ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; 1261da177e4SLinus Torvalds tp->t_rtx_res = tp->t_rtx_res_used; 127756b1c34SDave Chinner 128756b1c34SDave Chinner xfs_trans_switch_context(tp, ntp); 129e021a2e5SBrian Foster 1309d9e6233SBrian Foster /* move deferred ops over to the new tp */ 131ce356d64SBrian Foster xfs_defer_move(ntp, tp); 1321da177e4SLinus Torvalds 1337d095257SChristoph Hellwig xfs_trans_dup_dqinfo(tp, ntp); 1341da177e4SLinus Torvalds return ntp; 1351da177e4SLinus Torvalds } 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds /* 1381da177e4SLinus Torvalds * This is called to reserve free disk blocks and log space for the 1391da177e4SLinus Torvalds * given transaction. This must be done before allocating any resources 1401da177e4SLinus Torvalds * within the transaction. 1411da177e4SLinus Torvalds * 1421da177e4SLinus Torvalds * This will return ENOSPC if there are not enough blocks available. 1431da177e4SLinus Torvalds * It will sleep waiting for available log space. 1441da177e4SLinus Torvalds * The only valid value for the flags parameter is XFS_RES_LOG_PERM, which 1451da177e4SLinus Torvalds * is used by long running transactions. If any one of the reservations 1461da177e4SLinus Torvalds * fails then they will all be backed out. 1471da177e4SLinus Torvalds * 1481da177e4SLinus Torvalds * This does not do quota reservations. That typically is done by the 1491da177e4SLinus Torvalds * caller afterwards. 1501da177e4SLinus Torvalds */ 151253f4911SChristoph Hellwig static int 1521da177e4SLinus Torvalds xfs_trans_reserve( 1533d3c8b52SJie Liu struct xfs_trans *tp, 1543d3c8b52SJie Liu struct xfs_trans_res *resp, 1551da177e4SLinus Torvalds uint blocks, 1563d3c8b52SJie Liu uint rtextents) 1571da177e4SLinus Torvalds { 158dd401770SDave Chinner struct xfs_mount *mp = tp->t_mountp; 15959c1b082SNathan Scott int error = 0; 1600d485adaSDave Chinner bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; 1611da177e4SLinus Torvalds 1621da177e4SLinus Torvalds /* 1631da177e4SLinus Torvalds * Attempt to reserve the needed disk blocks by decrementing 1641da177e4SLinus Torvalds * the number needed from the number available. This will 1651da177e4SLinus Torvalds * fail if the count would go below zero. 1661da177e4SLinus Torvalds */ 1671da177e4SLinus Torvalds if (blocks > 0) { 168dd401770SDave Chinner error = xfs_mod_fdblocks(mp, -((int64_t)blocks), rsvd); 169756b1c34SDave Chinner if (error != 0) 1702451337dSDave Chinner return -ENOSPC; 1711da177e4SLinus Torvalds tp->t_blk_res += blocks; 1721da177e4SLinus Torvalds } 1731da177e4SLinus Torvalds 1741da177e4SLinus Torvalds /* 1751da177e4SLinus Torvalds * Reserve the log space needed for this transaction. 1761da177e4SLinus Torvalds */ 1773d3c8b52SJie Liu if (resp->tr_logres > 0) { 1789006fb91SChristoph Hellwig bool permanent = false; 1799006fb91SChristoph Hellwig 1803d3c8b52SJie Liu ASSERT(tp->t_log_res == 0 || 1813d3c8b52SJie Liu tp->t_log_res == resp->tr_logres); 1823d3c8b52SJie Liu ASSERT(tp->t_log_count == 0 || 1833d3c8b52SJie Liu tp->t_log_count == resp->tr_logcount); 1849006fb91SChristoph Hellwig 1853d3c8b52SJie Liu if (resp->tr_logflags & XFS_TRANS_PERM_LOG_RES) { 1861da177e4SLinus Torvalds tp->t_flags |= XFS_TRANS_PERM_LOG_RES; 1879006fb91SChristoph Hellwig permanent = true; 1881da177e4SLinus Torvalds } else { 1891da177e4SLinus Torvalds ASSERT(tp->t_ticket == NULL); 1901da177e4SLinus Torvalds ASSERT(!(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); 1911da177e4SLinus Torvalds } 1921da177e4SLinus Torvalds 1939006fb91SChristoph Hellwig if (tp->t_ticket != NULL) { 1943d3c8b52SJie Liu ASSERT(resp->tr_logflags & XFS_TRANS_PERM_LOG_RES); 195dd401770SDave Chinner error = xfs_log_regrant(mp, tp->t_ticket); 1969006fb91SChristoph Hellwig } else { 197dd401770SDave Chinner error = xfs_log_reserve(mp, 1983d3c8b52SJie Liu resp->tr_logres, 1993d3c8b52SJie Liu resp->tr_logcount, 2003d3c8b52SJie Liu &tp->t_ticket, XFS_TRANSACTION, 201710b1e2cSChristoph Hellwig permanent); 2021da177e4SLinus Torvalds } 2039006fb91SChristoph Hellwig 2049006fb91SChristoph Hellwig if (error) 2059006fb91SChristoph Hellwig goto undo_blocks; 2069006fb91SChristoph Hellwig 2073d3c8b52SJie Liu tp->t_log_res = resp->tr_logres; 2083d3c8b52SJie Liu tp->t_log_count = resp->tr_logcount; 2091da177e4SLinus Torvalds } 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds /* 2121da177e4SLinus Torvalds * Attempt to reserve the needed realtime extents by decrementing 2131da177e4SLinus Torvalds * the number needed from the number available. This will 2141da177e4SLinus Torvalds * fail if the count would go below zero. 2151da177e4SLinus Torvalds */ 2161da177e4SLinus Torvalds if (rtextents > 0) { 217dd401770SDave Chinner error = xfs_mod_frextents(mp, -((int64_t)rtextents)); 2181da177e4SLinus Torvalds if (error) { 2192451337dSDave Chinner error = -ENOSPC; 2201da177e4SLinus Torvalds goto undo_log; 2211da177e4SLinus Torvalds } 2221da177e4SLinus Torvalds tp->t_rtx_res += rtextents; 2231da177e4SLinus Torvalds } 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds return 0; 2261da177e4SLinus Torvalds 2271da177e4SLinus Torvalds /* 2281da177e4SLinus Torvalds * Error cases jump to one of these labels to undo any 2291da177e4SLinus Torvalds * reservations which have already been performed. 2301da177e4SLinus Torvalds */ 2311da177e4SLinus Torvalds undo_log: 2323d3c8b52SJie Liu if (resp->tr_logres > 0) { 2338b41e3f9SChristoph Hellwig xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket); 2341da177e4SLinus Torvalds tp->t_ticket = NULL; 2351da177e4SLinus Torvalds tp->t_log_res = 0; 2361da177e4SLinus Torvalds tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES; 2371da177e4SLinus Torvalds } 2381da177e4SLinus Torvalds 2391da177e4SLinus Torvalds undo_blocks: 2401da177e4SLinus Torvalds if (blocks > 0) { 241dd401770SDave Chinner xfs_mod_fdblocks(mp, (int64_t)blocks, rsvd); 2421da177e4SLinus Torvalds tp->t_blk_res = 0; 2431da177e4SLinus Torvalds } 24459c1b082SNathan Scott return error; 2451da177e4SLinus Torvalds } 2461da177e4SLinus Torvalds 247253f4911SChristoph Hellwig int 248253f4911SChristoph Hellwig xfs_trans_alloc( 249253f4911SChristoph Hellwig struct xfs_mount *mp, 250253f4911SChristoph Hellwig struct xfs_trans_res *resp, 251253f4911SChristoph Hellwig uint blocks, 252253f4911SChristoph Hellwig uint rtextents, 253253f4911SChristoph Hellwig uint flags, 254253f4911SChristoph Hellwig struct xfs_trans **tpp) 255253f4911SChristoph Hellwig { 256253f4911SChristoph Hellwig struct xfs_trans *tp; 2579febcda6SDarrick J. Wong bool want_retry = true; 258253f4911SChristoph Hellwig int error; 259253f4911SChristoph Hellwig 2608683edb7SDave Chinner /* 2618683edb7SDave Chinner * Allocate the handle before we do our freeze accounting and setting up 2628683edb7SDave Chinner * GFP_NOFS allocation context so that we avoid lockdep false positives 2638683edb7SDave Chinner * by doing GFP_KERNEL allocations inside sb_start_intwrite(). 2648683edb7SDave Chinner */ 2659febcda6SDarrick J. Wong retry: 26632a2b11fSCarlos Maiolino tp = kmem_cache_zalloc(xfs_trans_zone, GFP_KERNEL | __GFP_NOFAIL); 267253f4911SChristoph Hellwig if (!(flags & XFS_TRANS_NO_WRITECOUNT)) 268253f4911SChristoph Hellwig sb_start_intwrite(mp->m_super); 269756b1c34SDave Chinner xfs_trans_set_context(tp); 270253f4911SChristoph Hellwig 27110ee2526SDarrick J. Wong /* 27210ee2526SDarrick J. Wong * Zero-reservation ("empty") transactions can't modify anything, so 27310ee2526SDarrick J. Wong * they're allowed to run while we're frozen. 27410ee2526SDarrick J. Wong */ 27510ee2526SDarrick J. Wong WARN_ON(resp->tr_logres > 0 && 27610ee2526SDarrick J. Wong mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE); 277f74681baSBrian Foster ASSERT(!(flags & XFS_TRANS_RES_FDBLKS) || 278f74681baSBrian Foster xfs_sb_version_haslazysbcount(&mp->m_sb)); 279253f4911SChristoph Hellwig 280253f4911SChristoph Hellwig tp->t_magic = XFS_TRANS_HEADER_MAGIC; 281253f4911SChristoph Hellwig tp->t_flags = flags; 282253f4911SChristoph Hellwig tp->t_mountp = mp; 283253f4911SChristoph Hellwig INIT_LIST_HEAD(&tp->t_items); 284253f4911SChristoph Hellwig INIT_LIST_HEAD(&tp->t_busy); 2859d9e6233SBrian Foster INIT_LIST_HEAD(&tp->t_dfops); 286bba59c5eSBrian Foster tp->t_firstblock = NULLFSBLOCK; 287253f4911SChristoph Hellwig 288253f4911SChristoph Hellwig error = xfs_trans_reserve(tp, resp, blocks, rtextents); 2899febcda6SDarrick J. Wong if (error == -ENOSPC && want_retry) { 2909febcda6SDarrick J. Wong xfs_trans_cancel(tp); 2919febcda6SDarrick J. Wong 292a1a7d05aSDarrick J. Wong /* 293a1a7d05aSDarrick J. Wong * We weren't able to reserve enough space for the transaction. 294a1a7d05aSDarrick J. Wong * Flush the other speculative space allocations to free space. 295a1a7d05aSDarrick J. Wong * Do not perform a synchronous scan because callers can hold 296a1a7d05aSDarrick J. Wong * other locks. 297a1a7d05aSDarrick J. Wong */ 298a1a7d05aSDarrick J. Wong error = xfs_blockgc_free_space(mp, NULL); 2999febcda6SDarrick J. Wong if (error) 3009febcda6SDarrick J. Wong return error; 3019febcda6SDarrick J. Wong 3029febcda6SDarrick J. Wong want_retry = false; 3039febcda6SDarrick J. Wong goto retry; 304a1a7d05aSDarrick J. Wong } 305253f4911SChristoph Hellwig if (error) { 306253f4911SChristoph Hellwig xfs_trans_cancel(tp); 307253f4911SChristoph Hellwig return error; 308253f4911SChristoph Hellwig } 309253f4911SChristoph Hellwig 310ba18781bSDave Chinner trace_xfs_trans_alloc(tp, _RET_IP_); 311ba18781bSDave Chinner 312253f4911SChristoph Hellwig *tpp = tp; 313253f4911SChristoph Hellwig return 0; 314253f4911SChristoph Hellwig } 315253f4911SChristoph Hellwig 3161da177e4SLinus Torvalds /* 317e89c0413SDarrick J. Wong * Create an empty transaction with no reservation. This is a defensive 318b41b46c2SDave Chinner * mechanism for routines that query metadata without actually modifying them -- 319b41b46c2SDave Chinner * if the metadata being queried is somehow cross-linked (think a btree block 320b41b46c2SDave Chinner * pointer that points higher in the tree), we risk deadlock. However, blocks 321b41b46c2SDave Chinner * grabbed as part of a transaction can be re-grabbed. The verifiers will 322b41b46c2SDave Chinner * notice the corrupt block and the operation will fail back to userspace 323b41b46c2SDave Chinner * without deadlocking. 324e89c0413SDarrick J. Wong * 325b41b46c2SDave Chinner * Note the zero-length reservation; this transaction MUST be cancelled without 326b41b46c2SDave Chinner * any dirty data. 32727fb5a72SDarrick J. Wong * 328b41b46c2SDave Chinner * Callers should obtain freeze protection to avoid a conflict with fs freezing 329b41b46c2SDave Chinner * where we can be grabbing buffers at the same time that freeze is trying to 330b41b46c2SDave Chinner * drain the buffer LRU list. 331e89c0413SDarrick J. Wong */ 332e89c0413SDarrick J. Wong int 333e89c0413SDarrick J. Wong xfs_trans_alloc_empty( 334e89c0413SDarrick J. Wong struct xfs_mount *mp, 335e89c0413SDarrick J. Wong struct xfs_trans **tpp) 336e89c0413SDarrick J. Wong { 337e89c0413SDarrick J. Wong struct xfs_trans_res resv = {0}; 338e89c0413SDarrick J. Wong 339e89c0413SDarrick J. Wong return xfs_trans_alloc(mp, &resv, 0, 0, XFS_TRANS_NO_WRITECOUNT, tpp); 340e89c0413SDarrick J. Wong } 341e89c0413SDarrick J. Wong 342e89c0413SDarrick J. Wong /* 3431da177e4SLinus Torvalds * Record the indicated change to the given field for application 3441da177e4SLinus Torvalds * to the file system's superblock when the transaction commits. 3451da177e4SLinus Torvalds * For now, just store the change in the transaction structure. 3461da177e4SLinus Torvalds * 3471da177e4SLinus Torvalds * Mark the transaction structure to indicate that the superblock 3481da177e4SLinus Torvalds * needs to be updated before committing. 34992821e2bSDavid Chinner * 35092821e2bSDavid Chinner * Because we may not be keeping track of allocated/free inodes and 35192821e2bSDavid Chinner * used filesystem blocks in the superblock, we do not mark the 35292821e2bSDavid Chinner * superblock dirty in this transaction if we modify these fields. 35392821e2bSDavid Chinner * We still need to update the transaction deltas so that they get 35492821e2bSDavid Chinner * applied to the incore superblock, but we don't want them to 35592821e2bSDavid Chinner * cause the superblock to get locked and logged if these are the 35692821e2bSDavid Chinner * only fields in the superblock that the transaction modifies. 3571da177e4SLinus Torvalds */ 3581da177e4SLinus Torvalds void 3591da177e4SLinus Torvalds xfs_trans_mod_sb( 3601da177e4SLinus Torvalds xfs_trans_t *tp, 3611da177e4SLinus Torvalds uint field, 36220f4ebf2SDavid Chinner int64_t delta) 3631da177e4SLinus Torvalds { 36492821e2bSDavid Chinner uint32_t flags = (XFS_TRANS_DIRTY|XFS_TRANS_SB_DIRTY); 36592821e2bSDavid Chinner xfs_mount_t *mp = tp->t_mountp; 3661da177e4SLinus Torvalds 3671da177e4SLinus Torvalds switch (field) { 3681da177e4SLinus Torvalds case XFS_TRANS_SB_ICOUNT: 3691da177e4SLinus Torvalds tp->t_icount_delta += delta; 37092821e2bSDavid Chinner if (xfs_sb_version_haslazysbcount(&mp->m_sb)) 37192821e2bSDavid Chinner flags &= ~XFS_TRANS_SB_DIRTY; 3721da177e4SLinus Torvalds break; 3731da177e4SLinus Torvalds case XFS_TRANS_SB_IFREE: 3741da177e4SLinus Torvalds tp->t_ifree_delta += delta; 37592821e2bSDavid Chinner if (xfs_sb_version_haslazysbcount(&mp->m_sb)) 37692821e2bSDavid Chinner flags &= ~XFS_TRANS_SB_DIRTY; 3771da177e4SLinus Torvalds break; 3781da177e4SLinus Torvalds case XFS_TRANS_SB_FDBLOCKS: 3791da177e4SLinus Torvalds /* 3803e78b9a4SBrian Foster * Track the number of blocks allocated in the transaction. 3813e78b9a4SBrian Foster * Make sure it does not exceed the number reserved. If so, 3823e78b9a4SBrian Foster * shutdown as this can lead to accounting inconsistency. 3831da177e4SLinus Torvalds */ 3841da177e4SLinus Torvalds if (delta < 0) { 3851da177e4SLinus Torvalds tp->t_blk_res_used += (uint)-delta; 3863e78b9a4SBrian Foster if (tp->t_blk_res_used > tp->t_blk_res) 3873e78b9a4SBrian Foster xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 388f74681baSBrian Foster } else if (delta > 0 && (tp->t_flags & XFS_TRANS_RES_FDBLKS)) { 389f74681baSBrian Foster int64_t blkres_delta; 390f74681baSBrian Foster 391f74681baSBrian Foster /* 392f74681baSBrian Foster * Return freed blocks directly to the reservation 393f74681baSBrian Foster * instead of the global pool, being careful not to 394f74681baSBrian Foster * overflow the trans counter. This is used to preserve 395f74681baSBrian Foster * reservation across chains of transaction rolls that 396f74681baSBrian Foster * repeatedly free and allocate blocks. 397f74681baSBrian Foster */ 398f74681baSBrian Foster blkres_delta = min_t(int64_t, delta, 399f74681baSBrian Foster UINT_MAX - tp->t_blk_res); 400f74681baSBrian Foster tp->t_blk_res += blkres_delta; 401f74681baSBrian Foster delta -= blkres_delta; 4021da177e4SLinus Torvalds } 4031da177e4SLinus Torvalds tp->t_fdblocks_delta += delta; 40492821e2bSDavid Chinner if (xfs_sb_version_haslazysbcount(&mp->m_sb)) 40592821e2bSDavid Chinner flags &= ~XFS_TRANS_SB_DIRTY; 4061da177e4SLinus Torvalds break; 4071da177e4SLinus Torvalds case XFS_TRANS_SB_RES_FDBLOCKS: 4081da177e4SLinus Torvalds /* 4091da177e4SLinus Torvalds * The allocation has already been applied to the 4101da177e4SLinus Torvalds * in-core superblock's counter. This should only 4111da177e4SLinus Torvalds * be applied to the on-disk superblock. 4121da177e4SLinus Torvalds */ 4131da177e4SLinus Torvalds tp->t_res_fdblocks_delta += delta; 41492821e2bSDavid Chinner if (xfs_sb_version_haslazysbcount(&mp->m_sb)) 41592821e2bSDavid Chinner flags &= ~XFS_TRANS_SB_DIRTY; 4161da177e4SLinus Torvalds break; 4171da177e4SLinus Torvalds case XFS_TRANS_SB_FREXTENTS: 4181da177e4SLinus Torvalds /* 4191da177e4SLinus Torvalds * Track the number of blocks allocated in the 4201da177e4SLinus Torvalds * transaction. Make sure it does not exceed the 4211da177e4SLinus Torvalds * number reserved. 4221da177e4SLinus Torvalds */ 4231da177e4SLinus Torvalds if (delta < 0) { 4241da177e4SLinus Torvalds tp->t_rtx_res_used += (uint)-delta; 4251da177e4SLinus Torvalds ASSERT(tp->t_rtx_res_used <= tp->t_rtx_res); 4261da177e4SLinus Torvalds } 4271da177e4SLinus Torvalds tp->t_frextents_delta += delta; 4281da177e4SLinus Torvalds break; 4291da177e4SLinus Torvalds case XFS_TRANS_SB_RES_FREXTENTS: 4301da177e4SLinus Torvalds /* 4311da177e4SLinus Torvalds * The allocation has already been applied to the 432c41564b5SNathan Scott * in-core superblock's counter. This should only 4331da177e4SLinus Torvalds * be applied to the on-disk superblock. 4341da177e4SLinus Torvalds */ 4351da177e4SLinus Torvalds ASSERT(delta < 0); 4361da177e4SLinus Torvalds tp->t_res_frextents_delta += delta; 4371da177e4SLinus Torvalds break; 4381da177e4SLinus Torvalds case XFS_TRANS_SB_DBLOCKS: 4391da177e4SLinus Torvalds ASSERT(delta > 0); 4401da177e4SLinus Torvalds tp->t_dblocks_delta += delta; 4411da177e4SLinus Torvalds break; 4421da177e4SLinus Torvalds case XFS_TRANS_SB_AGCOUNT: 4431da177e4SLinus Torvalds ASSERT(delta > 0); 4441da177e4SLinus Torvalds tp->t_agcount_delta += delta; 4451da177e4SLinus Torvalds break; 4461da177e4SLinus Torvalds case XFS_TRANS_SB_IMAXPCT: 4471da177e4SLinus Torvalds tp->t_imaxpct_delta += delta; 4481da177e4SLinus Torvalds break; 4491da177e4SLinus Torvalds case XFS_TRANS_SB_REXTSIZE: 4501da177e4SLinus Torvalds tp->t_rextsize_delta += delta; 4511da177e4SLinus Torvalds break; 4521da177e4SLinus Torvalds case XFS_TRANS_SB_RBMBLOCKS: 4531da177e4SLinus Torvalds tp->t_rbmblocks_delta += delta; 4541da177e4SLinus Torvalds break; 4551da177e4SLinus Torvalds case XFS_TRANS_SB_RBLOCKS: 4561da177e4SLinus Torvalds tp->t_rblocks_delta += delta; 4571da177e4SLinus Torvalds break; 4581da177e4SLinus Torvalds case XFS_TRANS_SB_REXTENTS: 4591da177e4SLinus Torvalds tp->t_rextents_delta += delta; 4601da177e4SLinus Torvalds break; 4611da177e4SLinus Torvalds case XFS_TRANS_SB_REXTSLOG: 4621da177e4SLinus Torvalds tp->t_rextslog_delta += delta; 4631da177e4SLinus Torvalds break; 4641da177e4SLinus Torvalds default: 4651da177e4SLinus Torvalds ASSERT(0); 4661da177e4SLinus Torvalds return; 4671da177e4SLinus Torvalds } 4681da177e4SLinus Torvalds 469210c6f1cSDavid Chinner tp->t_flags |= flags; 4701da177e4SLinus Torvalds } 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds /* 4731da177e4SLinus Torvalds * xfs_trans_apply_sb_deltas() is called from the commit code 4741da177e4SLinus Torvalds * to bring the superblock buffer into the current transaction 4751da177e4SLinus Torvalds * and modify it as requested by earlier calls to xfs_trans_mod_sb(). 4761da177e4SLinus Torvalds * 4771da177e4SLinus Torvalds * For now we just look at each field allowed to change and change 4781da177e4SLinus Torvalds * it if necessary. 4791da177e4SLinus Torvalds */ 4801da177e4SLinus Torvalds STATIC void 4811da177e4SLinus Torvalds xfs_trans_apply_sb_deltas( 4821da177e4SLinus Torvalds xfs_trans_t *tp) 4831da177e4SLinus Torvalds { 4842bdf7cd0SChristoph Hellwig xfs_dsb_t *sbp; 485e8222613SDave Chinner struct xfs_buf *bp; 4861da177e4SLinus Torvalds int whole = 0; 4871da177e4SLinus Torvalds 488cead0b10SChristoph Hellwig bp = xfs_trans_getsb(tp); 4893e6e8afdSChristoph Hellwig sbp = bp->b_addr; 4901da177e4SLinus Torvalds 4911da177e4SLinus Torvalds /* 4921da177e4SLinus Torvalds * Check that superblock mods match the mods made to AGF counters. 4931da177e4SLinus Torvalds */ 4941da177e4SLinus Torvalds ASSERT((tp->t_fdblocks_delta + tp->t_res_fdblocks_delta) == 4951da177e4SLinus Torvalds (tp->t_ag_freeblks_delta + tp->t_ag_flist_delta + 4961da177e4SLinus Torvalds tp->t_ag_btree_delta)); 4971da177e4SLinus Torvalds 49892821e2bSDavid Chinner /* 49992821e2bSDavid Chinner * Only update the superblock counters if we are logging them 50092821e2bSDavid Chinner */ 50192821e2bSDavid Chinner if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { 5022bdf7cd0SChristoph Hellwig if (tp->t_icount_delta) 503413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta); 5042bdf7cd0SChristoph Hellwig if (tp->t_ifree_delta) 505413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta); 5062bdf7cd0SChristoph Hellwig if (tp->t_fdblocks_delta) 507413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta); 5082bdf7cd0SChristoph Hellwig if (tp->t_res_fdblocks_delta) 509413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta); 5101da177e4SLinus Torvalds } 5111da177e4SLinus Torvalds 5122bdf7cd0SChristoph Hellwig if (tp->t_frextents_delta) 513413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta); 5142bdf7cd0SChristoph Hellwig if (tp->t_res_frextents_delta) 515413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta); 5161da177e4SLinus Torvalds 5172bdf7cd0SChristoph Hellwig if (tp->t_dblocks_delta) { 518413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta); 5191da177e4SLinus Torvalds whole = 1; 5201da177e4SLinus Torvalds } 5212bdf7cd0SChristoph Hellwig if (tp->t_agcount_delta) { 522413d57c9SMarcin Slusarz be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta); 5231da177e4SLinus Torvalds whole = 1; 5241da177e4SLinus Torvalds } 5252bdf7cd0SChristoph Hellwig if (tp->t_imaxpct_delta) { 5262bdf7cd0SChristoph Hellwig sbp->sb_imax_pct += tp->t_imaxpct_delta; 5271da177e4SLinus Torvalds whole = 1; 5281da177e4SLinus Torvalds } 5292bdf7cd0SChristoph Hellwig if (tp->t_rextsize_delta) { 530413d57c9SMarcin Slusarz be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta); 5311da177e4SLinus Torvalds whole = 1; 5321da177e4SLinus Torvalds } 5332bdf7cd0SChristoph Hellwig if (tp->t_rbmblocks_delta) { 534413d57c9SMarcin Slusarz be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta); 5351da177e4SLinus Torvalds whole = 1; 5361da177e4SLinus Torvalds } 5372bdf7cd0SChristoph Hellwig if (tp->t_rblocks_delta) { 538413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta); 5391da177e4SLinus Torvalds whole = 1; 5401da177e4SLinus Torvalds } 5412bdf7cd0SChristoph Hellwig if (tp->t_rextents_delta) { 542413d57c9SMarcin Slusarz be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta); 5431da177e4SLinus Torvalds whole = 1; 5441da177e4SLinus Torvalds } 5452bdf7cd0SChristoph Hellwig if (tp->t_rextslog_delta) { 5462bdf7cd0SChristoph Hellwig sbp->sb_rextslog += tp->t_rextslog_delta; 5471da177e4SLinus Torvalds whole = 1; 5481da177e4SLinus Torvalds } 5491da177e4SLinus Torvalds 5503443a3bcSDave Chinner xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); 5511da177e4SLinus Torvalds if (whole) 5521da177e4SLinus Torvalds /* 553c41564b5SNathan Scott * Log the whole thing, the fields are noncontiguous. 5541da177e4SLinus Torvalds */ 5552bdf7cd0SChristoph Hellwig xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1); 5561da177e4SLinus Torvalds else 5571da177e4SLinus Torvalds /* 5581da177e4SLinus Torvalds * Since all the modifiable fields are contiguous, we 5591da177e4SLinus Torvalds * can get away with this. 5601da177e4SLinus Torvalds */ 5612bdf7cd0SChristoph Hellwig xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount), 5622bdf7cd0SChristoph Hellwig offsetof(xfs_dsb_t, sb_frextents) + 5631da177e4SLinus Torvalds sizeof(sbp->sb_frextents) - 1); 5641da177e4SLinus Torvalds } 5651da177e4SLinus Torvalds 5661da177e4SLinus Torvalds /* 567dc3ffbb1SDave Chinner * xfs_trans_unreserve_and_mod_sb() is called to release unused reservations and 568dc3ffbb1SDave Chinner * apply superblock counter changes to the in-core superblock. The 56945c34141SDavid Chinner * t_res_fdblocks_delta and t_res_frextents_delta fields are explicitly NOT 57045c34141SDavid Chinner * applied to the in-core superblock. The idea is that that has already been 57145c34141SDavid Chinner * done. 5721da177e4SLinus Torvalds * 57345c34141SDavid Chinner * If we are not logging superblock counters, then the inode allocated/free and 57445c34141SDavid Chinner * used block counts are not updated in the on disk superblock. In this case, 57545c34141SDavid Chinner * XFS_TRANS_SB_DIRTY will not be set when the transaction is updated but we 57645c34141SDavid Chinner * still need to update the incore superblock with the changes. 577f18c9a90SDave Chinner * 578f18c9a90SDave Chinner * Deltas for the inode count are +/-64, hence we use a large batch size of 128 579f18c9a90SDave Chinner * so we don't need to take the counter lock on every update. 5801da177e4SLinus Torvalds */ 581f18c9a90SDave Chinner #define XFS_ICOUNT_BATCH 128 582f18c9a90SDave Chinner 58371e330b5SDave Chinner void 5841da177e4SLinus Torvalds xfs_trans_unreserve_and_mod_sb( 5850bd5ddedSDave Chinner struct xfs_trans *tp) 5861da177e4SLinus Torvalds { 5870bd5ddedSDave Chinner struct xfs_mount *mp = tp->t_mountp; 5880d485adaSDave Chinner bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; 58945c34141SDavid Chinner int64_t blkdelta = 0; 59045c34141SDavid Chinner int64_t rtxdelta = 0; 5911b040712SChristoph Hellwig int64_t idelta = 0; 5921b040712SChristoph Hellwig int64_t ifreedelta = 0; 5930bd5ddedSDave Chinner int error; 5941da177e4SLinus Torvalds 5951b040712SChristoph Hellwig /* calculate deltas */ 59645c34141SDavid Chinner if (tp->t_blk_res > 0) 59745c34141SDavid Chinner blkdelta = tp->t_blk_res; 59845c34141SDavid Chinner if ((tp->t_fdblocks_delta != 0) && 59945c34141SDavid Chinner (xfs_sb_version_haslazysbcount(&mp->m_sb) || 60045c34141SDavid Chinner (tp->t_flags & XFS_TRANS_SB_DIRTY))) 60145c34141SDavid Chinner blkdelta += tp->t_fdblocks_delta; 60245c34141SDavid Chinner 60345c34141SDavid Chinner if (tp->t_rtx_res > 0) 60445c34141SDavid Chinner rtxdelta = tp->t_rtx_res; 60545c34141SDavid Chinner if ((tp->t_frextents_delta != 0) && 60645c34141SDavid Chinner (tp->t_flags & XFS_TRANS_SB_DIRTY)) 60745c34141SDavid Chinner rtxdelta += tp->t_frextents_delta; 60845c34141SDavid Chinner 6091b040712SChristoph Hellwig if (xfs_sb_version_haslazysbcount(&mp->m_sb) || 6101b040712SChristoph Hellwig (tp->t_flags & XFS_TRANS_SB_DIRTY)) { 6111b040712SChristoph Hellwig idelta = tp->t_icount_delta; 6121b040712SChristoph Hellwig ifreedelta = tp->t_ifree_delta; 6131b040712SChristoph Hellwig } 6141b040712SChristoph Hellwig 6151b040712SChristoph Hellwig /* apply the per-cpu counters */ 6161b040712SChristoph Hellwig if (blkdelta) { 6170d485adaSDave Chinner error = xfs_mod_fdblocks(mp, blkdelta, rsvd); 618dc3ffbb1SDave Chinner ASSERT(!error); 6191b040712SChristoph Hellwig } 6201b040712SChristoph Hellwig 621*5825bea0SDave Chinner if (idelta) 622f18c9a90SDave Chinner percpu_counter_add_batch(&mp->m_icount, idelta, 623f18c9a90SDave Chinner XFS_ICOUNT_BATCH); 6241b040712SChristoph Hellwig 625*5825bea0SDave Chinner if (ifreedelta) 626f18c9a90SDave Chinner percpu_counter_add(&mp->m_ifree, ifreedelta); 6271b040712SChristoph Hellwig 6280bd5ddedSDave Chinner if (rtxdelta == 0 && !(tp->t_flags & XFS_TRANS_SB_DIRTY)) 6290bd5ddedSDave Chinner return; 6300bd5ddedSDave Chinner 6311b040712SChristoph Hellwig /* apply remaining deltas */ 6320bd5ddedSDave Chinner spin_lock(&mp->m_sb_lock); 633dc3ffbb1SDave Chinner mp->m_sb.sb_frextents += rtxdelta; 634dc3ffbb1SDave Chinner mp->m_sb.sb_dblocks += tp->t_dblocks_delta; 635dc3ffbb1SDave Chinner mp->m_sb.sb_agcount += tp->t_agcount_delta; 636dc3ffbb1SDave Chinner mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta; 637dc3ffbb1SDave Chinner mp->m_sb.sb_rextsize += tp->t_rextsize_delta; 638dc3ffbb1SDave Chinner mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta; 639dc3ffbb1SDave Chinner mp->m_sb.sb_rblocks += tp->t_rblocks_delta; 640dc3ffbb1SDave Chinner mp->m_sb.sb_rextents += tp->t_rextents_delta; 641dc3ffbb1SDave Chinner mp->m_sb.sb_rextslog += tp->t_rextslog_delta; 6420bd5ddedSDave Chinner spin_unlock(&mp->m_sb_lock); 6431b040712SChristoph Hellwig 644dc3ffbb1SDave Chinner /* 645dc3ffbb1SDave Chinner * Debug checks outside of the spinlock so they don't lock up the 646dc3ffbb1SDave Chinner * machine if they fail. 647dc3ffbb1SDave Chinner */ 648dc3ffbb1SDave Chinner ASSERT(mp->m_sb.sb_imax_pct >= 0); 649dc3ffbb1SDave Chinner ASSERT(mp->m_sb.sb_rextslog >= 0); 6501b040712SChristoph Hellwig return; 6511da177e4SLinus Torvalds } 6521da177e4SLinus Torvalds 653e6631f85SDave Chinner /* Add the given log item to the transaction's list of log items. */ 654e98c414fSChristoph Hellwig void 655e98c414fSChristoph Hellwig xfs_trans_add_item( 656e98c414fSChristoph Hellwig struct xfs_trans *tp, 657e98c414fSChristoph Hellwig struct xfs_log_item *lip) 658e98c414fSChristoph Hellwig { 659f65020a8SJesper Juhl ASSERT(lip->li_mountp == tp->t_mountp); 660f65020a8SJesper Juhl ASSERT(lip->li_ailp == tp->t_mountp->m_ail); 661e6631f85SDave Chinner ASSERT(list_empty(&lip->li_trans)); 662e6631f85SDave Chinner ASSERT(!test_bit(XFS_LI_DIRTY, &lip->li_flags)); 663e98c414fSChristoph Hellwig 664e6631f85SDave Chinner list_add_tail(&lip->li_trans, &tp->t_items); 665ba18781bSDave Chinner trace_xfs_trans_add_item(tp, _RET_IP_); 666e98c414fSChristoph Hellwig } 667e98c414fSChristoph Hellwig 668e98c414fSChristoph Hellwig /* 669e6631f85SDave Chinner * Unlink the log item from the transaction. the log item is no longer 670e6631f85SDave Chinner * considered dirty in this transaction, as the linked transaction has 671e6631f85SDave Chinner * finished, either by abort or commit completion. 672e98c414fSChristoph Hellwig */ 673e98c414fSChristoph Hellwig void 674e98c414fSChristoph Hellwig xfs_trans_del_item( 675e98c414fSChristoph Hellwig struct xfs_log_item *lip) 676e98c414fSChristoph Hellwig { 677e6631f85SDave Chinner clear_bit(XFS_LI_DIRTY, &lip->li_flags); 678e6631f85SDave Chinner list_del_init(&lip->li_trans); 679e98c414fSChristoph Hellwig } 680e98c414fSChristoph Hellwig 681e6631f85SDave Chinner /* Detach and unlock all of the items in a transaction */ 682195cd83dSChristoph Hellwig static void 683e98c414fSChristoph Hellwig xfs_trans_free_items( 684e98c414fSChristoph Hellwig struct xfs_trans *tp, 685eacb24e7SChristoph Hellwig bool abort) 686e98c414fSChristoph Hellwig { 687e6631f85SDave Chinner struct xfs_log_item *lip, *next; 688e98c414fSChristoph Hellwig 689ba18781bSDave Chinner trace_xfs_trans_free_items(tp, _RET_IP_); 690ba18781bSDave Chinner 691e6631f85SDave Chinner list_for_each_entry_safe(lip, next, &tp->t_items, li_trans) { 692e6631f85SDave Chinner xfs_trans_del_item(lip); 693eacb24e7SChristoph Hellwig if (abort) 69422525c17SDave Chinner set_bit(XFS_LI_ABORTED, &lip->li_flags); 695ddf92053SChristoph Hellwig if (lip->li_ops->iop_release) 696ddf92053SChristoph Hellwig lip->li_ops->iop_release(lip); 697e98c414fSChristoph Hellwig } 698e98c414fSChristoph Hellwig } 699e98c414fSChristoph Hellwig 7000e57f6a3SDave Chinner static inline void 7010e57f6a3SDave Chinner xfs_log_item_batch_insert( 7020e57f6a3SDave Chinner struct xfs_ail *ailp, 7031d8c95a3SDave Chinner struct xfs_ail_cursor *cur, 7040e57f6a3SDave Chinner struct xfs_log_item **log_items, 7050e57f6a3SDave Chinner int nr_items, 7060e57f6a3SDave Chinner xfs_lsn_t commit_lsn) 7070e57f6a3SDave Chinner { 7080e57f6a3SDave Chinner int i; 7090e57f6a3SDave Chinner 71057e80956SMatthew Wilcox spin_lock(&ailp->ail_lock); 71157e80956SMatthew Wilcox /* xfs_trans_ail_update_bulk drops ailp->ail_lock */ 7121d8c95a3SDave Chinner xfs_trans_ail_update_bulk(ailp, cur, log_items, nr_items, commit_lsn); 7130e57f6a3SDave Chinner 714904c17e6SDave Chinner for (i = 0; i < nr_items; i++) { 715904c17e6SDave Chinner struct xfs_log_item *lip = log_items[i]; 716904c17e6SDave Chinner 717e8b78db7SChristoph Hellwig if (lip->li_ops->iop_unpin) 718904c17e6SDave Chinner lip->li_ops->iop_unpin(lip, 0); 719904c17e6SDave Chinner } 7200e57f6a3SDave Chinner } 7210e57f6a3SDave Chinner 7220e57f6a3SDave Chinner /* 7230e57f6a3SDave Chinner * Bulk operation version of xfs_trans_committed that takes a log vector of 7240e57f6a3SDave Chinner * items to insert into the AIL. This uses bulk AIL insertion techniques to 7250e57f6a3SDave Chinner * minimise lock traffic. 726e34a314cSDave Chinner * 727e34a314cSDave Chinner * If we are called with the aborted flag set, it is because a log write during 728e34a314cSDave Chinner * a CIL checkpoint commit has failed. In this case, all the items in the 729ddf92053SChristoph Hellwig * checkpoint have already gone through iop_committed and iop_committing, which 730e34a314cSDave Chinner * means that checkpoint commit abort handling is treated exactly the same 731e34a314cSDave Chinner * as an iclog write error even though we haven't started any IO yet. Hence in 732904c17e6SDave Chinner * this case all we need to do is iop_committed processing, followed by an 733904c17e6SDave Chinner * iop_unpin(aborted) call. 7341d8c95a3SDave Chinner * 7351d8c95a3SDave Chinner * The AIL cursor is used to optimise the insert process. If commit_lsn is not 7361d8c95a3SDave Chinner * at the end of the AIL, the insert cursor avoids the need to walk 7371d8c95a3SDave Chinner * the AIL to find the insertion point on every xfs_log_item_batch_insert() 7381d8c95a3SDave Chinner * call. This saves a lot of needless list walking and is a net win, even 7391d8c95a3SDave Chinner * though it slightly increases that amount of AIL lock traffic to set it up 7401d8c95a3SDave Chinner * and tear it down. 7410e57f6a3SDave Chinner */ 7420e57f6a3SDave Chinner void 7430e57f6a3SDave Chinner xfs_trans_committed_bulk( 7440e57f6a3SDave Chinner struct xfs_ail *ailp, 7450e57f6a3SDave Chinner struct xfs_log_vec *log_vector, 7460e57f6a3SDave Chinner xfs_lsn_t commit_lsn, 747d15cbf2fSChristoph Hellwig bool aborted) 7480e57f6a3SDave Chinner { 7490e57f6a3SDave Chinner #define LOG_ITEM_BATCH_SIZE 32 7500e57f6a3SDave Chinner struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE]; 7510e57f6a3SDave Chinner struct xfs_log_vec *lv; 7521d8c95a3SDave Chinner struct xfs_ail_cursor cur; 7530e57f6a3SDave Chinner int i = 0; 7540e57f6a3SDave Chinner 75557e80956SMatthew Wilcox spin_lock(&ailp->ail_lock); 7561d8c95a3SDave Chinner xfs_trans_ail_cursor_last(ailp, &cur, commit_lsn); 75757e80956SMatthew Wilcox spin_unlock(&ailp->ail_lock); 7581d8c95a3SDave Chinner 7590e57f6a3SDave Chinner /* unpin all the log items */ 7600e57f6a3SDave Chinner for (lv = log_vector; lv; lv = lv->lv_next ) { 7610e57f6a3SDave Chinner struct xfs_log_item *lip = lv->lv_item; 7620e57f6a3SDave Chinner xfs_lsn_t item_lsn; 7630e57f6a3SDave Chinner 7640e57f6a3SDave Chinner if (aborted) 76522525c17SDave Chinner set_bit(XFS_LI_ABORTED, &lip->li_flags); 7669ce632a2SChristoph Hellwig 7679ce632a2SChristoph Hellwig if (lip->li_ops->flags & XFS_ITEM_RELEASE_WHEN_COMMITTED) { 7689ce632a2SChristoph Hellwig lip->li_ops->iop_release(lip); 7699ce632a2SChristoph Hellwig continue; 7709ce632a2SChristoph Hellwig } 7719ce632a2SChristoph Hellwig 772e8b78db7SChristoph Hellwig if (lip->li_ops->iop_committed) 773904c17e6SDave Chinner item_lsn = lip->li_ops->iop_committed(lip, commit_lsn); 774e8b78db7SChristoph Hellwig else 775e8b78db7SChristoph Hellwig item_lsn = commit_lsn; 7760e57f6a3SDave Chinner 7771316d4daSDave Chinner /* item_lsn of -1 means the item needs no further processing */ 7780e57f6a3SDave Chinner if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) 7790e57f6a3SDave Chinner continue; 7800e57f6a3SDave Chinner 781e34a314cSDave Chinner /* 782e34a314cSDave Chinner * if we are aborting the operation, no point in inserting the 783e34a314cSDave Chinner * object into the AIL as we are in a shutdown situation. 784e34a314cSDave Chinner */ 785e34a314cSDave Chinner if (aborted) { 78657e80956SMatthew Wilcox ASSERT(XFS_FORCED_SHUTDOWN(ailp->ail_mount)); 787e8b78db7SChristoph Hellwig if (lip->li_ops->iop_unpin) 788904c17e6SDave Chinner lip->li_ops->iop_unpin(lip, 1); 789e34a314cSDave Chinner continue; 790e34a314cSDave Chinner } 791e34a314cSDave Chinner 7920e57f6a3SDave Chinner if (item_lsn != commit_lsn) { 7930e57f6a3SDave Chinner 7940e57f6a3SDave Chinner /* 7950e57f6a3SDave Chinner * Not a bulk update option due to unusual item_lsn. 7960e57f6a3SDave Chinner * Push into AIL immediately, rechecking the lsn once 7971d8c95a3SDave Chinner * we have the ail lock. Then unpin the item. This does 7981d8c95a3SDave Chinner * not affect the AIL cursor the bulk insert path is 7991d8c95a3SDave Chinner * using. 8000e57f6a3SDave Chinner */ 80157e80956SMatthew Wilcox spin_lock(&ailp->ail_lock); 8020e57f6a3SDave Chinner if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) 8030e57f6a3SDave Chinner xfs_trans_ail_update(ailp, lip, item_lsn); 8040e57f6a3SDave Chinner else 80557e80956SMatthew Wilcox spin_unlock(&ailp->ail_lock); 806e8b78db7SChristoph Hellwig if (lip->li_ops->iop_unpin) 807904c17e6SDave Chinner lip->li_ops->iop_unpin(lip, 0); 8080e57f6a3SDave Chinner continue; 8090e57f6a3SDave Chinner } 8100e57f6a3SDave Chinner 8110e57f6a3SDave Chinner /* Item is a candidate for bulk AIL insert. */ 8120e57f6a3SDave Chinner log_items[i++] = lv->lv_item; 8130e57f6a3SDave Chinner if (i >= LOG_ITEM_BATCH_SIZE) { 8141d8c95a3SDave Chinner xfs_log_item_batch_insert(ailp, &cur, log_items, 8150e57f6a3SDave Chinner LOG_ITEM_BATCH_SIZE, commit_lsn); 8160e57f6a3SDave Chinner i = 0; 8170e57f6a3SDave Chinner } 8180e57f6a3SDave Chinner } 8190e57f6a3SDave Chinner 8200e57f6a3SDave Chinner /* make sure we insert the remainder! */ 8210e57f6a3SDave Chinner if (i) 8221d8c95a3SDave Chinner xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn); 8231d8c95a3SDave Chinner 82457e80956SMatthew Wilcox spin_lock(&ailp->ail_lock); 825e4a1e29cSEric Sandeen xfs_trans_ail_cursor_done(&cur); 82657e80956SMatthew Wilcox spin_unlock(&ailp->ail_lock); 8270e57f6a3SDave Chinner } 8280e57f6a3SDave Chinner 829b1c1b5b6SDave Chinner /* 830b1037058SChristoph Hellwig * Commit the given transaction to the log. 8310924378aSDave Chinner * 8320924378aSDave Chinner * XFS disk error handling mechanism is not based on a typical 8330924378aSDave Chinner * transaction abort mechanism. Logically after the filesystem 8340924378aSDave Chinner * gets marked 'SHUTDOWN', we can't let any new transactions 8350924378aSDave Chinner * be durable - ie. committed to disk - because some metadata might 8360924378aSDave Chinner * be inconsistent. In such cases, this returns an error, and the 8370924378aSDave Chinner * caller may assume that all locked objects joined to the transaction 8380924378aSDave Chinner * have already been unlocked as if the commit had succeeded. 8390924378aSDave Chinner * Do not reference the transaction structure after this call. 8400924378aSDave Chinner */ 84170393313SChristoph Hellwig static int 84270393313SChristoph Hellwig __xfs_trans_commit( 843a3ccd2caSChristoph Hellwig struct xfs_trans *tp, 84470393313SChristoph Hellwig bool regrant) 8450924378aSDave Chinner { 846a3ccd2caSChristoph Hellwig struct xfs_mount *mp = tp->t_mountp; 8470924378aSDave Chinner xfs_lsn_t commit_lsn = -1; 848a3ccd2caSChristoph Hellwig int error = 0; 8490924378aSDave Chinner int sync = tp->t_flags & XFS_TRANS_SYNC; 8500924378aSDave Chinner 851ba18781bSDave Chinner trace_xfs_trans_commit(tp, _RET_IP_); 852ba18781bSDave Chinner 85398719051SBrian Foster /* 85498719051SBrian Foster * Finish deferred items on final commit. Only permanent transactions 85598719051SBrian Foster * should ever have deferred ops. 85698719051SBrian Foster */ 8579d9e6233SBrian Foster WARN_ON_ONCE(!list_empty(&tp->t_dfops) && 85898719051SBrian Foster !(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); 85998719051SBrian Foster if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) { 860b277c37fSBrian Foster error = xfs_defer_finish_noroll(&tp); 8619b1f4e98SBrian Foster if (error) 862e021a2e5SBrian Foster goto out_unreserve; 863e021a2e5SBrian Foster } 864e021a2e5SBrian Foster 8650924378aSDave Chinner /* 8660924378aSDave Chinner * If there is nothing to be logged by the transaction, 8670924378aSDave Chinner * then unlock all of the items associated with the 8680924378aSDave Chinner * transaction and free the transaction structure. 8690924378aSDave Chinner * Also make sure to return any reserved blocks to 8700924378aSDave Chinner * the free pool. 8710924378aSDave Chinner */ 872a3ccd2caSChristoph Hellwig if (!(tp->t_flags & XFS_TRANS_DIRTY)) 873a3ccd2caSChristoph Hellwig goto out_unreserve; 874a3ccd2caSChristoph Hellwig 875a3ccd2caSChristoph Hellwig if (XFS_FORCED_SHUTDOWN(mp)) { 8762451337dSDave Chinner error = -EIO; 877a3ccd2caSChristoph Hellwig goto out_unreserve; 8780924378aSDave Chinner } 879a3ccd2caSChristoph Hellwig 8800924378aSDave Chinner ASSERT(tp->t_ticket != NULL); 8810924378aSDave Chinner 8820924378aSDave Chinner /* 8830924378aSDave Chinner * If we need to update the superblock, then do it now. 8840924378aSDave Chinner */ 8850924378aSDave Chinner if (tp->t_flags & XFS_TRANS_SB_DIRTY) 8860924378aSDave Chinner xfs_trans_apply_sb_deltas(tp); 8870924378aSDave Chinner xfs_trans_apply_dquot_deltas(tp); 8880924378aSDave Chinner 88970393313SChristoph Hellwig xfs_log_commit_cil(mp, tp, &commit_lsn, regrant); 8901da177e4SLinus Torvalds 8910244b960SChristoph Hellwig xfs_trans_free(tp); 8920244b960SChristoph Hellwig 8931da177e4SLinus Torvalds /* 8941da177e4SLinus Torvalds * If the transaction needs to be synchronous, then force the 8951da177e4SLinus Torvalds * log out now and wait for it. 8961da177e4SLinus Torvalds */ 8971da177e4SLinus Torvalds if (sync) { 898656de4ffSChristoph Hellwig error = xfs_log_force_lsn(mp, commit_lsn, XFS_LOG_SYNC, NULL); 899ff6d6af2SBill O'Donnell XFS_STATS_INC(mp, xs_trans_sync); 9001da177e4SLinus Torvalds } else { 901ff6d6af2SBill O'Donnell XFS_STATS_INC(mp, xs_trans_async); 9021da177e4SLinus Torvalds } 9031da177e4SLinus Torvalds 904a3ccd2caSChristoph Hellwig return error; 905a3ccd2caSChristoph Hellwig 906a3ccd2caSChristoph Hellwig out_unreserve: 907a3ccd2caSChristoph Hellwig xfs_trans_unreserve_and_mod_sb(tp); 908a3ccd2caSChristoph Hellwig 909a3ccd2caSChristoph Hellwig /* 910a3ccd2caSChristoph Hellwig * It is indeed possible for the transaction to be not dirty but 911a3ccd2caSChristoph Hellwig * the dqinfo portion to be. All that means is that we have some 912a3ccd2caSChristoph Hellwig * (non-persistent) quota reservations that need to be unreserved. 913a3ccd2caSChristoph Hellwig */ 914a3ccd2caSChristoph Hellwig xfs_trans_unreserve_and_mod_dquots(tp); 915a3ccd2caSChristoph Hellwig if (tp->t_ticket) { 9168b41e3f9SChristoph Hellwig if (regrant && !XLOG_FORCED_SHUTDOWN(mp->m_log)) 9178b41e3f9SChristoph Hellwig xfs_log_ticket_regrant(mp->m_log, tp->t_ticket); 9188b41e3f9SChristoph Hellwig else 9198b41e3f9SChristoph Hellwig xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket); 920ba18781bSDave Chinner tp->t_ticket = NULL; 921a3ccd2caSChristoph Hellwig } 922195cd83dSChristoph Hellwig xfs_trans_free_items(tp, !!error); 923a3ccd2caSChristoph Hellwig xfs_trans_free(tp); 924a3ccd2caSChristoph Hellwig 925ff6d6af2SBill O'Donnell XFS_STATS_INC(mp, xs_trans_empty); 926a3ccd2caSChristoph Hellwig return error; 9271da177e4SLinus Torvalds } 9281da177e4SLinus Torvalds 92970393313SChristoph Hellwig int 93070393313SChristoph Hellwig xfs_trans_commit( 93170393313SChristoph Hellwig struct xfs_trans *tp) 93270393313SChristoph Hellwig { 93370393313SChristoph Hellwig return __xfs_trans_commit(tp, false); 93470393313SChristoph Hellwig } 93570393313SChristoph Hellwig 9361da177e4SLinus Torvalds /* 9371da177e4SLinus Torvalds * Unlock all of the transaction's items and free the transaction. 9381da177e4SLinus Torvalds * The transaction must not have modified any of its items, because 9391da177e4SLinus Torvalds * there is no way to restore them to their previous state. 9401da177e4SLinus Torvalds * 9411da177e4SLinus Torvalds * If the transaction has made a log reservation, make sure to release 9421da177e4SLinus Torvalds * it as well. 9431da177e4SLinus Torvalds */ 9441da177e4SLinus Torvalds void 9451da177e4SLinus Torvalds xfs_trans_cancel( 9464906e215SChristoph Hellwig struct xfs_trans *tp) 9471da177e4SLinus Torvalds { 9484906e215SChristoph Hellwig struct xfs_mount *mp = tp->t_mountp; 9494906e215SChristoph Hellwig bool dirty = (tp->t_flags & XFS_TRANS_DIRTY); 9501da177e4SLinus Torvalds 951ba18781bSDave Chinner trace_xfs_trans_cancel(tp, _RET_IP_); 952ba18781bSDave Chinner 95398719051SBrian Foster if (tp->t_flags & XFS_TRANS_PERM_LOG_RES) 9549e28a242SBrian Foster xfs_defer_cancel(tp); 955e021a2e5SBrian Foster 9561da177e4SLinus Torvalds /* 9571da177e4SLinus Torvalds * See if the caller is relying on us to shut down the 9581da177e4SLinus Torvalds * filesystem. This happens in paths where we detect 9591da177e4SLinus Torvalds * corruption and decide to give up. 9601da177e4SLinus Torvalds */ 9614906e215SChristoph Hellwig if (dirty && !XFS_FORCED_SHUTDOWN(mp)) { 9620733af21SRyan Hankins XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp); 9637d04a335SNathan Scott xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 96460a204f0SNathan Scott } 9651da177e4SLinus Torvalds #ifdef DEBUG 9664906e215SChristoph Hellwig if (!dirty && !XFS_FORCED_SHUTDOWN(mp)) { 967e6631f85SDave Chinner struct xfs_log_item *lip; 9681da177e4SLinus Torvalds 969e6631f85SDave Chinner list_for_each_entry(lip, &tp->t_items, li_trans) 970d6b8fc6cSKaixu Xia ASSERT(!xlog_item_is_intent_done(lip)); 9711da177e4SLinus Torvalds } 9721da177e4SLinus Torvalds #endif 9731da177e4SLinus Torvalds xfs_trans_unreserve_and_mod_sb(tp); 9747d095257SChristoph Hellwig xfs_trans_unreserve_and_mod_dquots(tp); 9751da177e4SLinus Torvalds 976ba18781bSDave Chinner if (tp->t_ticket) { 9778b41e3f9SChristoph Hellwig xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket); 978ba18781bSDave Chinner tp->t_ticket = NULL; 979ba18781bSDave Chinner } 9801da177e4SLinus Torvalds 981195cd83dSChristoph Hellwig xfs_trans_free_items(tp, dirty); 9821da177e4SLinus Torvalds xfs_trans_free(tp); 9831da177e4SLinus Torvalds } 9841da177e4SLinus Torvalds 985322ff6b8SNiv Sardi /* 986322ff6b8SNiv Sardi * Roll from one trans in the sequence of PERMANENT transactions to 987322ff6b8SNiv Sardi * the next: permanent transactions are only flushed out when 98870393313SChristoph Hellwig * committed with xfs_trans_commit(), but we still want as soon 989322ff6b8SNiv Sardi * as possible to let chunks of it go to the log. So we commit the 990322ff6b8SNiv Sardi * chunk we've been working on and get a new transaction to continue. 991322ff6b8SNiv Sardi */ 992322ff6b8SNiv Sardi int 993254133f5SChristoph Hellwig xfs_trans_roll( 994411350dfSChristoph Hellwig struct xfs_trans **tpp) 995322ff6b8SNiv Sardi { 996411350dfSChristoph Hellwig struct xfs_trans *trans = *tpp; 9973d3c8b52SJie Liu struct xfs_trans_res tres; 998322ff6b8SNiv Sardi int error; 999322ff6b8SNiv Sardi 1000ba18781bSDave Chinner trace_xfs_trans_roll(trans, _RET_IP_); 1001ba18781bSDave Chinner 1002322ff6b8SNiv Sardi /* 1003322ff6b8SNiv Sardi * Copy the critical parameters from one trans to the next. 1004322ff6b8SNiv Sardi */ 10053d3c8b52SJie Liu tres.tr_logres = trans->t_log_res; 10063d3c8b52SJie Liu tres.tr_logcount = trans->t_log_count; 1007411350dfSChristoph Hellwig 1008322ff6b8SNiv Sardi *tpp = xfs_trans_dup(trans); 1009322ff6b8SNiv Sardi 1010322ff6b8SNiv Sardi /* 1011322ff6b8SNiv Sardi * Commit the current transaction. 1012322ff6b8SNiv Sardi * If this commit failed, then it'd just unlock those items that 1013322ff6b8SNiv Sardi * are not marked ihold. That also means that a filesystem shutdown 1014322ff6b8SNiv Sardi * is in progress. The caller takes the responsibility to cancel 1015322ff6b8SNiv Sardi * the duplicate transaction that gets returned. 1016322ff6b8SNiv Sardi */ 101770393313SChristoph Hellwig error = __xfs_trans_commit(trans, true); 1018322ff6b8SNiv Sardi if (error) 1019d99831ffSEric Sandeen return error; 1020322ff6b8SNiv Sardi 1021322ff6b8SNiv Sardi /* 1022411350dfSChristoph Hellwig * Reserve space in the log for the next transaction. 1023322ff6b8SNiv Sardi * This also pushes items in the "AIL", the list of logged items, 1024322ff6b8SNiv Sardi * out to disk if they are taking up space at the tail of the log 1025322ff6b8SNiv Sardi * that we want to use. This requires that either nothing be locked 1026322ff6b8SNiv Sardi * across this call, or that anything that is locked be logged in 1027322ff6b8SNiv Sardi * the prior and the next transactions. 1028322ff6b8SNiv Sardi */ 10293d3c8b52SJie Liu tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; 1030411350dfSChristoph Hellwig return xfs_trans_reserve(*tpp, &tres, 0, 0); 1031322ff6b8SNiv Sardi } 10323a1af6c3SDarrick J. Wong 10333a1af6c3SDarrick J. Wong /* 10343a1af6c3SDarrick J. Wong * Allocate an transaction, lock and join the inode to it, and reserve quota. 10353a1af6c3SDarrick J. Wong * 10363a1af6c3SDarrick J. Wong * The caller must ensure that the on-disk dquots attached to this inode have 10373a1af6c3SDarrick J. Wong * already been allocated and initialized. The caller is responsible for 10383a1af6c3SDarrick J. Wong * releasing ILOCK_EXCL if a new transaction is returned. 10393a1af6c3SDarrick J. Wong */ 10403a1af6c3SDarrick J. Wong int 10413a1af6c3SDarrick J. Wong xfs_trans_alloc_inode( 10423a1af6c3SDarrick J. Wong struct xfs_inode *ip, 10433a1af6c3SDarrick J. Wong struct xfs_trans_res *resv, 10443a1af6c3SDarrick J. Wong unsigned int dblocks, 10453de4eb10SDarrick J. Wong unsigned int rblocks, 10463a1af6c3SDarrick J. Wong bool force, 10473a1af6c3SDarrick J. Wong struct xfs_trans **tpp) 10483a1af6c3SDarrick J. Wong { 10493a1af6c3SDarrick J. Wong struct xfs_trans *tp; 10503a1af6c3SDarrick J. Wong struct xfs_mount *mp = ip->i_mount; 1051766aabd5SDarrick J. Wong bool retried = false; 10523a1af6c3SDarrick J. Wong int error; 10533a1af6c3SDarrick J. Wong 1054766aabd5SDarrick J. Wong retry: 10553de4eb10SDarrick J. Wong error = xfs_trans_alloc(mp, resv, dblocks, 10563de4eb10SDarrick J. Wong rblocks / mp->m_sb.sb_rextsize, 10573a1af6c3SDarrick J. Wong force ? XFS_TRANS_RESERVE : 0, &tp); 10583a1af6c3SDarrick J. Wong if (error) 10593a1af6c3SDarrick J. Wong return error; 10603a1af6c3SDarrick J. Wong 10613a1af6c3SDarrick J. Wong xfs_ilock(ip, XFS_ILOCK_EXCL); 10623a1af6c3SDarrick J. Wong xfs_trans_ijoin(tp, ip, 0); 10633a1af6c3SDarrick J. Wong 10643a1af6c3SDarrick J. Wong error = xfs_qm_dqattach_locked(ip, false); 10653a1af6c3SDarrick J. Wong if (error) { 10663a1af6c3SDarrick J. Wong /* Caller should have allocated the dquots! */ 10673a1af6c3SDarrick J. Wong ASSERT(error != -ENOENT); 10683a1af6c3SDarrick J. Wong goto out_cancel; 10693a1af6c3SDarrick J. Wong } 10703a1af6c3SDarrick J. Wong 10713de4eb10SDarrick J. Wong error = xfs_trans_reserve_quota_nblks(tp, ip, dblocks, rblocks, force); 1072766aabd5SDarrick J. Wong if ((error == -EDQUOT || error == -ENOSPC) && !retried) { 1073766aabd5SDarrick J. Wong xfs_trans_cancel(tp); 1074766aabd5SDarrick J. Wong xfs_iunlock(ip, XFS_ILOCK_EXCL); 1075766aabd5SDarrick J. Wong xfs_blockgc_free_quota(ip, 0); 1076766aabd5SDarrick J. Wong retried = true; 1077766aabd5SDarrick J. Wong goto retry; 1078766aabd5SDarrick J. Wong } 10793a1af6c3SDarrick J. Wong if (error) 10803a1af6c3SDarrick J. Wong goto out_cancel; 10813a1af6c3SDarrick J. Wong 10823a1af6c3SDarrick J. Wong *tpp = tp; 10833a1af6c3SDarrick J. Wong return 0; 10843a1af6c3SDarrick J. Wong 10853a1af6c3SDarrick J. Wong out_cancel: 10863a1af6c3SDarrick J. Wong xfs_trans_cancel(tp); 10873a1af6c3SDarrick J. Wong xfs_iunlock(ip, XFS_ILOCK_EXCL); 10883a1af6c3SDarrick J. Wong return error; 10893a1af6c3SDarrick J. Wong } 1090f2f7b9ffSDarrick J. Wong 1091f2f7b9ffSDarrick J. Wong /* 1092f2f7b9ffSDarrick J. Wong * Allocate an transaction in preparation for inode creation by reserving quota 1093f2f7b9ffSDarrick J. Wong * against the given dquots. Callers are not required to hold any inode locks. 1094f2f7b9ffSDarrick J. Wong */ 1095f2f7b9ffSDarrick J. Wong int 1096f2f7b9ffSDarrick J. Wong xfs_trans_alloc_icreate( 1097f2f7b9ffSDarrick J. Wong struct xfs_mount *mp, 1098f2f7b9ffSDarrick J. Wong struct xfs_trans_res *resv, 1099f2f7b9ffSDarrick J. Wong struct xfs_dquot *udqp, 1100f2f7b9ffSDarrick J. Wong struct xfs_dquot *gdqp, 1101f2f7b9ffSDarrick J. Wong struct xfs_dquot *pdqp, 1102f2f7b9ffSDarrick J. Wong unsigned int dblocks, 1103f2f7b9ffSDarrick J. Wong struct xfs_trans **tpp) 1104f2f7b9ffSDarrick J. Wong { 1105f2f7b9ffSDarrick J. Wong struct xfs_trans *tp; 1106c237dd7cSDarrick J. Wong bool retried = false; 1107f2f7b9ffSDarrick J. Wong int error; 1108f2f7b9ffSDarrick J. Wong 1109c237dd7cSDarrick J. Wong retry: 1110f2f7b9ffSDarrick J. Wong error = xfs_trans_alloc(mp, resv, dblocks, 0, 0, &tp); 1111f2f7b9ffSDarrick J. Wong if (error) 1112f2f7b9ffSDarrick J. Wong return error; 1113f2f7b9ffSDarrick J. Wong 1114f2f7b9ffSDarrick J. Wong error = xfs_trans_reserve_quota_icreate(tp, udqp, gdqp, pdqp, dblocks); 1115c237dd7cSDarrick J. Wong if ((error == -EDQUOT || error == -ENOSPC) && !retried) { 1116c237dd7cSDarrick J. Wong xfs_trans_cancel(tp); 1117c237dd7cSDarrick J. Wong xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0); 1118c237dd7cSDarrick J. Wong retried = true; 1119c237dd7cSDarrick J. Wong goto retry; 1120c237dd7cSDarrick J. Wong } 1121f2f7b9ffSDarrick J. Wong if (error) { 1122f2f7b9ffSDarrick J. Wong xfs_trans_cancel(tp); 1123f2f7b9ffSDarrick J. Wong return error; 1124f2f7b9ffSDarrick J. Wong } 1125f2f7b9ffSDarrick J. Wong 1126f2f7b9ffSDarrick J. Wong *tpp = tp; 1127f2f7b9ffSDarrick J. Wong return 0; 1128f2f7b9ffSDarrick J. Wong } 11297317a03dSDarrick J. Wong 11307317a03dSDarrick J. Wong /* 11317317a03dSDarrick J. Wong * Allocate an transaction, lock and join the inode to it, and reserve quota 11327317a03dSDarrick J. Wong * in preparation for inode attribute changes that include uid, gid, or prid 11337317a03dSDarrick J. Wong * changes. 11347317a03dSDarrick J. Wong * 11357317a03dSDarrick J. Wong * The caller must ensure that the on-disk dquots attached to this inode have 11367317a03dSDarrick J. Wong * already been allocated and initialized. The ILOCK will be dropped when the 11377317a03dSDarrick J. Wong * transaction is committed or cancelled. 11387317a03dSDarrick J. Wong */ 11397317a03dSDarrick J. Wong int 11407317a03dSDarrick J. Wong xfs_trans_alloc_ichange( 11417317a03dSDarrick J. Wong struct xfs_inode *ip, 1142758303d1SDarrick J. Wong struct xfs_dquot *new_udqp, 1143758303d1SDarrick J. Wong struct xfs_dquot *new_gdqp, 1144758303d1SDarrick J. Wong struct xfs_dquot *new_pdqp, 11457317a03dSDarrick J. Wong bool force, 11467317a03dSDarrick J. Wong struct xfs_trans **tpp) 11477317a03dSDarrick J. Wong { 11487317a03dSDarrick J. Wong struct xfs_trans *tp; 11497317a03dSDarrick J. Wong struct xfs_mount *mp = ip->i_mount; 1150758303d1SDarrick J. Wong struct xfs_dquot *udqp; 1151758303d1SDarrick J. Wong struct xfs_dquot *gdqp; 1152758303d1SDarrick J. Wong struct xfs_dquot *pdqp; 1153758303d1SDarrick J. Wong bool retried = false; 11547317a03dSDarrick J. Wong int error; 11557317a03dSDarrick J. Wong 1156758303d1SDarrick J. Wong retry: 11577317a03dSDarrick J. Wong error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); 11587317a03dSDarrick J. Wong if (error) 11597317a03dSDarrick J. Wong return error; 11607317a03dSDarrick J. Wong 11617317a03dSDarrick J. Wong xfs_ilock(ip, XFS_ILOCK_EXCL); 11627317a03dSDarrick J. Wong xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 11637317a03dSDarrick J. Wong 11647317a03dSDarrick J. Wong error = xfs_qm_dqattach_locked(ip, false); 11657317a03dSDarrick J. Wong if (error) { 11667317a03dSDarrick J. Wong /* Caller should have allocated the dquots! */ 11677317a03dSDarrick J. Wong ASSERT(error != -ENOENT); 11687317a03dSDarrick J. Wong goto out_cancel; 11697317a03dSDarrick J. Wong } 11707317a03dSDarrick J. Wong 11717317a03dSDarrick J. Wong /* 11727317a03dSDarrick J. Wong * For each quota type, skip quota reservations if the inode's dquots 11737317a03dSDarrick J. Wong * now match the ones that came from the caller, or the caller didn't 1174758303d1SDarrick J. Wong * pass one in. The inode's dquots can change if we drop the ILOCK to 1175758303d1SDarrick J. Wong * perform a blockgc scan, so we must preserve the caller's arguments. 11767317a03dSDarrick J. Wong */ 1177758303d1SDarrick J. Wong udqp = (new_udqp != ip->i_udquot) ? new_udqp : NULL; 1178758303d1SDarrick J. Wong gdqp = (new_gdqp != ip->i_gdquot) ? new_gdqp : NULL; 1179758303d1SDarrick J. Wong pdqp = (new_pdqp != ip->i_pdquot) ? new_pdqp : NULL; 11807317a03dSDarrick J. Wong if (udqp || gdqp || pdqp) { 11815c615f0fSDarrick J. Wong unsigned int qflags = XFS_QMOPT_RES_REGBLKS; 11825c615f0fSDarrick J. Wong 11835c615f0fSDarrick J. Wong if (force) 11845c615f0fSDarrick J. Wong qflags |= XFS_QMOPT_FORCE_RES; 11855c615f0fSDarrick J. Wong 11865c615f0fSDarrick J. Wong /* 11875c615f0fSDarrick J. Wong * Reserve enough quota to handle blocks on disk and reserved 11885c615f0fSDarrick J. Wong * for a delayed allocation. We'll actually transfer the 11895c615f0fSDarrick J. Wong * delalloc reservation between dquots at chown time, even 11905c615f0fSDarrick J. Wong * though that part is only semi-transactional. 11915c615f0fSDarrick J. Wong */ 11925c615f0fSDarrick J. Wong error = xfs_trans_reserve_quota_bydquots(tp, mp, udqp, gdqp, 11935c615f0fSDarrick J. Wong pdqp, ip->i_d.di_nblocks + ip->i_delayed_blks, 11945c615f0fSDarrick J. Wong 1, qflags); 1195758303d1SDarrick J. Wong if ((error == -EDQUOT || error == -ENOSPC) && !retried) { 1196758303d1SDarrick J. Wong xfs_trans_cancel(tp); 1197758303d1SDarrick J. Wong xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0); 1198758303d1SDarrick J. Wong retried = true; 1199758303d1SDarrick J. Wong goto retry; 1200758303d1SDarrick J. Wong } 12017317a03dSDarrick J. Wong if (error) 12027317a03dSDarrick J. Wong goto out_cancel; 12037317a03dSDarrick J. Wong } 12047317a03dSDarrick J. Wong 12057317a03dSDarrick J. Wong *tpp = tp; 12067317a03dSDarrick J. Wong return 0; 12077317a03dSDarrick J. Wong 12087317a03dSDarrick J. Wong out_cancel: 12097317a03dSDarrick J. Wong xfs_trans_cancel(tp); 12107317a03dSDarrick J. Wong return error; 12117317a03dSDarrick J. Wong } 1212