mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
xfs: prevent race in zoned space reservations
xfs_zoned_add_available() checks whether the reservation list is empty
before adding blocks to the available-space counter. This check is not
serialized against a task adding itself to the reservation list however.
This allows the space provider to observe an empty list, after which a
reserver can enqueue itself and retry the counter before the new space is
added. The provider then adds the space and returns without waking the
now-eligible reserver, leaving it asleep until GC or another event
provides a wakeup, potentially adding seconds to max write latency.
Take the reservation lock before updating the counter and checking the
list. Use list_empty() because the list is now inspected under its lock.
Taking a per-mount lock when handing back space is far from ideal, but
benchmarking with null_blk showed no measurable performance regression.
Fixes: 0bb2193056 ("xfs: add support for zoned space reservations")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260609075655.1698743-1-hch@lst.de?part=2
Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
parent
f789d291bb
commit
ff99a5f6cb
|
|
@ -85,13 +85,13 @@ xfs_zoned_add_available(
|
|||
struct xfs_zone_info *zi = mp->m_zone_info;
|
||||
struct xfs_zone_reservation *reservation;
|
||||
|
||||
if (list_empty_careful(&zi->zi_reclaim_reservations)) {
|
||||
xfs_add_freecounter(mp, XC_FREE_RTAVAILABLE, count_fsb);
|
||||
spin_lock(&zi->zi_reservation_lock);
|
||||
xfs_add_freecounter(mp, XC_FREE_RTAVAILABLE, count_fsb);
|
||||
if (list_empty(&zi->zi_reclaim_reservations)) {
|
||||
spin_unlock(&zi->zi_reservation_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(&zi->zi_reservation_lock);
|
||||
xfs_add_freecounter(mp, XC_FREE_RTAVAILABLE, count_fsb);
|
||||
count_fsb = xfs_sum_freecounter(mp, XC_FREE_RTAVAILABLE);
|
||||
list_for_each_entry(reservation, &zi->zi_reclaim_reservations, entry) {
|
||||
if (reservation->count_fsb > count_fsb)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user