]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: Set xfs_buf type flag when growing summary/bitmap files
authorChandan Babu R <chandanrlinux@gmail.com>
Wed, 16 Sep 2020 03:50:42 +0000 (20:50 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 21 Sep 2020 16:54:29 +0000 (09:54 -0700)
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>
fs/xfs/xfs_rtalloc.c

index 5b89c12f15668b29b3c397dbb5ae8f5478036ca5..ace99cfa3e8be30daf4b96a49f82d32051659a25 100644 (file)
@@ -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);
                        /*