diff options
author | Dave Chinner <david@fromorbit.com> | 2015-02-23 05:22:03 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2015-02-23 05:22:03 -0500 |
commit | 0d485ada404b3614b045e574bec26aaf5d9b3c5b (patch) | |
tree | b08812daee1eed9e8be59e6c12bf0eeef5b6f7cf /fs/xfs/xfs_trans.c | |
parent | e88b64ea1f3da64dbb52636377be295c90367377 (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.c | 16 |
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 | ||
269 | undo_blocks: | 268 | undo_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); |
636 | out_undo_fdblocks: | 632 | out_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); |
639 | out: | 635 | out: |
640 | ASSERT(error == 0); | 636 | ASSERT(error == 0); |
641 | return; | 637 | return; |