| From 86a941bd2debe05ac7c0efb0208f76e5472c7d9b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 15 Sep 2020 20:50:42 -0700 |
| Subject: xfs: Set xfs_buf type flag when growing summary/bitmap files |
| |
| From: Chandan Babu R <chandanrlinux@gmail.com> |
| |
| [ Upstream commit 72cc95132a93293dcd0b6f68353f4741591c9aeb ] |
| |
| The following sequence of commands, |
| |
| mkfs.xfs -f -m reflink=0 -r rtdev=/dev/loop1,size=10M /dev/loop0 |
| mount -o rtdev=/dev/loop1 /dev/loop0 /mnt |
| xfs_growfs /mnt |
| |
| ... causes the following call trace to be printed on the console, |
| |
| XFS: Assertion failed: (bip->bli_flags & XFS_BLI_STALE) || (xfs_blft_from_flags(&bip->__bli_format) > XFS_BLFT_UNKNOWN_BUF && xfs_blft_from_flags(&bip->__bli_format) < XFS_BLFT_MAX_BUF), file: fs/xfs/xfs_buf_item.c, line: 331 |
| Call Trace: |
| xfs_buf_item_format+0x632/0x680 |
| ? kmem_alloc_large+0x29/0x90 |
| ? kmem_alloc+0x70/0x120 |
| ? xfs_log_commit_cil+0x132/0x940 |
| xfs_log_commit_cil+0x26f/0x940 |
| ? xfs_buf_item_init+0x1ad/0x240 |
| ? xfs_growfs_rt_alloc+0x1fc/0x280 |
| __xfs_trans_commit+0xac/0x370 |
| xfs_growfs_rt_alloc+0x1fc/0x280 |
| xfs_growfs_rt+0x1a0/0x5e0 |
| xfs_file_ioctl+0x3fd/0xc70 |
| ? selinux_file_ioctl+0x174/0x220 |
| ksys_ioctl+0x87/0xc0 |
| __x64_sys_ioctl+0x16/0x20 |
| do_syscall_64+0x3e/0x70 |
| entry_SYSCALL_64_after_hwframe+0x44/0xa9 |
| |
| This occurs because the buffer being formatted has the value of |
| XFS_BLFT_UNKNOWN_BUF assigned to the 'type' subfield of |
| bip->bli_formats->blf_flags. |
| |
| This commit fixes the issue by assigning one of XFS_BLFT_RTSUMMARY_BUF |
| and XFS_BLFT_RTBITMAP_BUF to the 'type' subfield of |
| bip->bli_formats->blf_flags before committing the corresponding |
| transaction. |
| |
| Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com> |
| Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/xfs/xfs_rtalloc.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c |
| index 86994d7f7cba3..912f96a248f25 100644 |
| --- a/fs/xfs/xfs_rtalloc.c |
| +++ b/fs/xfs/xfs_rtalloc.c |
| @@ -778,8 +778,14 @@ xfs_growfs_rt_alloc( |
| struct xfs_bmbt_irec map; /* block map output */ |
| int nmap; /* number of block maps */ |
| int resblks; /* space reservation */ |
| + enum xfs_blft buf_type; |
| struct xfs_trans *tp; |
| |
| + if (ip == mp->m_rsumip) |
| + buf_type = XFS_BLFT_RTSUMMARY_BUF; |
| + else |
| + buf_type = XFS_BLFT_RTBITMAP_BUF; |
| + |
| /* |
| * Allocate space to the file, as necessary. |
| */ |
| @@ -841,6 +847,8 @@ xfs_growfs_rt_alloc( |
| mp->m_bsize, 0, &bp); |
| if (error) |
| goto out_trans_cancel; |
| + |
| + xfs_trans_buf_set_type(tp, bp, buf_type); |
| memset(bp->b_addr, 0, mp->m_sb.sb_blocksize); |
| xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); |
| /* |
| -- |
| 2.27.0 |
| |