gfs2: Fix withdraw race
authorAndreas Gruenbacher <agruenba@redhat.com>
Wed, 30 Aug 2023 20:09:36 +0000 (22:09 +0200)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 5 Sep 2023 13:58:17 +0000 (15:58 +0200)
commite3da6be3d70449a1f14c99f13cc1eb453a2be4ea
tree8fd68f3768e75c0f0c48f29602bfefd76647e2fd
parentfe0690f0a6f190a9ec0736c01ddeba7a729cf30d
gfs2: Fix withdraw race

Function gfs2_withdraw() tries to synchronize concurrent callers by
atomically setting the SDF_WITHDRAWN flag in the first caller, setting
the SDF_WITHDRAW_IN_PROG flag to indicate that a withdraw is in
progress, performing the actual withdraw, and clearing the
SDF_WITHDRAW_IN_PROG flag when done.  All other callers wait for the
SDF_WITHDRAW_IN_PROG flag to be cleared before returning.

This leaves a small window in which callers can find the SDF_WITHDRAWN
flag set before the SDF_WITHDRAW_IN_PROG flag has been set, causing them
to return prematurely, before the withdraw has been completed.

Fix that by setting the SDF_WITHDRAWN and SDF_WITHDRAW_IN_PROG flags
atomically.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/util.c