aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans.c
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2015-02-23 05:22:03 -0500
committerDave Chinner <david@fromorbit.com>2015-02-23 05:22:03 -0500
commit0d485ada404b3614b045e574bec26aaf5d9b3c5b (patch)
treeb08812daee1eed9e8be59e6c12bf0eeef5b6f7cf /fs/xfs/xfs_trans.c
parente88b64ea1f3da64dbb52636377be295c90367377 (diff)
xfs: use generic percpu counters for free block counter
XFS has hand-rolled per-cpu counters for the superblock since before there was any generic implementation. The free block counter is special in that it is used for ENOSPC detection outside transaction contexts for for delayed allocation. This means that the counter needs to be accurate at zero. The current per-cpu counter code jumps through lots of hoops to ensure we never run past zero, but we don't need to make all those jumps with the generic counter implementation. The generic counter implementation allows us to pass a "batch" threshold at which the addition/subtraction to the counter value will be folded back into global value under lock. We can use this feature to reduce the batch size as we approach 0 in a very similar manner to the existing counters and their rebalance algorithm. If we use a batch size of 1 as we approach 0, then every addition and subtraction will be done against the global value and hence allow accurate detection of zero threshold crossing. Hence we can replace the handrolled, accurate-at-zero counters with generic percpu counters. Note: this removes just enough of the icsb infrastructure to compile without warnings. The rest will go in subsequent commits. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r--fs/xfs/xfs_trans.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 68680ce67547..e99f5e552c64 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -173,7 +173,7 @@ xfs_trans_reserve(
173 uint rtextents) 173 uint rtextents)
174{ 174{
175 int error = 0; 175 int error = 0;
176 int rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; 176 bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
177 177
178 /* Mark this thread as being in a transaction */ 178 /* Mark this thread as being in a transaction */
179 current_set_flags_nested(&tp->t_pflags, PF_FSTRANS); 179 current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
@@ -184,8 +184,7 @@ xfs_trans_reserve(
184 * fail if the count would go below zero. 184 * fail if the count would go below zero.
185 */ 185 */
186 if (blocks > 0) { 186 if (blocks > 0) {
187 error = xfs_icsb_modify_counters(tp->t_mountp, XFS_SBS_FDBLOCKS, 187 error = xfs_mod_fdblocks(tp->t_mountp, -((int64_t)blocks), rsvd);
188 -((int64_t)blocks), rsvd);
189 if (error != 0) { 188 if (error != 0) {
190 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); 189 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
191 return -ENOSPC; 190 return -ENOSPC;
@@ -268,8 +267,7 @@ undo_log:
268 267
269undo_blocks: 268undo_blocks:
270 if (blocks > 0) { 269 if (blocks > 0) {
271 xfs_icsb_modify_counters(tp->t_mountp, XFS_SBS_FDBLOCKS, 270 xfs_mod_fdblocks(tp->t_mountp, -((int64_t)blocks), rsvd);
272 (int64_t)blocks, rsvd);
273 tp->t_blk_res = 0; 271 tp->t_blk_res = 0;
274 } 272 }
275 273
@@ -516,14 +514,13 @@ xfs_trans_unreserve_and_mod_sb(
516 xfs_mount_t *mp = tp->t_mountp; 514 xfs_mount_t *mp = tp->t_mountp;
517 /* REFERENCED */ 515 /* REFERENCED */
518 int error; 516 int error;
519 int rsvd; 517 bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
520 int64_t blkdelta = 0; 518 int64_t blkdelta = 0;
521 int64_t rtxdelta = 0; 519 int64_t rtxdelta = 0;
522 int64_t idelta = 0; 520 int64_t idelta = 0;
523 int64_t ifreedelta = 0; 521 int64_t ifreedelta = 0;
524 522
525 msbp = msb; 523 msbp = msb;
526 rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
527 524
528 /* calculate deltas */ 525 /* calculate deltas */
529 if (tp->t_blk_res > 0) 526 if (tp->t_blk_res > 0)
@@ -547,8 +544,7 @@ xfs_trans_unreserve_and_mod_sb(
547 544
548 /* apply the per-cpu counters */ 545 /* apply the per-cpu counters */
549 if (blkdelta) { 546 if (blkdelta) {
550 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 547 error = xfs_mod_fdblocks(mp, blkdelta, rsvd);
551 blkdelta, rsvd);
552 if (error) 548 if (error)
553 goto out; 549 goto out;
554 } 550 }
@@ -635,7 +631,7 @@ out_undo_icount:
635 xfs_mod_icount(mp, -idelta); 631 xfs_mod_icount(mp, -idelta);
636out_undo_fdblocks: 632out_undo_fdblocks:
637 if (blkdelta) 633 if (blkdelta)
638 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, -blkdelta, rsvd); 634 xfs_mod_fdblocks(mp, -blkdelta, rsvd);
639out: 635out:
640 ASSERT(error == 0); 636 ASSERT(error == 0);
641 return; 637 return;