summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2021-10-06 07:59:59 -0500
committerAndreas Gruenbacher <agruenba@redhat.com>2021-10-25 08:42:19 +0200
commit60d8bae9d16a52346ba738518bd43702d15eb834 (patch)
tree7b0a86f2936932868c05ff6459e08c36723dd1d7 /fs/gfs2/glock.c
parent17a6eceeb1c54a0a4af5b03ccc1de7ab824408bc (diff)
downloadlinux-60d8bae9d16a52346ba738518bd43702d15eb834.tar.bz2
gfs2: further simplify do_promote
This patch further simplifies function do_promote by eliminating some redundant code in favor of using a lock_released flag. This is just prep work for a future patch. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index f9aebeba7454..db213f0ef960 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -487,12 +487,14 @@ __acquires(&gl->gl_lockref.lock)
const struct gfs2_glock_operations *glops = gl->gl_ops;
struct gfs2_holder *gh, *tmp, *first_gh;
bool incompat_holders_demoted = false;
+ bool lock_released;
int ret;
restart:
first_gh = find_first_strong_holder(gl);
list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
- if (!test_bit(HIF_WAIT, &gh->gh_iflags))
+ lock_released = false;
+ if (test_bit(HIF_HOLDER, &gh->gh_iflags))
continue;
if (!may_grant(gl, first_gh, gh)) {
/*
@@ -511,30 +513,31 @@ restart:
first_gh = gh;
}
if (gh->gh_list.prev == &gl->gl_holders &&
- glops->go_instantiate) {
- if (!(gh->gh_flags & GL_SKIP)) {
- spin_unlock(&gl->gl_lockref.lock);
- /* FIXME: eliminate this eventually */
- ret = glops->go_instantiate(gh);
- spin_lock(&gl->gl_lockref.lock);
- if (ret) {
- if (ret == 1)
- return 2;
- gh->gh_error = ret;
- list_del_init(&gh->gh_list);
- trace_gfs2_glock_queue(gh, 0);
- gfs2_holder_wake(gh);
- goto restart;
- }
+ !(gh->gh_flags & GL_SKIP) && glops->go_instantiate) {
+ lock_released = true;
+ spin_unlock(&gl->gl_lockref.lock);
+ ret = glops->go_instantiate(gh);
+ spin_lock(&gl->gl_lockref.lock);
+ if (ret) {
+ if (ret == 1)
+ return 2;
+ gh->gh_error = ret;
+ list_del_init(&gh->gh_list);
+ trace_gfs2_glock_queue(gh, 0);
+ gfs2_holder_wake(gh);
+ goto restart;
}
- set_bit(HIF_HOLDER, &gh->gh_iflags);
- trace_gfs2_promote(gh);
- gfs2_holder_wake(gh);
- goto restart;
}
set_bit(HIF_HOLDER, &gh->gh_iflags);
trace_gfs2_promote(gh);
gfs2_holder_wake(gh);
+ /*
+ * If we released the gl_lockref.lock the holders list may have
+ * changed. For that reason, we start again at the start of
+ * the holders queue.
+ */
+ if (lock_released)
+ goto restart;
}
return 0;
}