Before this patch, function run_queue would do special processing before calling the state machine for the blocking and non-blocking demote-in-progress cases. This function rolls those functions into the state machine, which will allow us to eventually simplify with later patches.
Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/glock.c | 44 +++++++++++++++++++++++++++++--------------- fs/gfs2/glock.h | 2 ++ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 8dc98d069afa..023e2186b374 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -631,21 +631,9 @@ __acquires(&gl->gl_lockref.lock) if (test_bit(GLF_DEMOTE, &gl->gl_flags) && gl->gl_demote_state != gl->gl_state) { - if (find_first_holder(gl)) { - clear_bit(GLF_LOCK, &gl->gl_flags); - smp_mb__after_atomic(); - return; - } - if (nonblock) { - clear_bit(GLF_LOCK, &gl->gl_flags); - smp_mb__after_atomic(); - gl->gl_lockref.count++; - __gfs2_glock_queue_work(gl, 0); - return; - } - 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; + __state_machine(gl, nonblock ? GL_ST_DEMOTE_NONBLOCK : + GL_ST_BLOCKING_DEMOTE); + return; } else { if (test_bit(GLF_DEMOTE, &gl->gl_flags)) gfs2_demote_wake(gl); @@ -713,6 +701,32 @@ static void __state_machine(struct gfs2_glock *gl, int new_state) if (ret == -EAGAIN) gl->gl_mch = GL_ST_FINISH_XMOTE; break; + + case GL_ST_BLOCKING_DEMOTE: + gl->gl_mch = GL_ST_IDLE; + if (find_first_holder(gl)) { + clear_bit(GLF_LOCK, &gl->gl_flags); + smp_mb__after_atomic(); + break; + } + 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; + gl->gl_mch = GL_ST_DO_XMOTE; + break; + + case GL_ST_DEMOTE_NONBLOCK: + gl->gl_mch = GL_ST_IDLE; + if (find_first_holder(gl)) { + clear_bit(GLF_LOCK, &gl->gl_flags); + smp_mb__after_atomic(); + break; + } + clear_bit(GLF_LOCK, &gl->gl_flags); + smp_mb__after_atomic(); + gl->gl_lockref.count++; + __gfs2_glock_queue_work(gl, 0); + break; } } while (gl->gl_mch != GL_ST_IDLE); } diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 8333bbc5a197..c8b704a73638 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -126,6 +126,8 @@ enum gl_machine_states { GL_ST_DO_XMOTE = 2, /* Promote or demote a waiter */ GL_ST_DO_XMOTE_UNLOCK = 3, /* Promote or demote a waiter after a failed state change attempt from dlm. */ + GL_ST_DEMOTE_NONBLOCK = 4, /* Demote is in progress - non-blocking */ + GL_ST_BLOCKING_DEMOTE = 5, /* Demote is in progress - blocking */ }; struct lm_lockops { -- 2.19.1