diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_linux.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 37 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 4 |
3 files changed, 28 insertions, 14 deletions
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 9fdc14cffb70..bd88ccb0cad0 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -75,6 +75,7 @@ | |||
75 | #include <linux/sort.h> | 75 | #include <linux/sort.h> |
76 | #include <linux/cpu.h> | 76 | #include <linux/cpu.h> |
77 | #include <linux/notifier.h> | 77 | #include <linux/notifier.h> |
78 | #include <linux/delay.h> | ||
78 | 79 | ||
79 | #include <asm/page.h> | 80 | #include <asm/page.h> |
80 | #include <asm/div64.h> | 81 | #include <asm/div64.h> |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index a64110b9023b..d62aee027368 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1746,10 +1746,7 @@ xfs_icsb_cpu_notify( | |||
1746 | case CPU_UP_PREPARE: | 1746 | case CPU_UP_PREPARE: |
1747 | /* Easy Case - initialize the area and locks, and | 1747 | /* Easy Case - initialize the area and locks, and |
1748 | * then rebalance when online does everything else for us. */ | 1748 | * then rebalance when online does everything else for us. */ |
1749 | spin_lock_init(&cntp->icsb_lock); | 1749 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1750 | cntp->icsb_icount = 0; | ||
1751 | cntp->icsb_ifree = 0; | ||
1752 | cntp->icsb_fdblocks = 0; | ||
1753 | break; | 1750 | break; |
1754 | case CPU_ONLINE: | 1751 | case CPU_ONLINE: |
1755 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); | 1752 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); |
@@ -1769,9 +1766,7 @@ xfs_icsb_cpu_notify( | |||
1769 | mp->m_sb.sb_ifree += cntp->icsb_ifree; | 1766 | mp->m_sb.sb_ifree += cntp->icsb_ifree; |
1770 | mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks; | 1767 | mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks; |
1771 | 1768 | ||
1772 | cntp->icsb_icount = 0; | 1769 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1773 | cntp->icsb_ifree = 0; | ||
1774 | cntp->icsb_fdblocks = 0; | ||
1775 | 1770 | ||
1776 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED); | 1771 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED); |
1777 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED); | 1772 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED); |
@@ -1800,7 +1795,7 @@ xfs_icsb_init_counters( | |||
1800 | 1795 | ||
1801 | for_each_online_cpu(i) { | 1796 | for_each_online_cpu(i) { |
1802 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); | 1797 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); |
1803 | spin_lock_init(&cntp->icsb_lock); | 1798 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1804 | } | 1799 | } |
1805 | /* | 1800 | /* |
1806 | * start with all counters disabled so that the | 1801 | * start with all counters disabled so that the |
@@ -1820,6 +1815,22 @@ xfs_icsb_destroy_counters( | |||
1820 | } | 1815 | } |
1821 | } | 1816 | } |
1822 | 1817 | ||
1818 | STATIC inline void | ||
1819 | xfs_icsb_lock_cntr( | ||
1820 | xfs_icsb_cnts_t *icsbp) | ||
1821 | { | ||
1822 | while (test_and_set_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags)) { | ||
1823 | ndelay(1000); | ||
1824 | } | ||
1825 | } | ||
1826 | |||
1827 | STATIC inline void | ||
1828 | xfs_icsb_unlock_cntr( | ||
1829 | xfs_icsb_cnts_t *icsbp) | ||
1830 | { | ||
1831 | clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags); | ||
1832 | } | ||
1833 | |||
1823 | 1834 | ||
1824 | STATIC inline void | 1835 | STATIC inline void |
1825 | xfs_icsb_lock_all_counters( | 1836 | xfs_icsb_lock_all_counters( |
@@ -1830,7 +1841,7 @@ xfs_icsb_lock_all_counters( | |||
1830 | 1841 | ||
1831 | for_each_online_cpu(i) { | 1842 | for_each_online_cpu(i) { |
1832 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); | 1843 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); |
1833 | spin_lock(&cntp->icsb_lock); | 1844 | xfs_icsb_lock_cntr(cntp); |
1834 | } | 1845 | } |
1835 | } | 1846 | } |
1836 | 1847 | ||
@@ -1843,7 +1854,7 @@ xfs_icsb_unlock_all_counters( | |||
1843 | 1854 | ||
1844 | for_each_online_cpu(i) { | 1855 | for_each_online_cpu(i) { |
1845 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); | 1856 | cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); |
1846 | spin_unlock(&cntp->icsb_lock); | 1857 | xfs_icsb_unlock_cntr(cntp); |
1847 | } | 1858 | } |
1848 | } | 1859 | } |
1849 | 1860 | ||
@@ -2070,7 +2081,7 @@ xfs_icsb_modify_counters_int( | |||
2070 | again: | 2081 | again: |
2071 | cpu = get_cpu(); | 2082 | cpu = get_cpu(); |
2072 | icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu), | 2083 | icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu), |
2073 | spin_lock(&icsbp->icsb_lock); | 2084 | xfs_icsb_lock_cntr(icsbp); |
2074 | if (unlikely(xfs_icsb_counter_disabled(mp, field))) | 2085 | if (unlikely(xfs_icsb_counter_disabled(mp, field))) |
2075 | goto slow_path; | 2086 | goto slow_path; |
2076 | 2087 | ||
@@ -2104,7 +2115,7 @@ again: | |||
2104 | BUG(); | 2115 | BUG(); |
2105 | break; | 2116 | break; |
2106 | } | 2117 | } |
2107 | spin_unlock(&icsbp->icsb_lock); | 2118 | xfs_icsb_unlock_cntr(icsbp); |
2108 | put_cpu(); | 2119 | put_cpu(); |
2109 | if (locked) | 2120 | if (locked) |
2110 | XFS_SB_UNLOCK(mp, s); | 2121 | XFS_SB_UNLOCK(mp, s); |
@@ -2120,7 +2131,7 @@ again: | |||
2120 | * manner. | 2131 | * manner. |
2121 | */ | 2132 | */ |
2122 | slow_path: | 2133 | slow_path: |
2123 | spin_unlock(&icsbp->icsb_lock); | 2134 | xfs_icsb_unlock_cntr(icsbp); |
2124 | put_cpu(); | 2135 | put_cpu(); |
2125 | 2136 | ||
2126 | /* need to hold superblock incase we need | 2137 | /* need to hold superblock incase we need |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 9d2ffbdc37a9..29cfcf0c11be 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -280,9 +280,11 @@ typedef struct xfs_icsb_cnts { | |||
280 | uint64_t icsb_fdblocks; | 280 | uint64_t icsb_fdblocks; |
281 | uint64_t icsb_ifree; | 281 | uint64_t icsb_ifree; |
282 | uint64_t icsb_icount; | 282 | uint64_t icsb_icount; |
283 | spinlock_t icsb_lock; | 283 | unsigned long icsb_flags; |
284 | } xfs_icsb_cnts_t; | 284 | } xfs_icsb_cnts_t; |
285 | 285 | ||
286 | #define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ | ||
287 | |||
286 | #define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */ | 288 | #define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */ |
287 | #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ | 289 | #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ |
288 | 290 | ||