linux-stable/fs/xfs/libxfs
Darrick J. Wong 8e698ee72c xfs: set bnobt/cntbt numrecs correctly when formatting new AGs
Through generic/300, I discovered that mkfs.xfs creates corrupt
filesystems when given these parameters:

# mkfs.xfs -d size=512M /dev/sda -f -d su=128k,sw=4 --unsupported
Filesystems formatted with --unsupported are not supported!!
meta-data=/dev/sda               isize=512    agcount=8, agsize=16352 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=1
         =                       reflink=1    bigtime=1 inobtcount=1 nrext64=1
data     =                       bsize=4096   blocks=130816, imaxpct=25
         =                       sunit=32     swidth=128 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=8192, version=2
         =                       sectsz=512   sunit=32 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
         =                       rgcount=0    rgsize=0 blks
Discarding blocks...Done.
# xfs_repair -n /dev/sda
Phase 1 - find and verify superblock...
        - reporting progress in intervals of 15 minutes
Phase 2 - using internal log
        - zero log...
        - 16:30:50: zeroing log - 16320 of 16320 blocks done
        - scan filesystem freespace and inode maps...
agf_freeblks 25, counted 0 in ag 4
sb_fdblocks 8823, counted 8798

The root cause of this problem is the numrecs handling in
xfs_freesp_init_recs, which is used to initialize a new AG.  Prior to
calling the function, we set up the new bnobt block with numrecs == 1
and rely on _freesp_init_recs to format that new record.  If the last
record created has a blockcount of zero, then it sets numrecs = 0.

That last bit isn't correct if the AG contains the log, the start of the
log is not immediately after the initial blocks due to stripe alignment,
and the end of the log is perfectly aligned with the end of the AG.  For
this case, we actually formatted a single bnobt record to handle the
free space before the start of the (stripe aligned) log, and incremented
arec to try to format a second record.  That second record turned out to
be unnecessary, so what we really want is to leave numrecs at 1.

The numrecs handling itself is overly complicated because a different
function sets numrecs == 1.  Change the bnobt creation code to start
with numrecs set to zero and only increment it after successfully
formatting a free space extent into the btree block.

