]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gfs2: Check for empty queue in run_queue
authorAndreas Gruenbacher <agruenba@redhat.com>
Thu, 6 Feb 2025 13:58:39 +0000 (14:58 +0100)
committerAndreas Gruenbacher <agruenba@redhat.com>
Mon, 10 Mar 2025 17:15:38 +0000 (18:15 +0100)
In run_queue(), check if the queue of pending requests is empty instead
of blindly assuming that it won't be.

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

index dd82bc27c27a0c3884138e934da34a775e92ebb2..5d4d7b7f3af3dbd48bcc9177668bbb9c292ccbad 100644 (file)
@@ -845,12 +845,13 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock)
 __releases(&gl->gl_lockref.lock)
 __acquires(&gl->gl_lockref.lock)
 {
-       struct gfs2_holder *gh = NULL;
+       struct gfs2_holder *gh;
 
        if (test_bit(GLF_LOCK, &gl->gl_flags))
                return;
        set_bit(GLF_LOCK, &gl->gl_flags);
 
+       /* While a demote is in progress, the GLF_LOCK flag must be set. */
        GLOCK_BUG_ON(gl, test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags));
 
        if (test_bit(GLF_DEMOTE, &gl->gl_flags) &&
@@ -862,18 +863,22 @@ __acquires(&gl->gl_lockref.lock)
                set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
                GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE);
                gl->gl_target = gl->gl_demote_state;
+               do_xmote(gl, NULL, gl->gl_target);
+               return;
        } else {
                if (test_bit(GLF_DEMOTE, &gl->gl_flags))
                        gfs2_demote_wake(gl);
                if (do_promote(gl))
                        goto out_unlock;
                gh = find_first_waiter(gl);
+               if (!gh)
+                       goto out_unlock;
                gl->gl_target = gh->gh_state;
                if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
                        do_error(gl, 0); /* Fail queued try locks */
+               do_xmote(gl, gh, gl->gl_target);
+               return;
        }
-       do_xmote(gl, gh, gl->gl_target);
-       return;
 
 out_sched:
        clear_bit(GLF_LOCK, &gl->gl_flags);