linux/fs/xfs/scrub
Darrick J. Wong 3fb84dfb97 xfs: fix online repair probing when CONFIG_XFS_ONLINE_REPAIR=n
commit 66314e9a57 upstream.

I received a report from the release engineering side of the house that
xfs_scrub without the -n flag (aka fix it mode) would try to fix a
broken filesystem even on a kernel that doesn't have online repair built
into it:

 # xfs_scrub -dTvn /mnt/test
 EXPERIMENTAL xfs_scrub program in use! Use at your own risk!
 Phase 1: Find filesystem geometry.
 /mnt/test: using 1 threads to scrub.
 Phase 1: Memory used: 132k/0k (108k/25k), time:  0.00/ 0.00/ 0.00s
 <snip>
 Phase 4: Repair filesystem.
 <snip>
 Info: /mnt/test/some/victimdir directory entries: Attempting repair. (repair.c line 351)
 Corruption: /mnt/test/some/victimdir directory entries: Repair unsuccessful; offline repair required. (repair.c line 204)

Source: https://blogs.oracle.com/linux/post/xfs-online-filesystem-repair

It is strange that xfs_scrub doesn't refuse to run, because the kernel
is supposed to return EOPNOTSUPP if we actually needed to run a repair,
and xfs_io's repair subcommand will perror that.  And yet:

 # xfs_io -x -c 'repair probe' /mnt/test
 #

The first problem is commit dcb660f922 (4.15) which should have had
xchk_probe set the CORRUPT OFLAG so that any of the repair machinery
will get called at all.

It turns out that some refactoring that happened in the 6.6-6.8 era
broke the operation of this corner case.  What we *really* want to
happen is that all the predicates that would steer xfs_scrub_metadata()
towards calling xrep_attempt() should function the same way that they do
when repair is compiled in; and then xrep_attempt gets to return the
fatal EOPNOTSUPP error code that causes the probe to fail.

Instead, commit 8336a64eb7 (6.6) started the failwhale swimming by
hoisting OFLAG checking logic into a helper whose non-repair stub always
returns false, causing scrub to return "repair not needed" when in fact
the repair is not supported.  Prior to that commit, the oflag checking
that was open-coded in scrub.c worked correctly.

Similarly, in commit 4bdfd7d157 (6.8) we hoisted the IFLAG_REPAIR
and ALREADY_FIXED logic into a helper whose non-repair stub always
returns false, so we never enter the if test body that would have called
xrep_attempt, let alone fail to decode the OFLAGs correctly.

