Now we replace the run_queue function with a new state in the glock state machine which does the same thing.
Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/glock.c | 60 +++++++++++++++++++++---------------------------- fs/gfs2/glock.h | 1 + 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 6048867b2d66..82c4614793b3 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -60,9 +60,6 @@ struct gfs2_glock_iter { typedef void (*glock_examiner) (struct gfs2_glock * gl); -static void __state_machine(struct gfs2_glock *gl, int new_state); -static void state_machine(struct gfs2_glock *gl, int new_state); - static struct dentry *gfs2_root; static struct workqueue_struct *glock_workqueue; struct workqueue_struct *gfs2_delete_workqueue; @@ -610,34 +607,11 @@ static inline struct gfs2_holder *find_first_holder(const struct gfs2_glock *gl) return NULL; } -/** - * run_queue - do all outstanding tasks related to a glock - * @gl: The glock in question - * @nonblock: True if we must not block in run_queue - * - */ - -static void run_queue(struct gfs2_glock *gl, const int nonblock) -__releases(&gl->gl_lockref.lock) -__acquires(&gl->gl_lockref.lock) -{ - if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) - return; - - GLOCK_BUG_ON(gl, test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags)); - - if (test_bit(GLF_DEMOTE, &gl->gl_flags) && - gl->gl_demote_state != gl->gl_state) - __state_machine(gl, nonblock ? GL_ST_DEMOTE_NONBLOCK : - GL_ST_BLOCKING_DEMOTE); - else - __state_machine(gl, GL_ST_PROMOTE); -} - /** * __state_machine - the glock state machine * @gl: pointer to the glock we are transitioning * @new_state: The new state we need to execute + * @nonblock: True if we must not block while demoting * * This function handles state transitions for glocks. * When the state_machine is called, it's given a new state that needs to be @@ -646,7 +620,8 @@ __acquires(&gl->gl_lockref.lock) * The lock might be released inside some of the states, so we may need react * to state changes from other calls. */ -static void __state_machine(struct gfs2_glock *gl, int new_state) +static void __state_machine(struct gfs2_glock *gl, int new_state, + const int nonblock) { struct gfs2_holder *gh = NULL; int ret; @@ -727,6 +702,22 @@ static void __state_machine(struct gfs2_glock *gl, int new_state) do_error(gl, 0); /* Fail queued try locks */ gl->gl_mch = GL_ST_DO_XMOTE; break; + + case GL_ST_RUN: + gl->gl_mch = GL_ST_IDLE; + if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) + break; + + GLOCK_BUG_ON(gl, test_bit(GLF_DEMOTE_IN_PROGRESS, + &gl->gl_flags)); + + if (test_bit(GLF_DEMOTE, &gl->gl_flags) && + gl->gl_demote_state != gl->gl_state) + gl->gl_mch = nonblock ? GL_ST_DEMOTE_NONBLOCK : + GL_ST_BLOCKING_DEMOTE; + else + gl->gl_mch = GL_ST_PROMOTE; + break; } } while (gl->gl_mch != GL_ST_IDLE); } @@ -738,12 +729,13 @@ static void __state_machine(struct gfs2_glock *gl, int new_state) * * Just like __state_machine but it acquires the gl_lockref lock */ -static void state_machine(struct gfs2_glock *gl, int new_state) +static void state_machine(struct gfs2_glock *gl, int new_state, + const int nonblock) __releases(&gl->gl_lockref.lock) __acquires(&gl->gl_lockref.lock) { spin_lock(&gl->gl_lockref.lock); - __state_machine(gl, new_state); + __state_machine(gl, new_state, nonblock); spin_unlock(&gl->gl_lockref.lock); } @@ -776,7 +768,7 @@ static void glock_work_func(struct work_struct *work) unsigned int drop_refs = 1; if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) { - state_machine(gl, GL_ST_FINISH_XMOTE); + state_machine(gl, GL_ST_FINISH_XMOTE, 0); drop_refs++; } spin_lock(&gl->gl_lockref.lock); @@ -794,7 +786,7 @@ static void glock_work_func(struct work_struct *work) set_bit(GLF_DEMOTE, &gl->gl_flags); } } - run_queue(gl, 0); + __state_machine(gl, GL_ST_RUN, 0); if (delay) { /* Keep one glock reference for the work we requeue. */ drop_refs--; @@ -1189,7 +1181,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh) gl->gl_lockref.count++; __gfs2_glock_queue_work(gl, 0); } - run_queue(gl, 1); + __state_machine(gl, GL_ST_RUN, 1); spin_unlock(&gl->gl_lockref.lock); if (!(gh->gh_flags & GL_ASYNC)) @@ -1733,7 +1725,7 @@ void gfs2_glock_finish_truncate(struct gfs2_inode *ip) spin_lock(&gl->gl_lockref.lock); clear_bit(GLF_LOCK, &gl->gl_flags); - run_queue(gl, 1); + __state_machine(gl, GL_ST_RUN, 1); spin_unlock(&gl->gl_lockref.lock); } diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 76db63d1efae..0239d3a9040c 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -129,6 +129,7 @@ enum gl_machine_states { GL_ST_DEMOTE_NONBLOCK = 4, /* Demote is in progress - non-blocking */ GL_ST_BLOCKING_DEMOTE = 5, /* Demote is in progress - blocking */ GL_ST_PROMOTE = 6, /* Promote the lock */ + GL_ST_RUN = 7, /* "Run" or progress the lock */ }; struct lm_lockops { -- 2.19.1