diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 232 |
1 files changed, 139 insertions, 93 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 397730f570b9..37c612ce3d05 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -52,21 +52,19 @@ STATIC void xfs_unmountfs_wait(xfs_mount_t *); | |||
52 | 52 | ||
53 | #ifdef HAVE_PERCPU_SB | 53 | #ifdef HAVE_PERCPU_SB |
54 | STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); | 54 | STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); |
55 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, int); | 55 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, int, |
56 | int); | ||
56 | STATIC void xfs_icsb_sync_counters(xfs_mount_t *); | 57 | STATIC void xfs_icsb_sync_counters(xfs_mount_t *); |
57 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, | 58 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, |
58 | int, int); | 59 | int, int); |
59 | STATIC int xfs_icsb_modify_counters_locked(xfs_mount_t *, xfs_sb_field_t, | ||
60 | int, int); | ||
61 | STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); | 60 | STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); |
62 | 61 | ||
63 | #else | 62 | #else |
64 | 63 | ||
65 | #define xfs_icsb_destroy_counters(mp) do { } while (0) | 64 | #define xfs_icsb_destroy_counters(mp) do { } while (0) |
66 | #define xfs_icsb_balance_counter(mp, a, b) do { } while (0) | 65 | #define xfs_icsb_balance_counter(mp, a, b, c) do { } while (0) |
67 | #define xfs_icsb_sync_counters(mp) do { } while (0) | 66 | #define xfs_icsb_sync_counters(mp) do { } while (0) |
68 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) | 67 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) |
69 | #define xfs_icsb_modify_counters_locked(mp, a, b, c) do { } while (0) | ||
70 | 68 | ||
71 | #endif | 69 | #endif |
72 | 70 | ||
@@ -545,9 +543,11 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
545 | ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); | 543 | ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); |
546 | } | 544 | } |
547 | 545 | ||
548 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); | 546 | mutex_lock(&mp->m_icsb_mutex); |
549 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); | 547 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); |
550 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); | 548 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); |
549 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0, 0); | ||
550 | mutex_unlock(&mp->m_icsb_mutex); | ||
551 | 551 | ||
552 | mp->m_sb_bp = bp; | 552 | mp->m_sb_bp = bp; |
553 | xfs_buf_relse(bp); | 553 | xfs_buf_relse(bp); |
@@ -1485,9 +1485,11 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | |||
1485 | case XFS_SBS_IFREE: | 1485 | case XFS_SBS_IFREE: |
1486 | case XFS_SBS_FDBLOCKS: | 1486 | case XFS_SBS_FDBLOCKS: |
1487 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { | 1487 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { |
1488 | status = xfs_icsb_modify_counters_locked(mp, | 1488 | XFS_SB_UNLOCK(mp, s); |
1489 | status = xfs_icsb_modify_counters(mp, | ||
1489 | msbp->msb_field, | 1490 | msbp->msb_field, |
1490 | msbp->msb_delta, rsvd); | 1491 | msbp->msb_delta, rsvd); |
1492 | s = XFS_SB_LOCK(mp); | ||
1491 | break; | 1493 | break; |
1492 | } | 1494 | } |
1493 | /* FALLTHROUGH */ | 1495 | /* FALLTHROUGH */ |
@@ -1521,11 +1523,12 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | |||
1521 | case XFS_SBS_IFREE: | 1523 | case XFS_SBS_IFREE: |
1522 | case XFS_SBS_FDBLOCKS: | 1524 | case XFS_SBS_FDBLOCKS: |
1523 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { | 1525 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { |
1524 | status = | 1526 | XFS_SB_UNLOCK(mp, s); |
1525 | xfs_icsb_modify_counters_locked(mp, | 1527 | status = xfs_icsb_modify_counters(mp, |
1526 | msbp->msb_field, | 1528 | msbp->msb_field, |
1527 | -(msbp->msb_delta), | 1529 | -(msbp->msb_delta), |
1528 | rsvd); | 1530 | rsvd); |
1531 | s = XFS_SB_LOCK(mp); | ||
1529 | break; | 1532 | break; |
1530 | } | 1533 | } |
1531 | /* FALLTHROUGH */ | 1534 | /* FALLTHROUGH */ |
@@ -1733,14 +1736,17 @@ xfs_icsb_cpu_notify( | |||
1733 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); | 1736 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1734 | break; | 1737 | break; |
1735 | case CPU_ONLINE: | 1738 | case CPU_ONLINE: |
1736 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); | 1739 | mutex_lock(&mp->m_icsb_mutex); |
1737 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); | 1740 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); |
1738 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); | 1741 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); |
1742 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0, 0); | ||
1743 | mutex_unlock(&mp->m_icsb_mutex); | ||
1739 | break; | 1744 | break; |
1740 | case CPU_DEAD: | 1745 | case CPU_DEAD: |
1741 | /* Disable all the counters, then fold the dead cpu's | 1746 | /* Disable all the counters, then fold the dead cpu's |
1742 | * count into the total on the global superblock and | 1747 | * count into the total on the global superblock and |
1743 | * re-enable the counters. */ | 1748 | * re-enable the counters. */ |
1749 | mutex_lock(&mp->m_icsb_mutex); | ||
1744 | s = XFS_SB_LOCK(mp); | 1750 | s = XFS_SB_LOCK(mp); |
1745 | xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT); | 1751 | xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT); |
1746 | xfs_icsb_disable_counter(mp, XFS_SBS_IFREE); | 1752 | xfs_icsb_disable_counter(mp, XFS_SBS_IFREE); |
@@ -1752,10 +1758,14 @@ xfs_icsb_cpu_notify( | |||
1752 | 1758 | ||
1753 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); | 1759 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1754 | 1760 | ||
1755 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED); | 1761 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, |
1756 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED); | 1762 | XFS_ICSB_SB_LOCKED, 0); |
1757 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, XFS_ICSB_SB_LOCKED); | 1763 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, |
1764 | XFS_ICSB_SB_LOCKED, 0); | ||
1765 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, | ||
1766 | XFS_ICSB_SB_LOCKED, 0); | ||
1758 | XFS_SB_UNLOCK(mp, s); | 1767 | XFS_SB_UNLOCK(mp, s); |
1768 | mutex_unlock(&mp->m_icsb_mutex); | ||
1759 | break; | 1769 | break; |
1760 | } | 1770 | } |
1761 | 1771 | ||
@@ -1784,6 +1794,9 @@ xfs_icsb_init_counters( | |||
1784 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); | 1794 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); |
1785 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); | 1795 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1786 | } | 1796 | } |
1797 | |||
1798 | mutex_init(&mp->m_icsb_mutex); | ||
1799 | |||
1787 | /* | 1800 | /* |
1788 | * start with all counters disabled so that the | 1801 | * start with all counters disabled so that the |
1789 | * initial balance kicks us off correctly | 1802 | * initial balance kicks us off correctly |
@@ -1888,6 +1901,17 @@ xfs_icsb_disable_counter( | |||
1888 | 1901 | ||
1889 | ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS)); | 1902 | ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS)); |
1890 | 1903 | ||
1904 | /* | ||
1905 | * If we are already disabled, then there is nothing to do | ||
1906 | * here. We check before locking all the counters to avoid | ||
1907 | * the expensive lock operation when being called in the | ||
1908 | * slow path and the counter is already disabled. This is | ||
1909 | * safe because the only time we set or clear this state is under | ||
1910 | * the m_icsb_mutex. | ||
1911 | */ | ||
1912 | if (xfs_icsb_counter_disabled(mp, field)) | ||
1913 | return 0; | ||
1914 | |||
1891 | xfs_icsb_lock_all_counters(mp); | 1915 | xfs_icsb_lock_all_counters(mp); |
1892 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { | 1916 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { |
1893 | /* drain back to superblock */ | 1917 | /* drain back to superblock */ |
@@ -1997,24 +2021,33 @@ xfs_icsb_sync_counters_lazy( | |||
1997 | /* | 2021 | /* |
1998 | * Balance and enable/disable counters as necessary. | 2022 | * Balance and enable/disable counters as necessary. |
1999 | * | 2023 | * |
2000 | * Thresholds for re-enabling counters are somewhat magic. | 2024 | * Thresholds for re-enabling counters are somewhat magic. inode counts are |
2001 | * inode counts are chosen to be the same number as single | 2025 | * chosen to be the same number as single on disk allocation chunk per CPU, and |
2002 | * on disk allocation chunk per CPU, and free blocks is | 2026 | * free blocks is something far enough zero that we aren't going thrash when we |
2003 | * something far enough zero that we aren't going thrash | 2027 | * get near ENOSPC. We also need to supply a minimum we require per cpu to |
2004 | * when we get near ENOSPC. | 2028 | * prevent looping endlessly when xfs_alloc_space asks for more than will |
2029 | * be distributed to a single CPU but each CPU has enough blocks to be | ||
2030 | * reenabled. | ||
2031 | * | ||
2032 | * Note that we can be called when counters are already disabled. | ||
2033 | * xfs_icsb_disable_counter() optimises the counter locking in this case to | ||
2034 | * prevent locking every per-cpu counter needlessly. | ||
2005 | */ | 2035 | */ |
2006 | #define XFS_ICSB_INO_CNTR_REENABLE 64 | 2036 | |
2037 | #define XFS_ICSB_INO_CNTR_REENABLE (uint64_t)64 | ||
2007 | #define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \ | 2038 | #define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \ |
2008 | (512 + XFS_ALLOC_SET_ASIDE(mp)) | 2039 | (uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp)) |
2009 | STATIC void | 2040 | STATIC void |
2010 | xfs_icsb_balance_counter( | 2041 | xfs_icsb_balance_counter( |
2011 | xfs_mount_t *mp, | 2042 | xfs_mount_t *mp, |
2012 | xfs_sb_field_t field, | 2043 | xfs_sb_field_t field, |
2013 | int flags) | 2044 | int flags, |
2045 | int min_per_cpu) | ||
2014 | { | 2046 | { |
2015 | uint64_t count, resid; | 2047 | uint64_t count, resid; |
2016 | int weight = num_online_cpus(); | 2048 | int weight = num_online_cpus(); |
2017 | int s; | 2049 | int s; |
2050 | uint64_t min = (uint64_t)min_per_cpu; | ||
2018 | 2051 | ||
2019 | if (!(flags & XFS_ICSB_SB_LOCKED)) | 2052 | if (!(flags & XFS_ICSB_SB_LOCKED)) |
2020 | s = XFS_SB_LOCK(mp); | 2053 | s = XFS_SB_LOCK(mp); |
@@ -2027,19 +2060,19 @@ xfs_icsb_balance_counter( | |||
2027 | case XFS_SBS_ICOUNT: | 2060 | case XFS_SBS_ICOUNT: |
2028 | count = mp->m_sb.sb_icount; | 2061 | count = mp->m_sb.sb_icount; |
2029 | resid = do_div(count, weight); | 2062 | resid = do_div(count, weight); |
2030 | if (count < XFS_ICSB_INO_CNTR_REENABLE) | 2063 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) |
2031 | goto out; | 2064 | goto out; |
2032 | break; | 2065 | break; |
2033 | case XFS_SBS_IFREE: | 2066 | case XFS_SBS_IFREE: |
2034 | count = mp->m_sb.sb_ifree; | 2067 | count = mp->m_sb.sb_ifree; |
2035 | resid = do_div(count, weight); | 2068 | resid = do_div(count, weight); |
2036 | if (count < XFS_ICSB_INO_CNTR_REENABLE) | 2069 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) |
2037 | goto out; | 2070 | goto out; |
2038 | break; | 2071 | break; |
2039 | case XFS_SBS_FDBLOCKS: | 2072 | case XFS_SBS_FDBLOCKS: |
2040 | count = mp->m_sb.sb_fdblocks; | 2073 | count = mp->m_sb.sb_fdblocks; |
2041 | resid = do_div(count, weight); | 2074 | resid = do_div(count, weight); |
2042 | if (count < XFS_ICSB_FDBLK_CNTR_REENABLE(mp)) | 2075 | if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp))) |
2043 | goto out; | 2076 | goto out; |
2044 | break; | 2077 | break; |
2045 | default: | 2078 | default: |
@@ -2054,32 +2087,39 @@ out: | |||
2054 | XFS_SB_UNLOCK(mp, s); | 2087 | XFS_SB_UNLOCK(mp, s); |
2055 | } | 2088 | } |
2056 | 2089 | ||
2057 | STATIC int | 2090 | int |
2058 | xfs_icsb_modify_counters_int( | 2091 | xfs_icsb_modify_counters( |
2059 | xfs_mount_t *mp, | 2092 | xfs_mount_t *mp, |
2060 | xfs_sb_field_t field, | 2093 | xfs_sb_field_t field, |
2061 | int delta, | 2094 | int delta, |
2062 | int rsvd, | 2095 | int rsvd) |
2063 | int flags) | ||
2064 | { | 2096 | { |
2065 | xfs_icsb_cnts_t *icsbp; | 2097 | xfs_icsb_cnts_t *icsbp; |
2066 | long long lcounter; /* long counter for 64 bit fields */ | 2098 | long long lcounter; /* long counter for 64 bit fields */ |
2067 | int cpu, s, locked = 0; | 2099 | int cpu, ret = 0, s; |
2068 | int ret = 0, balance_done = 0; | ||
2069 | 2100 | ||
2101 | might_sleep(); | ||
2070 | again: | 2102 | again: |
2071 | cpu = get_cpu(); | 2103 | cpu = get_cpu(); |
2072 | icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu), | 2104 | icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu); |
2073 | xfs_icsb_lock_cntr(icsbp); | 2105 | |
2106 | /* | ||
2107 | * if the counter is disabled, go to slow path | ||
2108 | */ | ||
2074 | if (unlikely(xfs_icsb_counter_disabled(mp, field))) | 2109 | if (unlikely(xfs_icsb_counter_disabled(mp, field))) |
2075 | goto slow_path; | 2110 | goto slow_path; |
2111 | xfs_icsb_lock_cntr(icsbp); | ||
2112 | if (unlikely(xfs_icsb_counter_disabled(mp, field))) { | ||
2113 | xfs_icsb_unlock_cntr(icsbp); | ||
2114 | goto slow_path; | ||
2115 | } | ||
2076 | 2116 | ||
2077 | switch (field) { | 2117 | switch (field) { |
2078 | case XFS_SBS_ICOUNT: | 2118 | case XFS_SBS_ICOUNT: |
2079 | lcounter = icsbp->icsb_icount; | 2119 | lcounter = icsbp->icsb_icount; |
2080 | lcounter += delta; | 2120 | lcounter += delta; |
2081 | if (unlikely(lcounter < 0)) | 2121 | if (unlikely(lcounter < 0)) |
2082 | goto slow_path; | 2122 | goto balance_counter; |
2083 | icsbp->icsb_icount = lcounter; | 2123 | icsbp->icsb_icount = lcounter; |
2084 | break; | 2124 | break; |
2085 | 2125 | ||
@@ -2087,7 +2127,7 @@ again: | |||
2087 | lcounter = icsbp->icsb_ifree; | 2127 | lcounter = icsbp->icsb_ifree; |
2088 | lcounter += delta; | 2128 | lcounter += delta; |
2089 | if (unlikely(lcounter < 0)) | 2129 | if (unlikely(lcounter < 0)) |
2090 | goto slow_path; | 2130 | goto balance_counter; |
2091 | icsbp->icsb_ifree = lcounter; | 2131 | icsbp->icsb_ifree = lcounter; |
2092 | break; | 2132 | break; |
2093 | 2133 | ||
@@ -2097,7 +2137,7 @@ again: | |||
2097 | lcounter = icsbp->icsb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | 2137 | lcounter = icsbp->icsb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); |
2098 | lcounter += delta; | 2138 | lcounter += delta; |
2099 | if (unlikely(lcounter < 0)) | 2139 | if (unlikely(lcounter < 0)) |
2100 | goto slow_path; | 2140 | goto balance_counter; |
2101 | icsbp->icsb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp); | 2141 | icsbp->icsb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp); |
2102 | break; | 2142 | break; |
2103 | default: | 2143 | default: |
@@ -2106,72 +2146,78 @@ again: | |||
2106 | } | 2146 | } |
2107 | xfs_icsb_unlock_cntr(icsbp); | 2147 | xfs_icsb_unlock_cntr(icsbp); |
2108 | put_cpu(); | 2148 | put_cpu(); |
2109 | if (locked) | ||
2110 | XFS_SB_UNLOCK(mp, s); | ||
2111 | return 0; | 2149 | return 0; |
2112 | 2150 | ||
2113 | /* | ||
2114 | * The slow path needs to be run with the SBLOCK | ||
2115 | * held so that we prevent other threads from | ||
2116 | * attempting to run this path at the same time. | ||
2117 | * this provides exclusion for the balancing code, | ||
2118 | * and exclusive fallback if the balance does not | ||
2119 | * provide enough resources to continue in an unlocked | ||
2120 | * manner. | ||
2121 | */ | ||
2122 | slow_path: | 2151 | slow_path: |
2123 | xfs_icsb_unlock_cntr(icsbp); | ||
2124 | put_cpu(); | 2152 | put_cpu(); |
2125 | 2153 | ||
2126 | /* need to hold superblock incase we need | 2154 | /* |
2127 | * to disable a counter */ | 2155 | * serialise with a mutex so we don't burn lots of cpu on |
2128 | if (!(flags & XFS_ICSB_SB_LOCKED)) { | 2156 | * the superblock lock. We still need to hold the superblock |
2129 | s = XFS_SB_LOCK(mp); | 2157 | * lock, however, when we modify the global structures. |
2130 | locked = 1; | 2158 | */ |
2131 | flags |= XFS_ICSB_SB_LOCKED; | 2159 | mutex_lock(&mp->m_icsb_mutex); |
2132 | } | 2160 | |
2133 | if (!balance_done) { | 2161 | /* |
2134 | xfs_icsb_balance_counter(mp, field, flags); | 2162 | * Now running atomically. |
2135 | balance_done = 1; | 2163 | * |
2164 | * If the counter is enabled, someone has beaten us to rebalancing. | ||
2165 | * Drop the lock and try again in the fast path.... | ||
2166 | */ | ||
2167 | if (!(xfs_icsb_counter_disabled(mp, field))) { | ||
2168 | mutex_unlock(&mp->m_icsb_mutex); | ||
2136 | goto again; | 2169 | goto again; |
2137 | } else { | ||
2138 | /* | ||
2139 | * we might not have enough on this local | ||
2140 | * cpu to allocate for a bulk request. | ||
2141 | * We need to drain this field from all CPUs | ||
2142 | * and disable the counter fastpath | ||
2143 | */ | ||
2144 | xfs_icsb_disable_counter(mp, field); | ||
2145 | } | 2170 | } |
2146 | 2171 | ||
2172 | /* | ||
2173 | * The counter is currently disabled. Because we are | ||
2174 | * running atomically here, we know a rebalance cannot | ||
2175 | * be in progress. Hence we can go straight to operating | ||
2176 | * on the global superblock. We do not call xfs_mod_incore_sb() | ||
2177 | * here even though we need to get the SB_LOCK. Doing so | ||
2178 | * will cause us to re-enter this function and deadlock. | ||
2179 | * Hence we get the SB_LOCK ourselves and then call | ||
2180 | * xfs_mod_incore_sb_unlocked() as the unlocked path operates | ||
2181 | * directly on the global counters. | ||
2182 | */ | ||
2183 | s = XFS_SB_LOCK(mp); | ||
2147 | ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd); | 2184 | ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd); |
2185 | XFS_SB_UNLOCK(mp, s); | ||
2148 | 2186 | ||
2149 | if (locked) | 2187 | /* |
2150 | XFS_SB_UNLOCK(mp, s); | 2188 | * Now that we've modified the global superblock, we |
2189 | * may be able to re-enable the distributed counters | ||
2190 | * (e.g. lots of space just got freed). After that | ||
2191 | * we are done. | ||
2192 | */ | ||
2193 | if (ret != ENOSPC) | ||
2194 | xfs_icsb_balance_counter(mp, field, 0, 0); | ||
2195 | mutex_unlock(&mp->m_icsb_mutex); | ||
2151 | return ret; | 2196 | return ret; |
2152 | } | ||
2153 | 2197 | ||
2154 | STATIC int | 2198 | balance_counter: |
2155 | xfs_icsb_modify_counters( | 2199 | xfs_icsb_unlock_cntr(icsbp); |
2156 | xfs_mount_t *mp, | 2200 | put_cpu(); |
2157 | xfs_sb_field_t field, | ||
2158 | int delta, | ||
2159 | int rsvd) | ||
2160 | { | ||
2161 | return xfs_icsb_modify_counters_int(mp, field, delta, rsvd, 0); | ||
2162 | } | ||
2163 | 2201 | ||
2164 | /* | 2202 | /* |
2165 | * Called when superblock is already locked | 2203 | * We may have multiple threads here if multiple per-cpu |
2166 | */ | 2204 | * counters run dry at the same time. This will mean we can |
2167 | STATIC int | 2205 | * do more balances than strictly necessary but it is not |
2168 | xfs_icsb_modify_counters_locked( | 2206 | * the common slowpath case. |
2169 | xfs_mount_t *mp, | 2207 | */ |
2170 | xfs_sb_field_t field, | 2208 | mutex_lock(&mp->m_icsb_mutex); |
2171 | int delta, | 2209 | |
2172 | int rsvd) | 2210 | /* |
2173 | { | 2211 | * running atomically. |
2174 | return xfs_icsb_modify_counters_int(mp, field, delta, | 2212 | * |
2175 | rsvd, XFS_ICSB_SB_LOCKED); | 2213 | * This will leave the counter in the correct state for future |
2214 | * accesses. After the rebalance, we simply try again and our retry | ||
2215 | * will either succeed through the fast path or slow path without | ||
2216 | * another balance operation being required. | ||
2217 | */ | ||
2218 | xfs_icsb_balance_counter(mp, field, 0, delta); | ||
2219 | mutex_unlock(&mp->m_icsb_mutex); | ||
2220 | goto again; | ||
2176 | } | 2221 | } |
2222 | |||
2177 | #endif | 2223 | #endif |