summaryrefslogtreecommitdiff
path: root/include/linux/timerqueue_types.h
diff options
context:
space:
mode:
authorMikhail Lobanov <m.lobanov@rosa.ru>2026-06-10 22:19:04 +0300
committerCarlos Maiolino <cem@kernel.org>2026-06-12 09:57:02 +0200
commit804826eac53cff44f88f42989fcc601c2612c0ed (patch)
treedf2e816f4e3d266266bf5ada5d6fa2629124f820 /include/linux/timerqueue_types.h
parent07e2939ddab876d68d661ebad6c4eedec98193b8 (diff)
xfs: shut down the filesystem on a failed mount
A corrupt/crafted XFS image can make mount fail after background inode inactivation has already been enabled. xfs_mountfs() turns on inodegc (xfs_inodegc_start()) right after log recovery, but the quota subsystem (mp->m_quotainfo) is only allocated much later, in xfs_qm_newmount() / xfs_qm_mount_quotas(). The quota accounting flags in mp->m_qflags are parsed from the mount options before xfs_mountfs() even runs. If the mount then aborts in between - e.g. xfs_rtmount_inodes() failing with "failed to read RT inodes" - the unwind path flushes the inodegc queue, which inactivates the inodes that are still queued, and xfs_inactive() calls xfs_qm_dqattach(). That path trusts XFS_IS_QUOTA_ON() (the flag is set) and dereferences the not yet allocated mp->m_quotainfo: XFS (loop0): failed to read RT inodes Oops: general protection fault, probably for non-canonical address 0xdffffc000000002a: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000150-0x0000000000000157] Workqueue: xfs-inodegc/loop0 xfs_inodegc_worker RIP: 0010:__mutex_lock+0xfe/0x930 Call Trace: xfs_qm_dqget_cache_lookup+0x63/0x7f0 xfs_qm_dqget_inode+0x336/0x860 xfs_qm_dqattach_one+0x232/0x4e0 xfs_qm_dqattach_locked+0x2c6/0x470 xfs_qm_dqattach+0x46/0x70 xfs_inactive+0x988/0xe80 xfs_inodegc_worker+0x27c/0x730 The NULL m_quotainfo deref is only one symptom. The deeper problem is that a failed mount should not be inactivating inodes at all: it must not write to the (possibly corrupt, only partially set up) persistent metadata of a filesystem we just refused to mount, and the subsystems inactivation relies on may not be initialised. Mark the filesystem shut down before flushing the inodegc queue in the xfs_mountfs() failure path. With the preceding patch a shut down mount no longer inactivates the queued inodes: xfs_inactive() returns early so they are dropped straight to reclaim instead. They are still pulled down so reclaim can free them (which is why the flush was added in commit ab23a7768739 ("xfs: per-cpu deferred inode inactivation queues")), but without touching the on-disk structures - matching that comment's own "pull down all the state and flee" intent. Use SHUTDOWN_META_IO_ERROR for the shutdown: it is the generic "cannot safely touch metadata" reason already used elsewhere in this file and in the xfs_ifree() failure path, and unlike SHUTDOWN_FORCE_UMOUNT it does not log a misleading "User initiated shutdown received". A failed mount is not necessarily on-disk corruption (it can be a transient I/O or resource error), so SHUTDOWN_CORRUPT_ONDISK would not be accurate either. Found by fuzzing XFS with syzkaller (corrupt image mount); reproduced and verified under QEMU/KASAN. Fixes: ab23a7768739 ("xfs: per-cpu deferred inode inactivation queues") Signed-off-by: Mikhail Lobanov <m.lobanov@rosa.ru> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
Diffstat (limited to 'include/linux/timerqueue_types.h')
0 files changed, 0 insertions, 0 deletions