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 9fdc14cffb7..bd88ccb0cad 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -75,6 +75,7 @@ #include <linux/sort.h> #include <linux/cpu.h> #include <linux/notifier.h> +#include <linux/delay.h> #include <asm/page.h> #include <asm/div64.h> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index a64110b9023..d62aee02736 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1746,10 +1746,7 @@ xfs_icsb_cpu_notify( case CPU_UP_PREPARE: /* Easy Case - initialize the area and locks, and * then rebalance when online does everything else for us. */ - spin_lock_init(&cntp->icsb_lock); - cntp->icsb_icount = 0; - cntp->icsb_ifree = 0; - cntp->icsb_fdblocks = 0; + memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); break; case CPU_ONLINE: xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); @@ -1769,9 +1766,7 @@ xfs_icsb_cpu_notify( mp->m_sb.sb_ifree += cntp->icsb_ifree; mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks; - cntp->icsb_icount = 0; - cntp->icsb_ifree = 0; - cntp->icsb_fdblocks = 0; + memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED); xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED); @@ -1800,7 +1795,7 @@ xfs_icsb_init_counters( for_each_online_cpu(i) { cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); - spin_lock_init(&cntp->icsb_lock); + memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); } /* * start with all counters disabled so that the @@ -1820,6 +1815,22 @@ xfs_icsb_destroy_counters( } } +STATIC inline void +xfs_icsb_lock_cntr( + xfs_icsb_cnts_t *icsbp) +{ + while (test_and_set_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags)) { + ndelay(1000); + } +} + +STATIC inline void +xfs_icsb_unlock_cntr( + xfs_icsb_cnts_t *icsbp) +{ + clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags); +} + STATIC inline void xfs_icsb_lock_all_counters( @@ -1830,7 +1841,7 @@ xfs_icsb_lock_all_counters( for_each_online_cpu(i) { cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); - spin_lock(&cntp->icsb_lock); + xfs_icsb_lock_cntr(cntp); } } @@ -1843,7 +1854,7 @@ xfs_icsb_unlock_all_counters( for_each_online_cpu(i) { cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); - spin_unlock(&cntp->icsb_lock); + xfs_icsb_unlock_cntr(cntp); } } @@ -2070,7 +2081,7 @@ xfs_icsb_modify_counters_int( again: cpu = get_cpu(); icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu), - spin_lock(&icsbp->icsb_lock); + xfs_icsb_lock_cntr(icsbp); if (unlikely(xfs_icsb_counter_disabled(mp, field))) goto slow_path; @@ -2104,7 +2115,7 @@ again: BUG(); break; } - spin_unlock(&icsbp->icsb_lock); + xfs_icsb_unlock_cntr(icsbp); put_cpu(); if (locked) XFS_SB_UNLOCK(mp, s); @@ -2120,7 +2131,7 @@ again: * manner. */ slow_path: - spin_unlock(&icsbp->icsb_lock); + xfs_icsb_unlock_cntr(icsbp); put_cpu(); /* need to hold superblock incase we need diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 9d2ffbdc37a..29cfcf0c11b 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -280,9 +280,11 @@ typedef struct xfs_icsb_cnts { uint64_t icsb_fdblocks; uint64_t icsb_ifree; uint64_t icsb_icount; - spinlock_t icsb_lock; + unsigned long icsb_flags; } xfs_icsb_cnts_t; +#define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ + #define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */ #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ |