From: George Wang Date: Fri, 3 Jul 2015 01:54:41 +0000 (+1000) Subject: xfs: use percpu_counter_read_positive for mp->m_icount X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0e6012463a50a2ca840ade4b0cfb3702d99c23c;p=thirdparty%2Fxfsprogs-dev.git xfs: use percpu_counter_read_positive for mp->m_icount Function percpu_counter_read just return the current counter, which can be negative. This will cause the checking of "allocated inode counts <= m_maxicount" false positive. Use percpu_counter_read_positive can solve this problem, and be consistent with the purpose to introduce percpu mechanism to xfs. Signed-off-by: George Wang Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 25f750859..ffc3e456d 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -173,8 +173,9 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC }; #define rcu_read_unlock() ((void) 0) #define WARN_ON_ONCE(expr) ((void) 0) -#define percpu_counter_read(x) (*x) -#define percpu_counter_sum(x) (*x) +#define percpu_counter_read(x) (*x) +#define percpu_counter_read_positive(x) ((*x) > 0 ? (*x) : 0) +#define percpu_counter_sum(x) (*x) /* * prandom_u32 is used for di_gen inode allocation, it must be zero for libxfs diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 5e512be9f..b57f89a7e 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -621,7 +621,7 @@ xfs_ialloc_ag_alloc( */ newlen = args.mp->m_ialloc_inos; if (args.mp->m_maxicount && - percpu_counter_read(&args.mp->m_icount) + newlen > + percpu_counter_read_positive(&args.mp->m_icount) + newlen > args.mp->m_maxicount) return -ENOSPC; args.minlen = args.maxlen = args.mp->m_ialloc_blks; @@ -1699,10 +1699,13 @@ xfs_dialloc( * If we have already hit the ceiling of inode blocks then clear * okalloc so we scan all available agi structures for a free * inode. + * + * Read rough value of mp->m_icount by percpu_counter_read_positive, + * which will sacrifice the preciseness but improve the performance. */ if (mp->m_maxicount && - percpu_counter_read(&mp->m_icount) + mp->m_ialloc_inos > - mp->m_maxicount) { + percpu_counter_read_positive(&mp->m_icount) + mp->m_ialloc_inos + > mp->m_maxicount) { noroom = 1; okalloc = 0; }