aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c32
-rw-r--r--fs/xfs/libxfs/xfs_sb.c1
-rw-r--r--fs/xfs/xfs_fsops.c9
-rw-r--r--fs/xfs/xfs_iomap.c2
-rw-r--r--fs/xfs/xfs_mount.c192
-rw-r--r--fs/xfs/xfs_mount.h3
-rw-r--r--fs/xfs/xfs_super.c10
-rw-r--r--fs/xfs/xfs_trans.c16
8 files changed, 134 insertions, 131 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);
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index a1ca9c2b8c00..7ef25588062f 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -640,9 +640,10 @@ xfs_fs_counts(
640 xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); 640 xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
641 cnt->allocino = percpu_counter_read_positive(&mp->m_icount); 641 cnt->allocino = percpu_counter_read_positive(&mp->m_icount);
642 cnt->freeino = percpu_counter_read_positive(&mp->m_ifree); 642 cnt->freeino = percpu_counter_read_positive(&mp->m_ifree);
643 cnt->freedata = percpu_counter_read_positive(&mp->m_fdblocks) -
644 XFS_ALLOC_SET_ASIDE(mp);
643 645
644 spin_lock(&mp->m_sb_lock); 646 spin_lock(&mp->m_sb_lock);
645 cnt->freedata = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
646 cnt->freertx = mp->m_sb.sb_frextents; 647 cnt->freertx = mp->m_sb.sb_frextents;
647 spin_unlock(&mp->m_sb_lock); 648 spin_unlock(&mp->m_sb_lock);
648 return 0; 649 return 0;
@@ -717,7 +718,8 @@ retry:
717 } else { 718 } else {
718 __int64_t free; 719 __int64_t free;
719 720
720 free = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); 721 free = percpu_counter_sum(&mp->m_fdblocks) -
722 XFS_ALLOC_SET_ASIDE(mp);
721 if (!free) 723 if (!free)
722 goto out; /* ENOSPC and fdblks_delta = 0 */ 724 goto out; /* ENOSPC and fdblks_delta = 0 */
723 725
@@ -756,8 +758,7 @@ out:
756 * the extra reserve blocks from the reserve..... 758 * the extra reserve blocks from the reserve.....
757 */ 759 */
758 int error; 760 int error;
759 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 761 error = xfs_mod_fdblocks(mp, fdblks_delta, 0);
760 fdblks_delta, 0);
761 if (error == -ENOSPC) 762 if (error == -ENOSPC)
762 goto retry; 763 goto retry;
763 } 764 }
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index ccb1dd0d509e..205b948c9d20 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -461,7 +461,7 @@ xfs_iomap_prealloc_size(
461 alloc_blocks); 461 alloc_blocks);
462 462
463 xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); 463 xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
464 freesp = mp->m_sb.sb_fdblocks; 464 freesp = percpu_counter_read_positive(&mp->m_fdblocks);
465 if (freesp < mp->m_low_space[XFS_LOWSP_5_PCNT]) { 465 if (freesp < mp->m_low_space[XFS_LOWSP_5_PCNT]) {
466 shift = 2; 466 shift = 2;
467 if (freesp < mp->m_low_space[XFS_LOWSP_4_PCNT]) 467 if (freesp < mp->m_low_space[XFS_LOWSP_4_PCNT])
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 650e8f18cd2a..767c09a5d3ff 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1114,7 +1114,6 @@ xfs_mod_icount(
1114 return 0; 1114 return 0;
1115} 1115}
1116 1116
1117
1118int 1117int
1119xfs_mod_ifree( 1118xfs_mod_ifree(
1120 struct xfs_mount *mp, 1119 struct xfs_mount *mp,
@@ -1128,6 +1127,92 @@ xfs_mod_ifree(
1128 } 1127 }
1129 return 0; 1128 return 0;
1130} 1129}
1130
1131int
1132xfs_mod_fdblocks(
1133 struct xfs_mount *mp,
1134 int64_t delta,
1135 bool rsvd)
1136{
1137 int64_t lcounter;
1138 long long res_used;
1139 s32 batch;
1140
1141 if (delta > 0) {
1142 /*
1143 * If the reserve pool is depleted, put blocks back into it
1144 * first. Most of the time the pool is full.
1145 */
1146 if (likely(mp->m_resblks == mp->m_resblks_avail)) {
1147 percpu_counter_add(&mp->m_fdblocks, delta);
1148 return 0;
1149 }
1150
1151 spin_lock(&mp->m_sb_lock);
1152 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
1153
1154 if (res_used > delta) {
1155 mp->m_resblks_avail += delta;
1156 } else {
1157 delta -= res_used;
1158 mp->m_resblks_avail = mp->m_resblks;
1159 percpu_counter_add(&mp->m_fdblocks, delta);
1160 }
1161 spin_unlock(&mp->m_sb_lock);
1162 return 0;
1163 }
1164
1165 /*
1166 * Taking blocks away, need to be more accurate the closer we
1167 * are to zero.
1168 *
1169 * batch size is set to a maximum of 1024 blocks - if we are
1170 * allocating of freeing extents larger than this then we aren't
1171 * going to be hammering the counter lock so a lock per update
1172 * is not a problem.
1173 *
1174 * If the counter has a value of less than 2 * max batch size,
1175 * then make everything serialise as we are real close to
1176 * ENOSPC.
1177 */
1178#define __BATCH 1024
1179 if (percpu_counter_compare(&mp->m_fdblocks, 2 * __BATCH) < 0)
1180 batch = 1;
1181 else
1182 batch = __BATCH;
1183#undef __BATCH
1184
1185 __percpu_counter_add(&mp->m_fdblocks, delta, batch);
1186 if (percpu_counter_compare(&mp->m_fdblocks,
1187 XFS_ALLOC_SET_ASIDE(mp)) >= 0) {
1188 /* we had space! */
1189 return 0;
1190 }
1191
1192 /*
1193 * lock up the sb for dipping into reserves before releasing the space
1194 * that took us to ENOSPC.
1195 */
1196 spin_lock(&mp->m_sb_lock);
1197 percpu_counter_add(&mp->m_fdblocks, -delta);
1198 if (!rsvd)
1199 goto fdblocks_enospc;
1200
1201 lcounter = (long long)mp->m_resblks_avail + delta;
1202 if (lcounter >= 0) {
1203 mp->m_resblks_avail = lcounter;
1204 spin_unlock(&mp->m_sb_lock);
1205 return 0;
1206 }
1207 printk_once(KERN_WARNING
1208 "Filesystem \"%s\": reserve blocks depleted! "
1209 "Consider increasing reserve pool size.",
1210 mp->m_fsname);
1211fdblocks_enospc:
1212 spin_unlock(&mp->m_sb_lock);
1213 return -ENOSPC;
1214}
1215
1131/* 1216/*
1132 * xfs_mod_incore_sb_unlocked() is a utility routine commonly used to apply 1217 * xfs_mod_incore_sb_unlocked() is a utility routine commonly used to apply
1133 * a delta to a specified field in the in-core superblock. Simply 1218 * a delta to a specified field in the in-core superblock. Simply
@@ -1146,7 +1231,6 @@ xfs_mod_incore_sb_unlocked(
1146{ 1231{
1147 int scounter; /* short counter for 32 bit fields */ 1232 int scounter; /* short counter for 32 bit fields */
1148 long long lcounter; /* long counter for 64 bit fields */ 1233 long long lcounter; /* long counter for 64 bit fields */
1149 long long res_used, rem;
1150 1234
1151 /* 1235 /*
1152 * With the in-core superblock spin lock held, switch 1236 * With the in-core superblock spin lock held, switch
@@ -1157,50 +1241,9 @@ xfs_mod_incore_sb_unlocked(
1157 switch (field) { 1241 switch (field) {
1158 case XFS_SBS_ICOUNT: 1242 case XFS_SBS_ICOUNT:
1159 case XFS_SBS_IFREE: 1243 case XFS_SBS_IFREE:
1244 case XFS_SBS_FDBLOCKS:
1160 ASSERT(0); 1245 ASSERT(0);
1161 return -EINVAL; 1246 return -EINVAL;
1162 case XFS_SBS_FDBLOCKS:
1163 lcounter = (long long)
1164 mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
1165 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
1166
1167 if (delta > 0) { /* Putting blocks back */
1168 if (res_used > delta) {
1169 mp->m_resblks_avail += delta;
1170 } else {
1171 rem = delta - res_used;
1172 mp->m_resblks_avail = mp->m_resblks;
1173 lcounter += rem;
1174 }
1175 } else { /* Taking blocks away */
1176 lcounter += delta;
1177 if (lcounter >= 0) {
1178 mp->m_sb.sb_fdblocks = lcounter +
1179 XFS_ALLOC_SET_ASIDE(mp);
1180 return 0;
1181 }
1182
1183 /*
1184 * We are out of blocks, use any available reserved
1185 * blocks if were allowed to.
1186 */
1187 if (!rsvd)
1188 return -ENOSPC;
1189
1190 lcounter = (long long)mp->m_resblks_avail + delta;
1191 if (lcounter >= 0) {
1192 mp->m_resblks_avail = lcounter;
1193 return 0;
1194 }
1195 printk_once(KERN_WARNING
1196 "Filesystem \"%s\": reserve blocks depleted! "
1197 "Consider increasing reserve pool size.",
1198 mp->m_fsname);
1199 return -ENOSPC;
1200 }
1201
1202 mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
1203 return 0;
1204 case XFS_SBS_FREXTENTS: 1247 case XFS_SBS_FREXTENTS:
1205 lcounter = (long long)mp->m_sb.sb_frextents; 1248 lcounter = (long long)mp->m_sb.sb_frextents;
1206 lcounter += delta; 1249 lcounter += delta;
@@ -1323,7 +1366,7 @@ xfs_mod_incore_sb(
1323 * 1366 *
1324 * Note that this function may not be used for the superblock values that 1367 * Note that this function may not be used for the superblock values that
1325 * are tracked with the in-memory per-cpu counters - a direct call to 1368 * are tracked with the in-memory per-cpu counters - a direct call to
1326 * xfs_icsb_modify_counters is required for these. 1369 * xfs_mod_incore_sb is required for these.
1327 */ 1370 */
1328int 1371int
1329xfs_mod_incore_sb_batch( 1372xfs_mod_incore_sb_batch(
@@ -1508,7 +1551,6 @@ xfs_icsb_cpu_notify(
1508 case CPU_ONLINE: 1551 case CPU_ONLINE:
1509 case CPU_ONLINE_FROZEN: 1552 case CPU_ONLINE_FROZEN:
1510 xfs_icsb_lock(mp); 1553 xfs_icsb_lock(mp);
1511 xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
1512 xfs_icsb_unlock(mp); 1554 xfs_icsb_unlock(mp);
1513 break; 1555 break;
1514 case CPU_DEAD: 1556 case CPU_DEAD:
@@ -1518,13 +1560,9 @@ xfs_icsb_cpu_notify(
1518 * re-enable the counters. */ 1560 * re-enable the counters. */
1519 xfs_icsb_lock(mp); 1561 xfs_icsb_lock(mp);
1520 spin_lock(&mp->m_sb_lock); 1562 spin_lock(&mp->m_sb_lock);
1521 xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS);
1522
1523 mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks;
1524 1563
1525 memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); 1564 memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
1526 1565
1527 xfs_icsb_balance_counter_locked(mp, XFS_SBS_FDBLOCKS, 0);
1528 spin_unlock(&mp->m_sb_lock); 1566 spin_unlock(&mp->m_sb_lock);
1529 xfs_icsb_unlock(mp); 1567 xfs_icsb_unlock(mp);
1530 break; 1568 break;
@@ -1550,10 +1588,14 @@ xfs_icsb_init_counters(
1550 if (error) 1588 if (error)
1551 goto free_icount; 1589 goto free_icount;
1552 1590
1591 error = percpu_counter_init(&mp->m_fdblocks, 0, GFP_KERNEL);
1592 if (error)
1593 goto free_ifree;
1594
1553 mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t); 1595 mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t);
1554 if (!mp->m_sb_cnts) { 1596 if (!mp->m_sb_cnts) {
1555 error = -ENOMEM; 1597 error = -ENOMEM;
1556 goto free_ifree; 1598 goto free_fdblocks;
1557 } 1599 }
1558 1600
1559 for_each_online_cpu(i) { 1601 for_each_online_cpu(i) {
@@ -1577,6 +1619,8 @@ xfs_icsb_init_counters(
1577 1619
1578 return 0; 1620 return 0;
1579 1621
1622free_fdblocks:
1623 percpu_counter_destroy(&mp->m_fdblocks);
1580free_ifree: 1624free_ifree:
1581 percpu_counter_destroy(&mp->m_ifree); 1625 percpu_counter_destroy(&mp->m_ifree);
1582free_icount: 1626free_icount:
@@ -1590,6 +1634,7 @@ xfs_icsb_reinit_counters(
1590{ 1634{
1591 percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount); 1635 percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount);
1592 percpu_counter_set(&mp->m_ifree, mp->m_sb.sb_ifree); 1636 percpu_counter_set(&mp->m_ifree, mp->m_sb.sb_ifree);
1637 percpu_counter_set(&mp->m_fdblocks, mp->m_sb.sb_fdblocks);
1593 1638
1594 xfs_icsb_lock(mp); 1639 xfs_icsb_lock(mp);
1595 /* 1640 /*
@@ -1597,7 +1642,6 @@ xfs_icsb_reinit_counters(
1597 * initial balance kicks us off correctly 1642 * initial balance kicks us off correctly
1598 */ 1643 */
1599 mp->m_icsb_counters = -1; 1644 mp->m_icsb_counters = -1;
1600 xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
1601 xfs_icsb_unlock(mp); 1645 xfs_icsb_unlock(mp);
1602} 1646}
1603 1647
@@ -1612,6 +1656,7 @@ xfs_icsb_destroy_counters(
1612 1656
1613 percpu_counter_destroy(&mp->m_icount); 1657 percpu_counter_destroy(&mp->m_icount);
1614 percpu_counter_destroy(&mp->m_ifree); 1658 percpu_counter_destroy(&mp->m_ifree);
1659 percpu_counter_destroy(&mp->m_fdblocks);
1615 1660
1616 mutex_destroy(&mp->m_icsb_mutex); 1661 mutex_destroy(&mp->m_icsb_mutex);
1617} 1662}
@@ -1665,18 +1710,11 @@ xfs_icsb_count(
1665 xfs_icsb_cnts_t *cnt, 1710 xfs_icsb_cnts_t *cnt,
1666 int flags) 1711 int flags)
1667{ 1712{
1668 xfs_icsb_cnts_t *cntp;
1669 int i;
1670
1671 memset(cnt, 0, sizeof(xfs_icsb_cnts_t)); 1713 memset(cnt, 0, sizeof(xfs_icsb_cnts_t));
1672 1714
1673 if (!(flags & XFS_ICSB_LAZY_COUNT)) 1715 if (!(flags & XFS_ICSB_LAZY_COUNT))
1674 xfs_icsb_lock_all_counters(mp); 1716 xfs_icsb_lock_all_counters(mp);
1675 1717
1676 for_each_online_cpu(i) {
1677 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1678 cnt->icsb_fdblocks += cntp->icsb_fdblocks;
1679 }
1680 1718
1681 if (!(flags & XFS_ICSB_LAZY_COUNT)) 1719 if (!(flags & XFS_ICSB_LAZY_COUNT))
1682 xfs_icsb_unlock_all_counters(mp); 1720 xfs_icsb_unlock_all_counters(mp);
@@ -1687,7 +1725,6 @@ xfs_icsb_counter_disabled(
1687 xfs_mount_t *mp, 1725 xfs_mount_t *mp,
1688 xfs_sb_field_t field) 1726 xfs_sb_field_t field)
1689{ 1727{
1690 ASSERT(field == XFS_SBS_FDBLOCKS);
1691 return test_bit(field, &mp->m_icsb_counters); 1728 return test_bit(field, &mp->m_icsb_counters);
1692} 1729}
1693 1730
@@ -1698,8 +1735,6 @@ xfs_icsb_disable_counter(
1698{ 1735{
1699 xfs_icsb_cnts_t cnt; 1736 xfs_icsb_cnts_t cnt;
1700 1737
1701 ASSERT(field == XFS_SBS_FDBLOCKS);
1702
1703 /* 1738 /*
1704 * If we are already disabled, then there is nothing to do 1739 * If we are already disabled, then there is nothing to do
1705 * here. We check before locking all the counters to avoid 1740 * here. We check before locking all the counters to avoid
@@ -1717,9 +1752,6 @@ xfs_icsb_disable_counter(
1717 1752
1718 xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT); 1753 xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT);
1719 switch(field) { 1754 switch(field) {
1720 case XFS_SBS_FDBLOCKS:
1721 mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
1722 break;
1723 default: 1755 default:
1724 BUG(); 1756 BUG();
1725 } 1757 }
@@ -1735,18 +1767,11 @@ xfs_icsb_enable_counter(
1735 uint64_t count, 1767 uint64_t count,
1736 uint64_t resid) 1768 uint64_t resid)
1737{ 1769{
1738 xfs_icsb_cnts_t *cntp;
1739 int i; 1770 int i;
1740 1771
1741 ASSERT(field == XFS_SBS_FDBLOCKS);
1742
1743 xfs_icsb_lock_all_counters(mp); 1772 xfs_icsb_lock_all_counters(mp);
1744 for_each_online_cpu(i) { 1773 for_each_online_cpu(i) {
1745 cntp = per_cpu_ptr(mp->m_sb_cnts, i);
1746 switch (field) { 1774 switch (field) {
1747 case XFS_SBS_FDBLOCKS:
1748 cntp->icsb_fdblocks = count + resid;
1749 break;
1750 default: 1775 default:
1751 BUG(); 1776 BUG();
1752 break; 1777 break;
@@ -1765,9 +1790,6 @@ xfs_icsb_sync_counters_locked(
1765 xfs_icsb_cnts_t cnt; 1790 xfs_icsb_cnts_t cnt;
1766 1791
1767 xfs_icsb_count(mp, &cnt, flags); 1792 xfs_icsb_count(mp, &cnt, flags);
1768
1769 if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS))
1770 mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
1771} 1793}
1772 1794
1773/* 1795/*
@@ -1809,20 +1831,12 @@ xfs_icsb_balance_counter_locked(
1809 int min_per_cpu) 1831 int min_per_cpu)
1810{ 1832{
1811 uint64_t count, resid; 1833 uint64_t count, resid;
1812 int weight = num_online_cpus();
1813 uint64_t min = (uint64_t)min_per_cpu;
1814 1834
1815 /* disable counter and sync counter */ 1835 /* disable counter and sync counter */
1816 xfs_icsb_disable_counter(mp, field); 1836 xfs_icsb_disable_counter(mp, field);
1817 1837
1818 /* update counters - first CPU gets residual*/ 1838 /* update counters - first CPU gets residual*/
1819 switch (field) { 1839 switch (field) {
1820 case XFS_SBS_FDBLOCKS:
1821 count = mp->m_sb.sb_fdblocks;
1822 resid = do_div(count, weight);
1823 if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp)))
1824 return;
1825 break;
1826 default: 1840 default:
1827 BUG(); 1841 BUG();
1828 count = resid = 0; /* quiet, gcc */ 1842 count = resid = 0; /* quiet, gcc */
@@ -1851,7 +1865,6 @@ xfs_icsb_modify_counters(
1851 int rsvd) 1865 int rsvd)
1852{ 1866{
1853 xfs_icsb_cnts_t *icsbp; 1867 xfs_icsb_cnts_t *icsbp;
1854 long long lcounter; /* long counter for 64 bit fields */
1855 int ret = 0; 1868 int ret = 0;
1856 1869
1857 might_sleep(); 1870 might_sleep();
@@ -1871,18 +1884,9 @@ again:
1871 } 1884 }
1872 1885
1873 switch (field) { 1886 switch (field) {
1874 case XFS_SBS_FDBLOCKS:
1875 BUG_ON((mp->m_resblks - mp->m_resblks_avail) != 0);
1876
1877 lcounter = icsbp->icsb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
1878 lcounter += delta;
1879 if (unlikely(lcounter < 0))
1880 goto balance_counter;
1881 icsbp->icsb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
1882 break;
1883 default: 1887 default:
1884 BUG(); 1888 BUG();
1885 break; 1889 goto balance_counter; /* be still, gcc */
1886 } 1890 }
1887 xfs_icsb_unlock_cntr(icsbp); 1891 xfs_icsb_unlock_cntr(icsbp);
1888 preempt_enable(); 1892 preempt_enable();
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 7ce997d43d81..84b745fbc787 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -85,6 +85,7 @@ typedef struct xfs_mount {
85 spinlock_t m_sb_lock; /* sb counter lock */ 85 spinlock_t m_sb_lock; /* sb counter lock */
86 struct percpu_counter m_icount; /* allocated inodes counter */ 86 struct percpu_counter m_icount; /* allocated inodes counter */
87 struct percpu_counter m_ifree; /* free inodes counter */ 87 struct percpu_counter m_ifree; /* free inodes counter */
88 struct percpu_counter m_fdblocks; /* free block counter */
88 89
89 struct xfs_buf *m_sb_bp; /* buffer for superblock */ 90 struct xfs_buf *m_sb_bp; /* buffer for superblock */
90 char *m_fsname; /* filesystem name */ 91 char *m_fsname; /* filesystem name */
@@ -393,6 +394,8 @@ extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
393 uint, int); 394 uint, int);
394extern int xfs_mod_icount(struct xfs_mount *mp, int64_t delta); 395extern int xfs_mod_icount(struct xfs_mount *mp, int64_t delta);
395extern int xfs_mod_ifree(struct xfs_mount *mp, int64_t delta); 396extern int xfs_mod_ifree(struct xfs_mount *mp, int64_t delta);
397extern int xfs_mod_fdblocks(struct xfs_mount *mp, int64_t delta,
398 bool reserved);
396extern int xfs_mount_log_sb(xfs_mount_t *); 399extern int xfs_mount_log_sb(xfs_mount_t *);
397extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); 400extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
398extern int xfs_readsb(xfs_mount_t *, int); 401extern int xfs_readsb(xfs_mount_t *, int);
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 049147776ee1..9ec75074026d 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1087,6 +1087,7 @@ xfs_fs_statfs(
1087 __uint64_t fakeinos, id; 1087 __uint64_t fakeinos, id;
1088 __uint64_t icount; 1088 __uint64_t icount;
1089 __uint64_t ifree; 1089 __uint64_t ifree;
1090 __uint64_t fdblocks;
1090 xfs_extlen_t lsize; 1091 xfs_extlen_t lsize;
1091 __int64_t ffree; 1092 __int64_t ffree;
1092 1093
@@ -1100,13 +1101,17 @@ xfs_fs_statfs(
1100 xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); 1101 xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
1101 icount = percpu_counter_sum(&mp->m_icount); 1102 icount = percpu_counter_sum(&mp->m_icount);
1102 ifree = percpu_counter_sum(&mp->m_ifree); 1103 ifree = percpu_counter_sum(&mp->m_ifree);
1104 fdblocks = percpu_counter_sum(&mp->m_fdblocks);
1103 1105
1104 spin_lock(&mp->m_sb_lock); 1106 spin_lock(&mp->m_sb_lock);
1105 statp->f_bsize = sbp->sb_blocksize; 1107 statp->f_bsize = sbp->sb_blocksize;
1106 lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; 1108 lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
1107 statp->f_blocks = sbp->sb_dblocks - lsize; 1109 statp->f_blocks = sbp->sb_dblocks - lsize;
1108 statp->f_bfree = statp->f_bavail = 1110 spin_unlock(&mp->m_sb_lock);
1109 sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); 1111
1112 statp->f_bfree = fdblocks - XFS_ALLOC_SET_ASIDE(mp);
1113 statp->f_bavail = statp->f_bfree;
1114
1110 fakeinos = statp->f_bfree << sbp->sb_inopblog; 1115 fakeinos = statp->f_bfree << sbp->sb_inopblog;
1111 statp->f_files = MIN(icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); 1116 statp->f_files = MIN(icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
1112 if (mp->m_maxicount) 1117 if (mp->m_maxicount)
@@ -1123,7 +1128,6 @@ xfs_fs_statfs(
1123 ffree = statp->f_files - (icount - ifree); 1128 ffree = statp->f_files - (icount - ifree);
1124 statp->f_ffree = max_t(__int64_t, ffree, 0); 1129 statp->f_ffree = max_t(__int64_t, ffree, 0);
1125 1130
1126 spin_unlock(&mp->m_sb_lock);
1127 1131
1128 if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && 1132 if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
1129 ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) == 1133 ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) ==
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;