From 3cdaa1898ff3b16f69619cb5df2f45158e104817 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Thu, 4 Jun 2015 13:03:34 +1000 Subject: xfs: fix sparse inodes 32-bit compile failure The kbuild test robot reports the following compilation failure with a 32-bit kernel configuration: fs/built-in.o: In function `xfs_ifree_cluster': >> xfs_inode.c:(.text+0x17ac84): undefined reference to `__umoddi3' This is due to the use of the modulus operator on a 64-bit variable in the ASSERT() added as part of the following commit: xfs: skip unallocated regions of inode chunks in xfs_ifree_cluster() This ASSERT() simply checks that the offset of the inode in a sparse cluster is appropriately aligned. Since the maximum inode record offset is 63 (for a 64 inode record) and the calculated offset here should be something less than that, just use a 32-bit variable to store the offset and call the do_mod() helper. Reported-by: kbuild test robot Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_inode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 11a8c28c47bd..a17cf1f16498 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2248,6 +2248,7 @@ xfs_ifree_cluster( int inodes_per_cluster; int nbufs; int i, j; + int ioffset; xfs_daddr_t blkno; xfs_buf_t *bp; xfs_inode_t *ip; @@ -2268,9 +2269,9 @@ xfs_ifree_cluster( * physically allocated. Skip the cluster if an inode falls into * a sparse region. */ - if ((xic->alloc & XFS_INOBT_MASK(inum - xic->first_ino)) == 0) { - ASSERT(((inum - xic->first_ino) % - inodes_per_cluster) == 0); + ioffset = inum - xic->first_ino; + if ((xic->alloc & XFS_INOBT_MASK(ioffset)) == 0) { + ASSERT(do_mod(ioffset, inodes_per_cluster) == 0); continue; } -- cgit v1.2.1 From 46fc58dacf6e9b00629c57998a8a23f85c262b3f Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Thu, 4 Jun 2015 13:03:34 +1000 Subject: xfs: check min blks for random debug mode sparse allocations The inode allocator enables random sparse inode chunk allocations in DEBUG mode to facilitate testing. Sparse inode allocations are not always possible, however, depending on the fs geometry. For example, there is no possibility for a sparse inode allocation on filesystems where the block size is large enough to fit one or more inode chunks within a single block. Fix up the DEBUG mode sparse inode allocation logic to trigger random sparse allocations only when the geometry of the fs allows it. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ialloc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index c6d684ed84d0..52553b854771 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -606,20 +606,20 @@ xfs_ialloc_ag_alloc( uint16_t allocmask = (uint16_t) -1; /* init. to full chunk */ struct xfs_inobt_rec_incore rec; struct xfs_perag *pag; - int do_sparse = 0; -#ifdef DEBUG - /* randomly do sparse inode allocations */ - if (xfs_sb_version_hassparseinodes(&tp->t_mountp->m_sb)) - do_sparse = prandom_u32() & 1; -#endif - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = tp->t_mountp; args.fsbno = NULLFSBLOCK; +#ifdef DEBUG + /* randomly do sparse inode allocations */ + if (xfs_sb_version_hassparseinodes(&tp->t_mountp->m_sb) && + args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks) + do_sparse = prandom_u32() & 1; +#endif + /* * Locking will ensure that we don't have two callers in here * at one time. @@ -768,6 +768,7 @@ sparse_alloc: return error; newlen = args.len << args.mp->m_sb.sb_inopblog; + ASSERT(newlen <= XFS_INODES_PER_CHUNK); allocmask = (1 << (newlen / XFS_INODES_PER_HOLEMASK_BIT)) - 1; } -- cgit v1.2.1