linux-stable/fs/xfs
Brian Foster d1db300b8f xfs: detect agfl count corruption and reset agfl
commit a27ba2607e upstream.

The struct xfs_agfl v5 header was originally introduced with
unexpected padding that caused the AGFL to operate with one less
slot than intended. The header has since been packed, but the fix
left an incompatibility for users who upgrade from an old kernel
with the unpacked header to a newer kernel with the packed header
while the AGFL happens to wrap around the end. The newer kernel
recognizes one extra slot at the physical end of the AGFL that the
previous kernel did not. The new kernel will eventually attempt to
allocate a block from that slot, which contains invalid data, and
cause a crash.

This condition can be detected by comparing the active range of the
AGFL to the count. While this detects a padding mismatch, it can
also trigger false positives for unrelated flcount corruption. Since
we cannot distinguish a size mismatch due to padding from unrelated
corruption, we can't trust the AGFL enough to simply repopulate the
empty slot.

Instead, avoid unnecessarily complex detection logic and and use a
solution that can handle any form of flcount corruption that slips
through read verifiers: distrust the entire AGFL and reset it to an
empty state. Any valid blocks within the AGFL are intentionally
leaked. This requires xfs_repair to rectify (which was already
necessary based on the state the AGFL was found in). The reset
mitigates the side effect of the padding mismatch problem from a
filesystem crash to a free space accounting inconsistency. The
generic approach also means that this patch can be safely backported
to kernels with or without a packed struct xfs_agfl.

Check the AGF for an invalid freelist count on initial read from
disk. If detected, set a flag on the xfs_perag to indicate that a
reset is required before the AGFL can be used. In the first
transaction that attempts to use a flagged AGFL, reset it to empty,
warn the user about the inconsistency and allow the freelist fixup
code to repopulate the AGFL with new blocks. The xfs_perag flag is
cleared to eliminate the need for repeated checks on each block
allocation operation.

This allows kernels that include the packing fix commit 96f859d52b
("libxfs: pack the agfl header structure so XFS_AGFL_SIZE is correct")
to handle older unpacked AGFL formats without a filesystem crash.

