aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs
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/libxfs
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/libxfs')
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c32
-rw-r--r--fs/xfs/libxfs/xfs_sb.c1
2 files changed, 14 insertions, 19 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 61ec015dca16..e39c9e83670e 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -2212,9 +2212,8 @@ xfs_bmap_add_extent_delay_real(
2212 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - 2212 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) -
2213 (bma->cur ? bma->cur->bc_private.b.allocated : 0)); 2213 (bma->cur ? bma->cur->bc_private.b.allocated : 0));
2214 if (diff > 0) { 2214 if (diff > 0) {
2215 error = xfs_icsb_modify_counters(bma->ip->i_mount, 2215 error = xfs_mod_fdblocks(bma->ip->i_mount,
2216 XFS_SBS_FDBLOCKS, 2216 -((int64_t)diff), false);
2217 -((int64_t)diff), 0);
2218 ASSERT(!error); 2217 ASSERT(!error);
2219 if (error) 2218 if (error)
2220 goto done; 2219 goto done;
@@ -2265,9 +2264,8 @@ xfs_bmap_add_extent_delay_real(
2265 temp += bma->cur->bc_private.b.allocated; 2264 temp += bma->cur->bc_private.b.allocated;
2266 ASSERT(temp <= da_old); 2265 ASSERT(temp <= da_old);
2267 if (temp < da_old) 2266 if (temp < da_old)
2268 xfs_icsb_modify_counters(bma->ip->i_mount, 2267 xfs_mod_fdblocks(bma->ip->i_mount,
2269 XFS_SBS_FDBLOCKS, 2268 (int64_t)(da_old - temp), false);
2270 (int64_t)(da_old - temp), 0);
2271 } 2269 }
2272 2270
2273 /* clear out the allocated field, done with it now in any case. */ 2271 /* clear out the allocated field, done with it now in any case. */
@@ -2944,8 +2942,8 @@ xfs_bmap_add_extent_hole_delay(
2944 } 2942 }
2945 if (oldlen != newlen) { 2943 if (oldlen != newlen) {
2946 ASSERT(oldlen > newlen); 2944 ASSERT(oldlen > newlen);
2947 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, 2945 xfs_mod_fdblocks(ip->i_mount, (int64_t)(oldlen - newlen),
2948 (int64_t)(oldlen - newlen), 0); 2946 false);
2949 /* 2947 /*
2950 * Nothing to do for disk quota accounting here. 2948 * Nothing to do for disk quota accounting here.
2951 */ 2949 */
@@ -4163,15 +4161,13 @@ xfs_bmapi_reserve_delalloc(
4163 error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, 4161 error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
4164 -((int64_t)extsz), 0); 4162 -((int64_t)extsz), 0);
4165 } else { 4163 } else {
4166 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 4164 error = xfs_mod_fdblocks(mp, -((int64_t)alen), false);
4167 -((int64_t)alen), 0);
4168 } 4165 }
4169 4166
4170 if (error) 4167 if (error)
4171 goto out_unreserve_quota; 4168 goto out_unreserve_quota;
4172 4169
4173 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 4170 error = xfs_mod_fdblocks(mp, -((int64_t)indlen), false);
4174 -((int64_t)indlen), 0);
4175 if (error) 4171 if (error)
4176 goto out_unreserve_blocks; 4172 goto out_unreserve_blocks;
4177 4173
@@ -4200,7 +4196,7 @@ out_unreserve_blocks:
4200 if (rt) 4196 if (rt)
4201 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0); 4197 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0);
4202 else 4198 else
4203 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, alen, 0); 4199 xfs_mod_fdblocks(mp, alen, false);
4204out_unreserve_quota: 4200out_unreserve_quota:
4205 if (XFS_IS_QUOTA_ON(mp)) 4201 if (XFS_IS_QUOTA_ON(mp))
4206 xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0, rt ? 4202 xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0, rt ?
@@ -5012,10 +5008,8 @@ xfs_bmap_del_extent(
5012 * Nothing to do for disk quota accounting here. 5008 * Nothing to do for disk quota accounting here.
5013 */ 5009 */
5014 ASSERT(da_old >= da_new); 5010 ASSERT(da_old >= da_new);
5015 if (da_old > da_new) { 5011 if (da_old > da_new)
5016 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 5012 xfs_mod_fdblocks(mp, (int64_t)(da_old - da_new), false);
5017 (int64_t)(da_old - da_new), 0);
5018 }
5019done: 5013done:
5020 *logflagsp = flags; 5014 *logflagsp = flags;
5021 return error; 5015 return error;
@@ -5290,8 +5284,8 @@ xfs_bunmapi(
5290 ip, -((long)del.br_blockcount), 0, 5284 ip, -((long)del.br_blockcount), 0,
5291 XFS_QMOPT_RES_RTBLKS); 5285 XFS_QMOPT_RES_RTBLKS);
5292 } else { 5286 } else {
5293 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 5287 xfs_mod_fdblocks(mp, (int64_t)del.br_blockcount,
5294 (int64_t)del.br_blockcount, 0); 5288 false);
5295 (void)xfs_trans_reserve_quota_nblks(NULL, 5289 (void)xfs_trans_reserve_quota_nblks(NULL,
5296 ip, -((long)del.br_blockcount), 0, 5290 ip, -((long)del.br_blockcount), 0,
5297 XFS_QMOPT_RES_REGBLKS); 5291 XFS_QMOPT_RES_REGBLKS);
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index b66aeab99cfb..31a3e972f86f 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -773,6 +773,7 @@ xfs_log_sb(
773 773
774 mp->m_sb.sb_icount = percpu_counter_sum(&mp->m_icount); 774 mp->m_sb.sb_icount = percpu_counter_sum(&mp->m_icount);
775 mp->m_sb.sb_ifree = percpu_counter_sum(&mp->m_ifree); 775 mp->m_sb.sb_ifree = percpu_counter_sum(&mp->m_ifree);
776 mp->m_sb.sb_fdblocks = percpu_counter_sum(&mp->m_fdblocks);
776 777
777 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); 778 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb);
778 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); 779 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);