Fixes: f327a00745 ("xfs: account for log space when formatting new AGs")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2023-05-02 09:14:36 +10:00
..
xfs_ag.c xfs: set bnobt/cntbt numrecs correctly when formatting new AGs 2023-05-02 09:14:36 +10:00
xfs_ag.h xfs: allow queued AG intents to drain before scrubbing 2023-04-11 18:59:58 -07:00
xfs_ag_resv.c xfs: inobt can use perags in many more places than it does 2023-02-13 09:14:52 +11:00
xfs_ag_resv.h
xfs_alloc.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_alloc.h xfs: replace xfs_btree_has_record with a general keyspace scanner 2023-04-11 19:00:10 -07:00
xfs_alloc_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_alloc_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_attr.c xfs: replace XFS_IFORK_Q with a proper predicate function 2022-07-12 11:17:27 -07:00
xfs_attr.h xfs: replace XFS_IFORK_Q with a proper predicate function 2022-07-12 11:17:27 -07:00
xfs_attr_leaf.c xfs: don't leak memory when attr fork loading fails 2022-07-20 16:40:39 -07:00
xfs_attr_leaf.h xfs: don't hold xattr leaf buffers across transaction rolls 2022-06-29 08:47:56 -07:00
xfs_attr_remote.c xfs: rework xfs_buf_incore() API 2022-07-07 22:05:18 +10:00
xfs_attr_remote.h xfs: rename struct xfs_attr_item to xfs_attr_intent 2022-05-22 16:00:26 +10:00
xfs_attr_sf.h
xfs_bit.c
xfs_bit.h
xfs_bmap.c xfs: don't unconditionally null args->pag in xfs_bmap_btalloc_at_eof 2023-05-02 09:14:27 +10:00
xfs_bmap.h xfs: accumulate iextent records when checking bmap 2023-04-11 19:00:24 -07:00
xfs_bmap_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_bmap_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_btree.h xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_btree_staging.c xfs: encode the max btree height in the cursor 2021-10-19 11:45:15 -07:00
xfs_btree_staging.h
xfs_cksum.h
xfs_da_btree.c xfs: trim the mapp array accordingly in xfs_da_grow_inode_int 2022-10-04 16:39:42 +11:00
xfs_da_btree.h xfs: fix TOCTOU race involving the new logged xattrs control knob 2022-06-15 23:13:32 -07:00
xfs_da_format.h Merge tag 'large-extent-counters-v9' of https://github.com/chandanr/linux into xfs-5.19-for-next 2022-04-21 16:46:17 +10:00
xfs_defer.c xfs: allow queued AG intents to drain before scrubbing 2023-04-11 18:59:58 -07:00
xfs_defer.h xfs: Implement attr logging and replay 2022-05-09 19:09:07 +10:00
xfs_dir2.c xfs: stabilize the dirent name transformation function used for ascii-ci dir hash computation 2023-04-11 19:05:04 -07:00
xfs_dir2.h xfs: stabilize the dirent name transformation function used for ascii-ci dir hash computation 2023-04-11 19:05:04 -07:00
xfs_dir2_block.c xfs: replace inode fork size macros with functions 2022-07-12 11:17:27 -07:00
xfs_dir2_data.c xfs: convert bp->b_bn references to xfs_buf_daddr() 2021-08-19 10:07:15 -07:00
xfs_dir2_leaf.c xfs: fix exception caused by unexpected illegal bestcount in leaf dir 2022-10-20 09:42:56 -07:00
xfs_dir2_node.c xfs: convert bp->b_bn references to xfs_buf_daddr() 2021-08-19 10:07:15 -07:00
xfs_dir2_priv.h xfs: constify the name argument to various directory functions 2022-03-14 10:23:17 -07:00
xfs_dir2_sf.c xfs: Remove the unneeded result variable 2022-09-19 06:52:14 +10:00
xfs_dquot_buf.c xfs: remove the xfs_dqblk_t typedef 2021-10-14 09:19:33 -07:00
xfs_errortag.h xfs: add debug knob to slow down write for fun 2022-11-28 17:54:49 -08:00
xfs_format.h xfs: rename XFS_REFC_COW_START to _COWFLAG 2022-10-31 08:58:22 -07:00
xfs_fs.h Merge tag 'large-extent-counters-v9' of https://github.com/chandanr/linux into xfs-5.19-for-next 2022-04-21 16:46:17 +10:00
xfs_health.h
xfs_ialloc.c xfs: convert xfs_ialloc_has_inodes_at_extent to return keyfill scan results 2023-04-11 19:00:15 -07:00
xfs_ialloc.h xfs: convert xfs_ialloc_has_inodes_at_extent to return keyfill scan results 2023-04-11 19:00:15 -07:00
xfs_ialloc_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_ialloc_btree.h xfs: standardize ondisk to incore conversion for inode btrees 2023-04-11 19:00:01 -07:00
xfs_iext_tree.c
xfs_inode_buf.c xfs: make attr forks permanent 2022-07-14 09:46:37 -07:00
xfs_inode_buf.h xfs: kill xfs_sb_version_has_v3inode() 2021-08-19 10:07:14 -07:00
xfs_inode_fork.c xfs: standardize btree record checking code [v24.5] 2023-04-14 07:09:18 +10:00
xfs_inode_fork.h xfs: _{attr,data}_map_shared should take ILOCK_EXCL until iread_extents is completely done 2023-04-12 15:49:10 +10:00
xfs_log_format.h xfs: refactor all the EFI/EFD log item sizeof logic 2022-10-31 08:58:20 -07:00
xfs_log_recover.h xfs: convert buf_cancel_table allocation to kmalloc_array 2022-05-27 10:27:19 +10:00
xfs_log_rlimit.c xfs: reduce transaction reservations with reflink 2022-04-28 10:25:42 -07:00
xfs_quota_defs.h xfs: remove warning counters from struct xfs_dquot_res 2022-05-11 17:12:09 +10:00
xfs_refcount.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_refcount.h xfs: replace xfs_btree_has_record with a general keyspace scanner 2023-04-11 19:00:10 -07:00
xfs_refcount_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_refcount_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_rmap.c xfs: teach scrub to check for sole ownership of metadata objects 2023-04-11 19:00:15 -07:00
xfs_rmap.h xfs: teach scrub to check for sole ownership of metadata objects 2023-04-11 19:00:15 -07:00
xfs_rmap_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_rmap_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_rtbitmap.c xfs: pass explicit mount pointer to rtalloc query functions 2022-04-12 06:49:41 +10:00
xfs_sb.c xfs: don't consider future format versions valid 2023-04-12 15:48:50 +10:00
xfs_sb.h xfs: open code sb verifier feature checks 2021-08-19 10:07:13 -07:00
xfs_shared.h xfs: tag transactions that contain intent done items 2022-05-04 11:46:21 +10:00
xfs_symlink_remote.c xfs: convert XFS_IFORK_PTR to a static inline helper 2022-07-09 15:17:21 -07:00
xfs_trans_inode.c xfs: convert xfs_sb_version_has checks to use mount features 2021-08-19 10:07:14 -07:00
xfs_trans_resv.c xfs: increase rename inode reservation 2022-10-26 13:02:24 -07:00
xfs_trans_resv.h xfs: rename xfs_*alloc*_log_count to _block_count 2022-04-28 10:25:59 -07:00
xfs_trans_space.h xfs: compute the maximum height of the rmap btree when reflink enabled 2021-10-19 11:45:16 -07:00
xfs_types.c xfs: Pre-calculate per-AG agino geometry 2022-07-07 19:13:10 +10:00
xfs_types.h xfs: replace xfs_btree_has_record with a general keyspace scanner 2023-04-11 19:00:10 -07:00