diff mbox

xfs: Use xfs_icluster_size_fsb() to calculate inode chunk alignment

Message ID 1487249852-27104-1-git-send-email-chandan@linux.vnet.ibm.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Chandan Rajendra Feb. 16, 2017, 12:57 p.m. UTC
On a ppc64 system, executing generic/256 test with 32k block size gives the following call trace,

XFS: Assertion failed: args->maxlen > 0, file: /root/repos/linux/fs/xfs/libxfs/xfs_alloc.c, line: 2026

kernel BUG at /root/repos/linux/fs/xfs/xfs_message.c:113!
Oops: Exception in kernel mode, sig: 5 [#1]
SMP NR_CPUS=2048
DEBUG_PAGEALLOC
NUMA
pSeries
Modules linked in:
CPU: 2 PID: 19361 Comm: mkdir Not tainted 4.10.0-rc5 #58
task: c000000102606d80 task.stack: c0000001026b8000
NIP: c0000000004ef798 LR: c0000000004ef798 CTR: c00000000082b290
REGS: c0000001026bb090 TRAP: 0700   Not tainted  (4.10.0-rc5)
MSR: 8000000000029032 <SF,EE,ME,IR,DR,RI>
CR: 28004428  XER: 00000000
CFAR: c0000000004ef180 SOFTE: 1
GPR00: c0000000004ef798 c0000001026bb310 c000000001157300 ffffffffffffffea
GPR04: 000000000000000a c0000001026bb130 0000000000000000 ffffffffffffffc0
GPR08: 00000000000000d1 0000000000000021 00000000ffffffd1 c000000000dd4990
GPR12: 0000000022004444 c00000000fe00800 0000000020000000 0000000000000000
GPR16: 0000000000000000 0000000043a606fc 0000000043a76c08 0000000043a1b3d0
GPR20: 000001002a35cd60 c0000001026bbb80 0000000000000000 0000000000000001
GPR24: 0000000000000240 0000000000000004 c00000062dc55000 0000000000000000
GPR28: 0000000000000004 c00000062ecd9200 0000000000000000 c0000001026bb6c0
NIP [c0000000004ef798] .assfail+0x28/0x30
LR [c0000000004ef798] .assfail+0x28/0x30
Call Trace:
[c0000001026bb310] [c0000000004ef798] .assfail+0x28/0x30 (unreliable)
[c0000001026bb380] [c000000000455d74] .xfs_alloc_space_available+0x194/0x1b0
[c0000001026bb410] [c00000000045b914] .xfs_alloc_fix_freelist+0x144/0x480
[c0000001026bb580] [c00000000045c368] .xfs_alloc_vextent+0x698/0xa90
[c0000001026bb650] [c0000000004a6200] .xfs_ialloc_ag_alloc+0x170/0x820
[c0000001026bb7c0] [c0000000004a9098] .xfs_dialloc+0x158/0x320
[c0000001026bb8a0] [c0000000004e628c] .xfs_ialloc+0x7c/0x610
[c0000001026bb990] [c0000000004e8138] .xfs_dir_ialloc+0xa8/0x2f0
[c0000001026bbaa0] [c0000000004e8814] .xfs_create+0x494/0x790
[c0000001026bbbf0] [c0000000004e5ebc] .xfs_generic_create+0x2bc/0x410
[c0000001026bbce0] [c0000000002b4a34] .vfs_mkdir+0x154/0x230
[c0000001026bbd70] [c0000000002bc444] .SyS_mkdirat+0x94/0x120
[c0000001026bbe30] [c00000000000b760] system_call+0x38/0xfc
Instruction dump:
4e800020 60000000 7c0802a6 7c862378 3c82ffca 7ca72b78 38841c18 7c651b78
38600000 f8010010 f821ff91 4bfff94d <0fe00000> 60000000 7c0802a6 7c892378

When block size is larger than inode cluster size, the call to
XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size) returns 0. Also, mkfs.xfs
would have set xfs_sb->sb_inoalignmt to 0. This causes
xfs_ialloc_cluster_alignment() to return 0.  Due to this
args.minalignslop (in xfs_ialloc_ag_alloc()) gets the unsigned
equivalent of -1 assigned to it. This later causes alloc_len in
xfs_alloc_space_available() to have a value of 0. In such a scenario
when args.total is also 0, the assert statement "ASSERT(args->maxlen >
0);" fails.

This commit fixes the bug by replacing the call to XFS_B_TO_FSBT() in
xfs_ialloc_cluster_alignment() with a call to xfs_icluster_size_fsb().

Suggested-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com>
---
 fs/xfs/libxfs/xfs_ialloc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

Christoph Hellwig Feb. 16, 2017, 8:28 p.m. UTC | #1
Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Eric Sandeen Feb. 17, 2017, 11:09 p.m. UTC | #2
On 2/16/17 6:57 AM, Chandan Rajendra wrote:
> On a ppc64 system, executing generic/256 test with 32k block size gives the following call trace,
> 
> XFS: Assertion failed: args->maxlen > 0, file: /root/repos/linux/fs/xfs/libxfs/xfs_alloc.c, line: 2026

The fix for the assert seems fine as far as it goes, but again,
I think we need to look into i.e. how m_inalign_mask gets set,
and whether that's a problem for this case as well.

I think it may be working by accident, but a little digging
is in order.

-Eric

