PT-2026-121896
CVE-2026-98924
·
Published
2026-10-23
·
Updated
2026-10-23
Description by
Score
N/A
Not availableNo severity ratings or metrics are available. When they are, we'll update the corresponding info on the page.
In the Linux kernel, the following vulnerability has been resolved:
fs: avoid repeated scans in evict inodes()
We observed hung tasks when users attempted to unmount a filesystem
after its disk had been removed while still in use. During device
removal, fs bdev mark dead() calls evict inodes() while holding s umount.
Each time evict inodes() drops s inode list lock to reschedule, it
restarts the walk from the head of s inodes. With many referenced inodes
at the head of the list, these restarts repeatedly scan the same inodes
without reclaiming them. This can keep s umount held for a long time,
blocking concurrent umount attempts and triggering hung-task reports.
Keep the current inode, already marked I FREEING, out of the disposal
batch until s inode list lock is reacquired. Resume the walk from this
inode and dispose of it in a later batch or at the end of the walk.
The zero-refcount and state checks under i lock allow this walker to
claim the inode by setting I FREEING and removing it from the LRU.
Other reclaimers skip the inode, leaving this walker responsible for
eviction. Only evict() removes it from s inodes, so keeping it out of
the disposal batch ensures that it remains on the list while the lock
is dropped. After reacquiring the lock, reading its current next pointer
accounts for concurrent removal of following inodes.
The existing inode lifetime rules prohibit acquiring a reference to an
inode marked I FREEING or I WILL FREE. iget() requires its caller to
hold i lock and establish that taking a reference is valid. Inode lookup
and igrab() check these flags under i lock when acquiring a reference
from zero. ihold() requires an existing reference, which would keep
i count nonzero and prevent this walker from claiming the inode. These
rules already allow iput final() and the inode shrinker to release
i lock after setting I FREEING and before eviction completes.
A temporary iget() reference would also keep the inode on the list,
but its release must preserve last-reference handling. Another user can
acquire a reference, update lazy timestamps and drop its reference while
the pin is held. If the pin becomes the last reference, dropping it with
atomic dec and test() and evicting directly bypasses iput()'s lazytime
handling and can lose those timestamp updates.
Releasing the pin with iput() preserves that handling, but does not
guarantee eviction. fs bdev mark dead() runs with SB ACTIVE set, so iput()
may retain the inode in cache, whereas evict inodes() must evict eligible
zero-reference inodes. The inode may also have been freed when iput()
returns, so the walker cannot then use it to force eviction. Using
I FREEING preserves the existing eviction behavior without introducing
an additional last-reference transition.
The xfstests auto group passed on ext4 and XFS with known unrelated
failures excluded. No new issues were observed, and the previously
reproducible hung task no longer occurs with this patch.
Found an issue in the description? Have something to add? Feel free to write us 👾