gfs2: harden gfs2_glock_hold

Function gfs2_glock_hold() is expected only to be called when the glock is
held, so use lockref_get_not_zero() instead of lockref_get_not_dead().

In addition, when an asynchronous callback arrives in gfs2_glock_cb(), the
glock can already be dead (from __gfs2_glock_put()), or it can be on the glock
lru list with refcount 0, so we cannot use gfs2_glock_hold() there.

With gfs2_glock_cb() now handling dead glocks, we can remove the racy check in
gdlm_bast().

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
Andreas Gruenbacher 2026-08-12 12:08:06 +02:00
parent da26828b82
commit 657e5af4fe
2 changed files with 4 additions and 5 deletions

View File

@ -183,7 +183,7 @@ static void gfs2_free_dead_glocks(struct gfs2_sbd *sdp)
struct gfs2_glock *gfs2_glock_hold(struct gfs2_glock *gl)
{
if (!lockref_get_not_dead(&gl->gl_lockref))
if (!lockref_get_not_zero(&gl->gl_lockref))
GLOCK_BUG_ON(gl, 1);
return gl;
}
@ -1769,7 +1769,9 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
{
unsigned long delay = 0;
gfs2_glock_hold(gl);
if (!lockref_get_not_dead(&gl->gl_lockref))
return;
spin_lock(&gl->gl_lockref.lock);
if (!list_empty(&gl->gl_holders) &&
glock_type(gl) == LM_TYPE_INODE) {

View File

@ -182,9 +182,6 @@ static void gdlm_bast(void *arg, int mode)
{
struct gfs2_glock *gl = arg;
if (__lockref_is_dead(&gl->gl_lockref))
return;
switch (mode) {
case DLM_LOCK_EX:
gfs2_glock_cb(gl, LM_ST_UNLOCKED);