The final insult (yes, we're doing The Naked Gun now) is commit
48a72f6086 (6.8) in which we hoisted the "are we going to try a
repair?" predicate into yet another function with a non-repair stub
always returns false.

Fix xchk_probe to trigger xrep_probe if repair is enabled, or return
EOPNOTSUPP directly if it is not.  For all the other scrub types, we
need to fix the header predicates so that the ->repair functions (which
are all xrep_notsupported) get called to return EOPNOTSUPP.  Commit
48a72 is tagged here because the scrub code prior to LTS 6.12 are
incomplete and not worth patching.

Reported-by: David Flynn <david.flynn@oracle.com>
Cc: <stable@vger.kernel.org> # v6.8
Fixes: 8336a64eb7 ("xfs: don't complain about unfixed metadata when repairs were injected")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2025-02-27 04:30:22 -08:00
..
agb_bitmap.c xfs: move the per-AG datatype bitmaps to separate files 2023-12-15 10:03:30 -08:00
agb_bitmap.h xfs: create agblock bitmap helper to count the number of set regions 2024-02-22 12:43:37 -08:00
agheader.c xfs: fix zero byte checking in the superblock scrubber 2024-12-27 14:02:01 +01:00
agheader_repair.c xfs: return a 64-bit block count from xfs_btree_count_blocks 2024-12-19 18:13:08 +01:00
agino_bitmap.h xfs: repair AGI unlinked inode bucket lists 2024-04-15 14:58:58 -07:00
alloc.c xfs: repair free space btrees 2023-12-15 10:03:32 -08:00
alloc_repair.c xfs: fix error bailout in xrep_abt_build_new_trees 2024-04-15 14:54:06 -07:00
attr.c xfs: add a per-leaf block callback to xchk_xattr_walk 2024-04-23 16:55:15 -07:00
attr.h xfs: repair extended attributes 2024-04-15 14:58:53 -07:00
attr_repair.c xfs: exchange-range for repairs is no longer dynamic 2024-04-23 16:55:19 -07:00
attr_repair.h xfs: actually rebuild the parent pointer xattrs 2024-04-23 16:55:15 -07:00
bitmap.c xfs: fix sparse warnings about unused interval tree functions 2024-04-22 12:51:43 +05:30
bitmap.h xfs: create agblock bitmap helper to count the number of set regions 2024-02-22 12:43:37 -08:00
bmap.c xfs: attr forks require attr, not attr2 2024-08-14 21:19:14 +05:30
bmap_repair.c xfs: fix integer overflow in xrep_bmap 2024-10-11 12:32:48 +02:00
btree.c xfs: consolidate btree block verification 2024-02-22 12:40:57 -08:00
btree.h overflow: Add struct_size_t() helper 2023-05-26 13:52:19 -07:00
common.c xfs: move dirent update hooks to xfs_dir2.c 2024-07-02 11:37:00 -07:00
common.h xfs: fix online repair probing when CONFIG_XFS_ONLINE_REPAIR=n 2025-02-27 04:30:22 -08:00
cow_repair.c xfs: convert remaining kmem_free() to kfree() 2024-02-13 18:07:34 +05:30
dab_bitmap.h xfs: create an xattr iteration function for scrub 2024-04-15 14:58:54 -07:00
dabtree.c xfs: scrub should set preen if attr leaf has holes 2024-04-15 14:58:54 -07:00
dabtree.h xfs: flag empty xattr leaf blocks for optimization 2024-04-15 14:58:54 -07:00
dir.c xfs: refactor dir format helpers 2024-04-26 11:21:46 +05:30
dir_repair.c xfs: factor out a xfs_dir_replace_args helper 2024-04-26 11:19:04 +05:30
dirtree.c xfs: fix corruptions in the directory tree 2024-04-23 16:55:17 -07:00
dirtree.h xfs: fix corruptions in the directory tree 2024-04-23 16:55:17 -07:00
dirtree_repair.c xfs: fix corruptions in the directory tree 2024-04-23 16:55:17 -07:00
dqiterate.c xfs: improve dquot iteration for scrub 2023-12-15 10:03:45 -08:00
findparent.c xfs: actually rebuild the parent pointer xattrs 2024-04-23 16:55:15 -07:00
findparent.h xfs: implement live updates for directory repairs 2024-04-23 16:55:13 -07:00
fsb_bitmap.h xfs: reintroduce reaping of file metadata blocks to xrep_reap_extents 2023-12-15 10:03:38 -08:00
fscounters.c xfs: return a 64-bit block count from xfs_btree_count_blocks 2024-12-19 18:13:08 +01:00
fscounters.h xfs: support RT inodes in xfs_mod_delalloc 2024-04-22 18:00:48 +05:30
fscounters_repair.c xfs: support RT inodes in xfs_mod_delalloc 2024-04-22 18:00:48 +05:30
health.c xfs: report directory tree corruption in the health information 2024-04-23 16:55:17 -07:00
health.h xfs: refactor the btree cursor allocation logic in xchk_ag_btcur_init 2024-02-22 12:39:48 -08:00
ialloc.c xfs: return a 64-bit block count from xfs_btree_count_blocks 2024-12-19 18:13:08 +01:00
ialloc_repair.c xfs: scrub: convert comma to semicolon 2024-10-07 08:00:11 +02:00
ino_bitmap.h xfs: teach online scrub to find directory tree structure problems 2024-04-23 16:55:16 -07:00
inode.c xfs: ensure unlinked list state is consistent with nlink during scrub 2024-04-15 14:58:54 -07:00
inode_repair.c xfs: replace shouty XFS_BM{BT,DR} macros 2024-09-01 08:58:20 -07:00
iscan.c xfs: use dontcache for grabbing inodes during scrub 2024-04-23 16:55:18 -07:00
iscan.h xfs: scan the filesystem to repair a directory dotdot entry 2024-04-15 14:58:56 -07:00
listxattr.c xfs: add a per-leaf block callback to xchk_xattr_walk 2024-04-23 16:55:15 -07:00
listxattr.h xfs: add a per-leaf block callback to xchk_xattr_walk 2024-04-23 16:55:15 -07:00
newbt.c xfs: convert "skip_discard" to a proper flags bitset 2024-07-02 11:37:01 -07:00
newbt.h xfs: repair the rmapbt 2024-02-22 12:43:38 -08:00
nlinks.c xfs: add a per-leaf block callback to xchk_xattr_walk 2024-04-23 16:55:15 -07:00
nlinks.h xfs: move files to orphanage instead of letting nlinks drop to zero 2024-04-15 14:58:57 -07:00
nlinks_repair.c xfs: drop the scrub file's iolock when transaction allocation fails 2024-04-23 16:55:18 -07:00
off_bitmap.h xfs: repair problems in CoW forks 2023-12-15 10:03:40 -08:00
orphanage.c xfs: invalidate dentries for a file before moving it to the orphanage 2024-04-23 16:55:19 -07:00
orphanage.h xfs: fix corruptions in the directory tree 2024-04-23 16:55:17 -07:00
parent.c xfs: fix a memory leak 2024-07-29 09:25:01 +05:30
parent_repair.c xfs: exchange-range for repairs is no longer dynamic 2024-04-23 16:55:19 -07:00
quota.c xfs: repair quotas 2023-12-15 10:03:45 -08:00
quota.h xfs: repair quotas 2023-12-15 10:03:45 -08:00
quota_repair.c xfs: Remove header files which are included more than once 2024-07-01 09:32:29 +05:30
quotacheck.c xfs: repair dquots based on live quotacheck results 2024-02-22 12:30:57 -08:00
quotacheck.h xfs: repair dquots based on live quotacheck results 2024-02-22 12:30:57 -08:00
quotacheck_repair.c xfs: repair dquots based on live quotacheck results 2024-02-22 12:30:57 -08:00
rcbag.c xfs: create refcount bag structure for btree repairs 2024-02-22 12:43:41 -08:00
rcbag.h xfs: create refcount bag structure for btree repairs 2024-02-22 12:43:41 -08:00
rcbag_btree.c xfs: create refcount bag structure for btree repairs 2024-02-22 12:43:41 -08:00
rcbag_btree.h xfs: create refcount bag structure for btree repairs 2024-02-22 12:43:41 -08:00
readdir.c xfs: refactor dir format helpers 2024-04-26 11:21:46 +05:30
readdir.h xfs: deferred scrub of dirents 2024-04-23 07:47:02 -07:00
reap.c xfs: convert "skip_discard" to a proper flags bitset 2024-07-02 11:37:01 -07:00
reap.h xfs: add the ability to reap entire inode forks 2024-04-15 14:58:49 -07:00
refcount.c xfs: return a 64-bit block count from xfs_btree_count_blocks 2024-12-19 18:13:08 +01:00
refcount_repair.c xfs: port refcount repair to the new refcount bag structure 2024-02-22 12:43:42 -08:00
repair.c xfs: don't fail repairs on metadata files with no attr fork 2024-10-22 13:37:18 +02:00
repair.h xfs: fix online repair probing when CONFIG_XFS_ONLINE_REPAIR=n 2025-02-27 04:30:22 -08:00
rmap.c xfs: repair the rmapbt 2024-02-22 12:43:38 -08:00
rmap_repair.c xfs: Remove unused function is_rt_data_fork 2024-04-22 12:51:43 +05:30
rtbitmap.c xfs: remove conditional building of rt geometry validator functions 2024-01-30 14:04:43 +05:30
rtbitmap.h xfs: online repair of realtime bitmaps 2023-12-15 10:03:43 -08:00
rtbitmap_repair.c xfs: fix error returns from xfs_bmapi_write 2024-04-30 09:45:18 +05:30
rtsummary.c xfs: replace m_rsumsize with m_rsumblocks 2024-09-01 08:58:19 -07:00
rtsummary.h xfs: replace m_rsumsize with m_rsumblocks 2024-09-01 08:58:19 -07:00
rtsummary_repair.c xfs: replace m_rsumsize with m_rsumblocks 2024-09-01 08:58:19 -07:00
scrub.c xfs: fix online repair probing when CONFIG_XFS_ONLINE_REPAIR=n 2025-02-27 04:30:22 -08:00
scrub.h xfs: add xchk_setup_nothing and xchk_nothing helpers 2024-09-01 08:58:19 -07:00
stats.c xfs: teach online scrub to find directory tree structure problems 2024-04-23 16:55:16 -07:00
stats.h xfs: track usage statistics of online fsck 2023-08-10 07:48:07 -07:00
symlink.c xfs: online repair of symbolic links 2024-04-15 14:58:58 -07:00
symlink_repair.c xfs: set XFS_SICK_INO_SYMLINK_ZAPPED explicitly when zapping a symlink 2024-12-19 18:13:08 +01:00
tempexch.h xfs: exchange-range for repairs is no longer dynamic 2024-04-23 16:55:19 -07:00
tempfile.c xfs: pass the icreate args object to xfs_dialloc 2024-09-01 08:58:19 -07:00
tempfile.h xfs: online repair of directories 2024-04-15 14:58:55 -07:00
trace.c xfs: teach online scrub to find directory tree structure problems 2024-04-23 16:55:16 -07:00
trace.h xfs: fix scrub tracepoints when inode-rooted btrees are involved 2024-12-19 18:13:08 +01:00
xfarray.c xfs: drop xfarray sortinfo folio on error 2024-05-27 15:55:52 +05:30
xfarray.h xfs: reduce the rate of cond_resched calls inside scrub 2024-04-23 16:55:17 -07:00
xfblob.c xfs: repair extended attributes 2024-04-15 14:58:53 -07:00
xfblob.h xfs: online repair of directories 2024-04-15 14:58:55 -07:00
xfile.c mm,tmpfs: consider end of file write in shmem_is_huge 2024-09-09 16:39:12 -07:00
xfile.h xfs: repair extended attributes 2024-04-15 14:58:53 -07:00
xfs_scrub.h xfs: introduce vectored scrub mode 2024-04-23 16:55:18 -07:00