From: Bob Peterson <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 18/19] gfs2: don't call go_unlock unless demote is close at hand
Date: Wed, 27 Mar 2019 06:35:31 -0600 [thread overview]
Message-ID: <20190327123532.27131-19-rpeterso@redhat.com> (raw)
In-Reply-To: <20190327123532.27131-1-rpeterso@redhat.com>
The go_unlock glops function is only used when unlocking rgrps.
Before this patch, the glock code did:
1. spin_unlock(&gl->gl_lockref.lock);
2. go_unlock
3. spin_lock(&gl->gl_lockref.lock);
The go_unlock function checked for the GLF_DEMOTE or DEMOTE_PENDING
bits, and if set, called rgrp_go_unlock. But doing it that way
leaves a race: by the time rgrp_go_unlock returns, another process
may have set GLF_DEMOTE, causing the go_unlock to have been skipped.
This patch changes function gfs2_glock_dq so that it does not
release the gl_lockref lock until after the test for DEMOTE is
complete, and we know for sure whether it needs demoting (for this go).
That way, nobody can sneak in and change the flag during the function.
For simplicity's sake, I also changed the go_unlock parameter to
accept the glock rather than the holder.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
---
fs/gfs2/glock.c | 9 ++++++---
fs/gfs2/incore.h | 2 +-
fs/gfs2/rgrp.c | 8 +++-----
fs/gfs2/rgrp.h | 2 +-
4 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 72a7b19c3aef..465de5ef8a5d 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1173,9 +1173,12 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
if (find_first_holder(gl) == NULL) {
if (glops->go_unlock) {
GLOCK_BUG_ON(gl, test_and_set_bit(GLF_LOCK, &gl->gl_flags));
- spin_unlock(&gl->gl_lockref.lock);
- glops->go_unlock(gh);
- spin_lock(&gl->gl_lockref.lock);
+ if (test_bit(GLF_DEMOTE, &gl->gl_flags) ||
+ test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags)) {
+ spin_unlock(&gl->gl_lockref.lock);
+ glops->go_unlock(gl);
+ spin_lock(&gl->gl_lockref.lock);
+ }
clear_bit(GLF_LOCK, &gl->gl_flags);
}
if (list_empty(&gl->gl_holders) &&
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 341590b348a3..94afe91deb73 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -242,7 +242,7 @@ struct gfs2_glock_operations {
void (*go_inval) (struct gfs2_glock *gl, int flags);
int (*go_demote_ok) (const struct gfs2_glock *gl);
int (*go_lock) (struct gfs2_holder *gh);
- void (*go_unlock) (struct gfs2_holder *gh);
+ void (*go_unlock) (struct gfs2_glock *gl);
void (*go_dump)(struct seq_file *seq, struct gfs2_glock *gl);
void (*go_callback)(struct gfs2_glock *gl, bool remote);
const int go_type;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 52a4f340a867..2a7f47923f88 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1306,13 +1306,11 @@ void gfs2_rgrp_brelse(struct gfs2_rgrpd *rgd)
*
*/
-void gfs2_rgrp_go_unlock(struct gfs2_holder *gh)
+void gfs2_rgrp_go_unlock(struct gfs2_glock *gl)
{
- struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object;
- int demote_requested = test_bit(GLF_DEMOTE, &gh->gh_gl->gl_flags) |
- test_bit(GLF_PENDING_DEMOTE, &gh->gh_gl->gl_flags);
+ struct gfs2_rgrpd *rgd = gl->gl_object;
- if (rgd && demote_requested)
+ if (rgd)
gfs2_rgrp_brelse(rgd);
}
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index 499079a9dbbe..f2b6665857e1 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -36,7 +36,7 @@ extern int gfs2_rindex_update(struct gfs2_sbd *sdp);
extern void gfs2_free_clones(struct gfs2_rgrpd *rgd);
extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh);
extern void gfs2_rgrp_brelse(struct gfs2_rgrpd *rgd);
-extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh);
+extern void gfs2_rgrp_go_unlock(struct gfs2_glock *gl);
extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip);
--
2.20.1
next prev parent reply other threads:[~2019-03-27 12:35 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-27 12:35 [Cluster-devel] [PATCH 00/19] gfs2: misc recovery patch collection Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 01/19] gfs2: log error reform Bob Peterson
2019-04-09 13:46 ` Andreas Gruenbacher
2019-03-27 12:35 ` [Cluster-devel] [PATCH 02/19] gfs2: Introduce concept of a pending withdraw Bob Peterson
2019-04-09 14:00 ` Andreas Gruenbacher
2019-03-27 12:35 ` [Cluster-devel] [PATCH 03/19] gfs2: Ignore recovery attempts if gfs2 has io error or is withdrawn Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 04/19] gfs2: move check_journal_clean to util.c for future use Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 05/19] gfs2: Allow some glocks to be used during withdraw Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 06/19] gfs2: Make secondary withdrawers wait for first withdrawer Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 07/19] gfs2: Don't write log headers after file system withdraw Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 08/19] gfs2: Force withdraw to replay journals and wait for it to finish Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 09/19] gfs2: Add verbose option to check_journal_clean Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 10/19] gfs2: Check for log write errors before telling dlm to unlock Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 11/19] gfs2: Do log_flush in gfs2_ail_empty_gl even if ail list is empty Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 12/19] gfs2: If the journal isn't live ignore log flushes Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 13/19] gfs2: Issue revokes more intelligently Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 14/19] gfs2: Warn when a journal replay overwrites a rgrp with buffers Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 15/19] gfs2: log which portion of the journal is replayed Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 16/19] gfs2: Only remove revokes that we've submitted Bob Peterson
2019-03-27 12:35 ` [Cluster-devel] [PATCH 17/19] gfs2: eliminate tr_num_revoke_rm Bob Peterson
2019-03-27 12:35 ` Bob Peterson [this message]
2019-03-27 12:35 ` [Cluster-devel] [PATCH 19/19] gfs2: clean_journal was setting sd_log_flush_head replaying other journals Bob Peterson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190327123532.27131-19-rpeterso@redhat.com \
--to=rpeterso@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).