diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 76 |
1 files changed, 33 insertions, 43 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 702ea6a7e648..650e8f18cd2a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1114,6 +1114,20 @@ xfs_mod_icount( | |||
1114 | return 0; | 1114 | return 0; |
1115 | } | 1115 | } |
1116 | 1116 | ||
1117 | |||
1118 | int | ||
1119 | xfs_mod_ifree( | ||
1120 | struct xfs_mount *mp, | ||
1121 | int64_t delta) | ||
1122 | { | ||
1123 | percpu_counter_add(&mp->m_ifree, delta); | ||
1124 | if (percpu_counter_compare(&mp->m_ifree, 0) < 0) { | ||
1125 | ASSERT(0); | ||
1126 | percpu_counter_add(&mp->m_ifree, -delta); | ||
1127 | return -EINVAL; | ||
1128 | } | ||
1129 | return 0; | ||
1130 | } | ||
1117 | /* | 1131 | /* |
1118 | * xfs_mod_incore_sb_unlocked() is a utility routine commonly used to apply | 1132 | * xfs_mod_incore_sb_unlocked() is a utility routine commonly used to apply |
1119 | * a delta to a specified field in the in-core superblock. Simply | 1133 | * a delta to a specified field in the in-core superblock. Simply |
@@ -1142,17 +1156,9 @@ xfs_mod_incore_sb_unlocked( | |||
1142 | */ | 1156 | */ |
1143 | switch (field) { | 1157 | switch (field) { |
1144 | case XFS_SBS_ICOUNT: | 1158 | case XFS_SBS_ICOUNT: |
1145 | ASSERT(0); | ||
1146 | return -ENOSPC; | ||
1147 | case XFS_SBS_IFREE: | 1159 | case XFS_SBS_IFREE: |
1148 | lcounter = (long long)mp->m_sb.sb_ifree; | 1160 | ASSERT(0); |
1149 | lcounter += delta; | 1161 | return -EINVAL; |
1150 | if (lcounter < 0) { | ||
1151 | ASSERT(0); | ||
1152 | return -EINVAL; | ||
1153 | } | ||
1154 | mp->m_sb.sb_ifree = lcounter; | ||
1155 | return 0; | ||
1156 | case XFS_SBS_FDBLOCKS: | 1162 | case XFS_SBS_FDBLOCKS: |
1157 | lcounter = (long long) | 1163 | lcounter = (long long) |
1158 | mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | 1164 | mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); |
@@ -1502,7 +1508,6 @@ xfs_icsb_cpu_notify( | |||
1502 | case CPU_ONLINE: | 1508 | case CPU_ONLINE: |
1503 | case CPU_ONLINE_FROZEN: | 1509 | case CPU_ONLINE_FROZEN: |
1504 | xfs_icsb_lock(mp); | 1510 | xfs_icsb_lock(mp); |
1505 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); | ||
1506 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); | 1511 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); |
1507 | xfs_icsb_unlock(mp); | 1512 | xfs_icsb_unlock(mp); |
1508 | break; | 1513 | break; |
@@ -1513,15 +1518,12 @@ xfs_icsb_cpu_notify( | |||
1513 | * re-enable the counters. */ | 1518 | * re-enable the counters. */ |
1514 | xfs_icsb_lock(mp); | 1519 | xfs_icsb_lock(mp); |
1515 | spin_lock(&mp->m_sb_lock); | 1520 | spin_lock(&mp->m_sb_lock); |
1516 | xfs_icsb_disable_counter(mp, XFS_SBS_IFREE); | ||
1517 | xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS); | 1521 | xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS); |
1518 | 1522 | ||
1519 | mp->m_sb.sb_ifree += cntp->icsb_ifree; | ||
1520 | mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks; | 1523 | mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks; |
1521 | 1524 | ||
1522 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); | 1525 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1523 | 1526 | ||
1524 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_IFREE, 0); | ||
1525 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_FDBLOCKS, 0); | 1527 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_FDBLOCKS, 0); |
1526 | spin_unlock(&mp->m_sb_lock); | 1528 | spin_unlock(&mp->m_sb_lock); |
1527 | xfs_icsb_unlock(mp); | 1529 | xfs_icsb_unlock(mp); |
@@ -1544,10 +1546,14 @@ xfs_icsb_init_counters( | |||
1544 | if (error) | 1546 | if (error) |
1545 | return error; | 1547 | return error; |
1546 | 1548 | ||
1549 | error = percpu_counter_init(&mp->m_ifree, 0, GFP_KERNEL); | ||
1550 | if (error) | ||
1551 | goto free_icount; | ||
1552 | |||
1547 | mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t); | 1553 | mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t); |
1548 | if (!mp->m_sb_cnts) { | 1554 | if (!mp->m_sb_cnts) { |
1549 | percpu_counter_destroy(&mp->m_icount); | 1555 | error = -ENOMEM; |
1550 | return -ENOMEM; | 1556 | goto free_ifree; |
1551 | } | 1557 | } |
1552 | 1558 | ||
1553 | for_each_online_cpu(i) { | 1559 | for_each_online_cpu(i) { |
@@ -1570,6 +1576,12 @@ xfs_icsb_init_counters( | |||
1570 | #endif /* CONFIG_HOTPLUG_CPU */ | 1576 | #endif /* CONFIG_HOTPLUG_CPU */ |
1571 | 1577 | ||
1572 | return 0; | 1578 | return 0; |
1579 | |||
1580 | free_ifree: | ||
1581 | percpu_counter_destroy(&mp->m_ifree); | ||
1582 | free_icount: | ||
1583 | percpu_counter_destroy(&mp->m_icount); | ||
1584 | return error; | ||
1573 | } | 1585 | } |
1574 | 1586 | ||
1575 | void | 1587 | void |
@@ -1577,6 +1589,7 @@ xfs_icsb_reinit_counters( | |||
1577 | xfs_mount_t *mp) | 1589 | xfs_mount_t *mp) |
1578 | { | 1590 | { |
1579 | percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount); | 1591 | percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount); |
1592 | percpu_counter_set(&mp->m_ifree, mp->m_sb.sb_ifree); | ||
1580 | 1593 | ||
1581 | xfs_icsb_lock(mp); | 1594 | xfs_icsb_lock(mp); |
1582 | /* | 1595 | /* |
@@ -1584,7 +1597,6 @@ xfs_icsb_reinit_counters( | |||
1584 | * initial balance kicks us off correctly | 1597 | * initial balance kicks us off correctly |
1585 | */ | 1598 | */ |
1586 | mp->m_icsb_counters = -1; | 1599 | mp->m_icsb_counters = -1; |
1587 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); | ||
1588 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); | 1600 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); |
1589 | xfs_icsb_unlock(mp); | 1601 | xfs_icsb_unlock(mp); |
1590 | } | 1602 | } |
@@ -1599,6 +1611,7 @@ xfs_icsb_destroy_counters( | |||
1599 | } | 1611 | } |
1600 | 1612 | ||
1601 | percpu_counter_destroy(&mp->m_icount); | 1613 | percpu_counter_destroy(&mp->m_icount); |
1614 | percpu_counter_destroy(&mp->m_ifree); | ||
1602 | 1615 | ||
1603 | mutex_destroy(&mp->m_icsb_mutex); | 1616 | mutex_destroy(&mp->m_icsb_mutex); |
1604 | } | 1617 | } |
@@ -1662,7 +1675,6 @@ xfs_icsb_count( | |||
1662 | 1675 | ||
1663 | for_each_online_cpu(i) { | 1676 | for_each_online_cpu(i) { |
1664 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); | 1677 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); |
1665 | cnt->icsb_ifree += cntp->icsb_ifree; | ||
1666 | cnt->icsb_fdblocks += cntp->icsb_fdblocks; | 1678 | cnt->icsb_fdblocks += cntp->icsb_fdblocks; |
1667 | } | 1679 | } |
1668 | 1680 | ||
@@ -1675,7 +1687,7 @@ xfs_icsb_counter_disabled( | |||
1675 | xfs_mount_t *mp, | 1687 | xfs_mount_t *mp, |
1676 | xfs_sb_field_t field) | 1688 | xfs_sb_field_t field) |
1677 | { | 1689 | { |
1678 | ASSERT((field >= XFS_SBS_IFREE) && (field <= XFS_SBS_FDBLOCKS)); | 1690 | ASSERT(field == XFS_SBS_FDBLOCKS); |
1679 | return test_bit(field, &mp->m_icsb_counters); | 1691 | return test_bit(field, &mp->m_icsb_counters); |
1680 | } | 1692 | } |
1681 | 1693 | ||
@@ -1686,7 +1698,7 @@ xfs_icsb_disable_counter( | |||
1686 | { | 1698 | { |
1687 | xfs_icsb_cnts_t cnt; | 1699 | xfs_icsb_cnts_t cnt; |
1688 | 1700 | ||
1689 | ASSERT((field >= XFS_SBS_IFREE) && (field <= XFS_SBS_FDBLOCKS)); | 1701 | ASSERT(field == XFS_SBS_FDBLOCKS); |
1690 | 1702 | ||
1691 | /* | 1703 | /* |
1692 | * If we are already disabled, then there is nothing to do | 1704 | * If we are already disabled, then there is nothing to do |
@@ -1705,9 +1717,6 @@ xfs_icsb_disable_counter( | |||
1705 | 1717 | ||
1706 | xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT); | 1718 | xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT); |
1707 | switch(field) { | 1719 | switch(field) { |
1708 | case XFS_SBS_IFREE: | ||
1709 | mp->m_sb.sb_ifree = cnt.icsb_ifree; | ||
1710 | break; | ||
1711 | case XFS_SBS_FDBLOCKS: | 1720 | case XFS_SBS_FDBLOCKS: |
1712 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; | 1721 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; |
1713 | break; | 1722 | break; |
@@ -1729,15 +1738,12 @@ xfs_icsb_enable_counter( | |||
1729 | xfs_icsb_cnts_t *cntp; | 1738 | xfs_icsb_cnts_t *cntp; |
1730 | int i; | 1739 | int i; |
1731 | 1740 | ||
1732 | ASSERT((field >= XFS_SBS_IFREE) && (field <= XFS_SBS_FDBLOCKS)); | 1741 | ASSERT(field == XFS_SBS_FDBLOCKS); |
1733 | 1742 | ||
1734 | xfs_icsb_lock_all_counters(mp); | 1743 | xfs_icsb_lock_all_counters(mp); |
1735 | for_each_online_cpu(i) { | 1744 | for_each_online_cpu(i) { |
1736 | cntp = per_cpu_ptr(mp->m_sb_cnts, i); | 1745 | cntp = per_cpu_ptr(mp->m_sb_cnts, i); |
1737 | switch (field) { | 1746 | switch (field) { |
1738 | case XFS_SBS_IFREE: | ||
1739 | cntp->icsb_ifree = count + resid; | ||
1740 | break; | ||
1741 | case XFS_SBS_FDBLOCKS: | 1747 | case XFS_SBS_FDBLOCKS: |
1742 | cntp->icsb_fdblocks = count + resid; | 1748 | cntp->icsb_fdblocks = count + resid; |
1743 | break; | 1749 | break; |
@@ -1760,8 +1766,6 @@ xfs_icsb_sync_counters_locked( | |||
1760 | 1766 | ||
1761 | xfs_icsb_count(mp, &cnt, flags); | 1767 | xfs_icsb_count(mp, &cnt, flags); |
1762 | 1768 | ||
1763 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE)) | ||
1764 | mp->m_sb.sb_ifree = cnt.icsb_ifree; | ||
1765 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS)) | 1769 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS)) |
1766 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; | 1770 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; |
1767 | } | 1771 | } |
@@ -1813,12 +1817,6 @@ xfs_icsb_balance_counter_locked( | |||
1813 | 1817 | ||
1814 | /* update counters - first CPU gets residual*/ | 1818 | /* update counters - first CPU gets residual*/ |
1815 | switch (field) { | 1819 | switch (field) { |
1816 | case XFS_SBS_IFREE: | ||
1817 | count = mp->m_sb.sb_ifree; | ||
1818 | resid = do_div(count, weight); | ||
1819 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) | ||
1820 | return; | ||
1821 | break; | ||
1822 | case XFS_SBS_FDBLOCKS: | 1820 | case XFS_SBS_FDBLOCKS: |
1823 | count = mp->m_sb.sb_fdblocks; | 1821 | count = mp->m_sb.sb_fdblocks; |
1824 | resid = do_div(count, weight); | 1822 | resid = do_div(count, weight); |
@@ -1873,14 +1871,6 @@ again: | |||
1873 | } | 1871 | } |
1874 | 1872 | ||
1875 | switch (field) { | 1873 | switch (field) { |
1876 | case XFS_SBS_IFREE: | ||
1877 | lcounter = icsbp->icsb_ifree; | ||
1878 | lcounter += delta; | ||
1879 | if (unlikely(lcounter < 0)) | ||
1880 | goto balance_counter; | ||
1881 | icsbp->icsb_ifree = lcounter; | ||
1882 | break; | ||
1883 | |||
1884 | case XFS_SBS_FDBLOCKS: | 1874 | case XFS_SBS_FDBLOCKS: |
1885 | BUG_ON((mp->m_resblks - mp->m_resblks_avail) != 0); | 1875 | BUG_ON((mp->m_resblks - mp->m_resblks_avail) != 0); |
1886 | 1876 | ||