> kernel BUG at /root/repos/linux/fs/xfs/xfs_message.c:113!
> Oops: Exception in kernel mode, sig: 5 [#1]
> SMP NR_CPUS=2048
> DEBUG_PAGEALLOC
> NUMA
> pSeries
> Modules linked in:
> CPU: 2 PID: 19361 Comm: mkdir Not tainted 4.10.0-rc5 #58
> task: c000000102606d80 task.stack: c0000001026b8000
> NIP: c0000000004ef798 LR: c0000000004ef798 CTR: c00000000082b290
> REGS: c0000001026bb090 TRAP: 0700   Not tainted  (4.10.0-rc5)
> MSR: 8000000000029032 <SF,EE,ME,IR,DR,RI>
> CR: 28004428  XER: 00000000
> CFAR: c0000000004ef180 SOFTE: 1
> GPR00: c0000000004ef798 c0000001026bb310 c000000001157300 ffffffffffffffea
> GPR04: 000000000000000a c0000001026bb130 0000000000000000 ffffffffffffffc0
> GPR08: 00000000000000d1 0000000000000021 00000000ffffffd1 c000000000dd4990
> GPR12: 0000000022004444 c00000000fe00800 0000000020000000 0000000000000000
> GPR16: 0000000000000000 0000000043a606fc 0000000043a76c08 0000000043a1b3d0
> GPR20: 000001002a35cd60 c0000001026bbb80 0000000000000000 0000000000000001
> GPR24: 0000000000000240 0000000000000004 c00000062dc55000 0000000000000000
> GPR28: 0000000000000004 c00000062ecd9200 0000000000000000 c0000001026bb6c0
> NIP [c0000000004ef798] .assfail+0x28/0x30
> LR [c0000000004ef798] .assfail+0x28/0x30
> Call Trace:
> [c0000001026bb310] [c0000000004ef798] .assfail+0x28/0x30 (unreliable)
> [c0000001026bb380] [c000000000455d74] .xfs_alloc_space_available+0x194/0x1b0
> [c0000001026bb410] [c00000000045b914] .xfs_alloc_fix_freelist+0x144/0x480
> [c0000001026bb580] [c00000000045c368] .xfs_alloc_vextent+0x698/0xa90
> [c0000001026bb650] [c0000000004a6200] .xfs_ialloc_ag_alloc+0x170/0x820
> [c0000001026bb7c0] [c0000000004a9098] .xfs_dialloc+0x158/0x320
> [c0000001026bb8a0] [c0000000004e628c] .xfs_ialloc+0x7c/0x610
> [c0000001026bb990] [c0000000004e8138] .xfs_dir_ialloc+0xa8/0x2f0
> [c0000001026bbaa0] [c0000000004e8814] .xfs_create+0x494/0x790
> [c0000001026bbbf0] [c0000000004e5ebc] .xfs_generic_create+0x2bc/0x410
> [c0000001026bbce0] [c0000000002b4a34] .vfs_mkdir+0x154/0x230
> [c0000001026bbd70] [c0000000002bc444] .SyS_mkdirat+0x94/0x120
> [c0000001026bbe30] [c00000000000b760] system_call+0x38/0xfc
> Instruction dump:
> 4e800020 60000000 7c0802a6 7c862378 3c82ffca 7ca72b78 38841c18 7c651b78
> 38600000 f8010010 f821ff91 4bfff94d <0fe00000> 60000000 7c0802a6 7c892378
> 
> When block size is larger than inode cluster size, the call to
> XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size) returns 0. Also, mkfs.xfs
> would have set xfs_sb->sb_inoalignmt to 0. This causes
> xfs_ialloc_cluster_alignment() to return 0.  Due to this
> args.minalignslop (in xfs_ialloc_ag_alloc()) gets the unsigned
> equivalent of -1 assigned to it. This later causes alloc_len in
> xfs_alloc_space_available() to have a value of 0. In such a scenario
> when args.total is also 0, the assert statement "ASSERT(args->maxlen >
> 0);" fails.
> 
> This commit fixes the bug by replacing the call to XFS_B_TO_FSBT() in
> xfs_ialloc_cluster_alignment() with a call to xfs_icluster_size_fsb().
> 
> Suggested-by: Darrick J. Wong <darrick.wong@oracle.com>
> Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com>
> ---
>  fs/xfs/libxfs/xfs_ialloc.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
> index f272abf..d41ade5 100644
> --- a/fs/xfs/libxfs/xfs_ialloc.c
> +++ b/fs/xfs/libxfs/xfs_ialloc.c
> @@ -51,8 +51,7 @@ xfs_ialloc_cluster_alignment(
>  	struct xfs_mount	*mp)
>  {
>  	if (xfs_sb_version_hasalign(&mp->m_sb) &&
> -	    mp->m_sb.sb_inoalignmt >=
> -			XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
> +	    mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
>  		return mp->m_sb.sb_inoalignmt;
>  	return 1;
>  }
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index f272abf..d41ade5 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -51,8 +51,7 @@  xfs_ialloc_cluster_alignment(
 	struct xfs_mount	*mp)
 {
 	if (xfs_sb_version_hasalign(&mp->m_sb) &&
-	    mp->m_sb.sb_inoalignmt >=
-			XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
+	    mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
 		return mp->m_sb.sb_inoalignmt;
 	return 1;
 }