gfs2: check gl_object in rgrp glops
authorBob Peterson <rpeterso@redhat.com>
Tue, 24 Jan 2023 19:55:18 +0000 (14:55 -0500)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 31 Jan 2023 21:40:24 +0000 (22:40 +0100)
commitfd5f446f0b3d529e55cf2f81f3b994a7216808ca
treeddea7fed4ff1bd05ae6515b7e126970acce80e92
parentf0e56edc2ec7a40f4e94590172f21317baafb196
gfs2: check gl_object in rgrp glops

Function gfs2_clear_rgrpd() is called during unmount to free all rgrps
and their sub-objects. If the rgrp glock is held (e.g. in SH) it calls
gfs2_glock_cb() to unlock, then calls flush_delayed_work() to make
sure any glock work is finished. However, there is a race with other
cluster nodes who may request the rgrp glock in another mode (say, EX).

Func gfs2_clear_rgrpd() calls glock_clear_object() which sets gl_object
to NULL but that's done without holding the gl_lockref spin_lock.
While the lock is not held Another node's demote request can cause the
state machine to run again, and since the gl_lockref is released in
do_xmote, the second process's call to do_xmote can call go_inval
(rgrp_go_inval) after the gl_object has been cleared, which results in
NULL pointer reference of the rgrp glock's gl_object.

Other go_inval glops functions don't require the gl_object to exist, as
evidenced by function inode_go_inval() which explicitly checks for if
(ip) before referencing gl_object. This patch does the same thing
for rgrp glocks. Both the go_inval and go_sync ops are patched to check
the existence of gl_object (rgd) before trying to dereference it.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/glops.c