Suggested-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by Dave Chiluk <chiluk+linuxxfs@indeed.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-05 11:41:55 +02:00
..
libxfs xfs: detect agfl count corruption and reset agfl 2018-06-05 11:41:55 +02:00
Kconfig xfs: define fatal assert build time tunable 2017-06-19 08:59:10 -07:00
kmem.c mm, vmalloc: use __GFP_HIGHMEM implicitly 2017-05-08 17:15:13 -07:00
kmem.h xfs: map KM_MAYFAIL to __GFP_RETRY_MAYFAIL 2017-07-12 16:26:03 -07:00
Makefile xfs: use the common helper uuid_is_null() 2017-06-05 16:59:08 +02:00
mrlock.h
xfs.h xfs: define fatal assert build time tunable 2017-06-19 08:59:10 -07:00
xfs_acl.c xfs: don't change inode mode if ACL update fails 2017-10-11 10:21:06 -07:00
xfs_acl.h xfs: Don't clear SGID when inheriting ACLs 2017-06-27 18:23:21 -07:00
xfs_aops.c xfs: ubsan fixes 2018-02-03 17:39:14 +01:00
xfs_aops.h xfs: perform dax_device lookup at mount 2017-08-31 09:31:47 -07:00
xfs_attr.h xfs: pass along transaction context when reading xattr block buffers 2017-06-20 10:45:22 -07:00
xfs_attr_inactive.c xfs: reinit btree pointer on attr tree inactivation walk 2017-10-11 10:21:07 -07:00
xfs_attr_list.c xfs: assert locking precondіtion in xfs_attr_list_int_ilocked 2017-07-13 14:55:05 -07:00
xfs_bmap_item.c xfs: log recovery should replay deferred ops in order 2018-02-03 17:39:06 +01:00
xfs_bmap_item.h xfs: log recovery should replay deferred ops in order 2018-02-03 17:39:06 +01:00
xfs_bmap_util.c xfs: move more RT specific code under CONFIG_XFS_RT 2017-10-11 10:21:06 -07:00
xfs_bmap_util.h xfs: move more RT specific code under CONFIG_XFS_RT 2017-10-11 10:21:06 -07:00
xfs_buf.c xfs: fortify xfs_alloc_buftarg error handling 2018-02-03 17:39:10 +01:00
xfs_buf.h xfs: perform dax_device lookup at mount 2017-08-31 09:31:47 -07:00
xfs_buf_item.c xfs: fix compiler warnings 2017-09-02 08:22:19 -07:00
xfs_buf_item.h xfs: remove unnecessary dirty bli format check for ordered bufs 2017-09-01 10:55:30 -07:00
xfs_dir2_readdir.c xfs: pass along transaction context when reading directory block buffers 2017-06-20 10:45:22 -07:00
xfs_discard.c Force log to disk before reading the AGF during a fstrim 2018-05-30 07:52:23 +02:00
xfs_discard.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_dquot.c xfs: Properly retry failed dquot items in case of error during buffer writeback 2018-02-03 17:39:15 +01:00
xfs_dquot.h
xfs_dquot_item.c xfs: Properly retry failed dquot items in case of error during buffer writeback 2018-02-03 17:39:15 +01:00
xfs_dquot_item.h
xfs_error.c fs/xfs: Use %pS printk format for direct addresses 2017-09-25 18:22:30 -07:00
xfs_error.h xfs: add log item pinning error injection tag 2017-08-22 09:22:24 -07:00
xfs_export.c
xfs_export.h
xfs_extent_busy.c xfs: fix len comparison in xfs_extent_busy_trim 2017-02-16 17:20:12 -08:00
xfs_extent_busy.h xfs: improve handling of busy extents in the low-level allocator 2017-02-09 10:50:25 -08:00
xfs_extfree_item.c xfs: better log intent item refcount checking 2017-04-25 09:40:42 -07:00
xfs_extfree_item.h
xfs_file.c xfs: prevent creating negative-sized file via INSERT_RANGE 2018-05-09 09:51:52 +02:00
xfs_filestream.c
xfs_filestream.h
xfs_fsmap.c xfs: move two more RT specific functions into CONFIG_XFS_RT 2017-10-16 12:26:50 -07:00
xfs_fsmap.h xfs: implement the GETFSMAP ioctl 2017-04-03 15:18:17 -07:00
xfs_fsops.c xfs: convert XFS_AGFL_SIZE to a helper function 2018-06-05 11:41:55 +02:00
xfs_fsops.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_globals.c xfs: define fatal assert build time tunable 2017-06-19 08:59:10 -07:00
xfs_icache.c xfs: return a distinct error code value for IGET_INCORE cache misses 2017-12-20 10:10:31 +01:00
xfs_icache.h xfs: check if an inode is cached and allocated 2017-06-19 14:11:34 -07:00
xfs_icreate_item.c fs: xfs: xfs_icreate_item: constify xfs_item_ops structure 2016-11-28 14:57:42 +11:00
xfs_icreate_item.h
xfs_inode.c xfs: always free inline data before resetting inode fork during ifree 2018-02-03 17:39:06 +01:00
xfs_inode.h xfs: Switch to iomap for SEEK_HOLE / SEEK_DATA 2017-07-02 22:46:13 -07:00
xfs_inode_item.c xfs: Don't log uninitialised fields in inode structures 2017-10-11 10:21:06 -07:00
xfs_inode_item.h
xfs_ioctl.c xfs: validate bdev support for DAX inode flag 2017-09-26 10:55:19 -07:00
xfs_ioctl.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_ioctl32.c xfs: implement the GETFSMAP ioctl 2017-04-03 15:18:17 -07:00
xfs_ioctl32.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_iomap.c xfs: update i_size after unwritten conversion in dio completion 2017-09-26 10:55:19 -07:00
xfs_iomap.h xfs: update i_size after unwritten conversion in dio completion 2017-09-26 10:55:19 -07:00
xfs_iops.c xfs: truncate pagecache before writeback in xfs_setattr_size() 2017-12-20 10:10:26 +01:00
xfs_iops.h
xfs_itable.c xfs: export various function for the online scrubber 2017-06-19 14:11:34 -07:00
xfs_itable.h xfs: export various function for the online scrubber 2017-06-19 14:11:34 -07:00
xfs_linux.h xfs: XFS_IS_REALTIME_INODE() should be false if no rt device present 2017-09-12 20:02:22 -07:00
xfs_log.c xfs: Fix bool initialization/comparison 2017-10-11 10:21:06 -07:00
xfs_log.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_log_cil.c xfs: Fix leak of discard bio 2017-08-04 13:43:36 -07:00
xfs_log_priv.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_log_recover.c xfs: log recovery should replay deferred ops in order 2018-02-03 17:39:06 +01:00
xfs_message.c xfs: define bug_on_assert debug mode sysfs tunable 2017-06-19 08:59:10 -07:00
xfs_message.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_mount.c xfs: Fix bool initialization/comparison 2017-10-11 10:21:06 -07:00
xfs_mount.h xfs: detect agfl count corruption and reset agfl 2018-06-05 11:41:55 +02:00
xfs_mru_cache.c
xfs_mru_cache.h
xfs_ondisk.h xfs: Don't log uninitialised fields in inode structures 2017-10-11 10:21:06 -07:00
xfs_pnfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_pnfs.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_qm.c xfs: quota: check result of register_shrinker() 2018-03-03 10:24:33 +01:00
xfs_qm.h
xfs_qm_bhv.c xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_qm_syscalls.c xfs: wait on new inodes during quotaoff dquot release 2017-04-28 08:11:08 -07:00
xfs_quota.h
xfs_quotaops.c VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
xfs_refcount_item.c xfs: log recovery should replay deferred ops in order 2018-02-03 17:39:06 +01:00
xfs_refcount_item.h xfs: log recovery should replay deferred ops in order 2018-02-03 17:39:06 +01:00
xfs_reflink.c xfs: handle racy AIO in xfs_reflink_end_cow 2017-10-03 21:27:55 -07:00
xfs_reflink.h xfs: separate function to check if inode shares extents 2017-06-19 14:11:35 -07:00
xfs_rmap_item.c xfs: better log intent item refcount checking 2017-04-25 09:40:42 -07:00
xfs_rmap_item.h
xfs_rtalloc.c xfs: remove the ip argument to xfs_defer_finish 2017-09-01 10:55:30 -07:00
xfs_rtalloc.h xfs: export various function for the online scrubber 2017-06-19 14:11:34 -07:00
xfs_stats.c xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_stats.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_super.c Convert fs/*/* to SB_I_VERSION 2017-10-18 18:51:27 -04:00
xfs_super.h xfs: don't block the log commit handler for discards 2017-02-09 11:36:40 -08:00
xfs_symlink.c xfs: remove the ip argument to xfs_defer_finish 2017-09-01 10:55:30 -07:00
xfs_symlink.h xfs: allow reading of already-locked remote symbolic link 2017-06-20 10:45:22 -07:00
xfs_sysctl.c xfs: garbage collect old cowextsz reservations 2016-10-05 16:26:28 -07:00
xfs_sysctl.h xfs: define bug_on_assert debug mode sysfs tunable 2017-06-19 08:59:10 -07:00
xfs_sysfs.c xfs: replace log_badcrc_factor knob with error injection tag 2017-06-27 18:23:21 -07:00
xfs_sysfs.h
xfs_trace.c xfs: implement the GETFSMAP ioctl 2017-04-03 15:18:17 -07:00
xfs_trace.h xfs: detect agfl count corruption and reset agfl 2018-06-05 11:41:55 +02:00
xfs_trans.c xfs: refactor xfs_trans_roll 2017-09-01 10:55:30 -07:00
xfs_trans.h xfs: disallow marking previously dirty buffers as ordered 2017-09-01 10:55:30 -07:00
xfs_trans_ail.c xfs: add log item pinning error injection tag 2017-08-22 09:22:24 -07:00
xfs_trans_bmap.c xfs: try to avoid blowing out the transaction reservation when bunmaping a shared extent 2017-06-19 08:59:10 -07:00
xfs_trans_buf.c xfs: disallow marking previously dirty buffers as ordered 2017-09-01 10:55:30 -07:00
xfs_trans_dquot.c
xfs_trans_extfree.c
xfs_trans_inode.c xfs: refactor xfs_trans_roll 2017-09-01 10:55:30 -07:00
xfs_trans_priv.h xfs: Properly retry failed inode items in case of error during buffer writeback 2017-08-22 09:22:23 -07:00
xfs_trans_refcount.c xfs: connect refcount adjust functions to upper layers 2016-10-03 09:11:22 -07:00
xfs_trans_rmap.c xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_xattr.c xfs: several xattr functions can be void 2016-12-05 12:32:14 +11:00