All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock
@ 2021-10-11 19:39 Bob Peterson
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 01/13] gfs2: Allow append and immutable bits to coexist Bob Peterson
                   ` (12 more replies)
  0 siblings, 13 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:39 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Hi,

This is version 3 of my patch collection: these are bugs and/or improvements
I made as a result of the recent "node scope" bugs and problems encountered
during the testing of them. In other words, some of the patches are not
directly related to the "node scope" bug directly, but they were found while
testing the patches. This version incorporates several suggestions made by
Andreas. Also, I broke the patch "gfs2: fix GL_SKIP node_scope problems" into
three smaller patches that do some refactoring to make sure I got the right
logic.

Andreas Gruenbacher (2):
  gfs2: Save ip from gfs2_glock_nq_init
  gfs2: Remove 'first' trace_gfs2_promote argument

Bob Peterson (11):
  gfs2: Allow append and immutable bits to coexist
  gfs2: dequeue iopen holder in gfs2_inode_lookup error
  gfs2: dump glocks from gfs2_consist_OBJ_i
  gfs2: change go_lock to go_instantiate
  gfs2: re-factor function do_promote
  gfs2: further simplify do_promote
  gfs2: split glock instantiation off from do_promote
  gfs2: fix GL_SKIP node_scope problems
  gfs2: Eliminate GIF_INVALID flag
  gfs2: remove RDF_UPTODATE flag
  gfs2: set glock object after nq

 fs/gfs2/file.c       |  10 +---
 fs/gfs2/glock.c      | 130 +++++++++++++++++++++++++++++++------------
 fs/gfs2/glock.h      |  14 ++++-
 fs/gfs2/glops.c      |  29 +++++-----
 fs/gfs2/incore.h     |   6 +-
 fs/gfs2/inode.c      |  12 ++--
 fs/gfs2/rgrp.c       |  57 +++++++++----------
 fs/gfs2/rgrp.h       |   2 +-
 fs/gfs2/super.c      |   4 +-
 fs/gfs2/trace_gfs2.h |   9 +--
 fs/gfs2/util.c       |   2 +
 11 files changed, 165 insertions(+), 110 deletions(-)

-- 
2.31.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 01/13] gfs2: Allow append and immutable bits to coexist
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
@ 2021-10-11 19:39 ` Bob Peterson
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 02/13] gfs2: Save ip from gfs2_glock_nq_init Bob Peterson
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:39 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Before this patch, function do_gfs2_set_flags checked if the append
and immutable flags were being set while already set. If so, error -EPERM
was given. There's no reason why these two flags should be mutually
exclusive, and if you set them separately, you will, in essence, set
one while it is already set. For example:

chattr +a /mnt/gfs2/file1
chattr +i /mnt/gfs2/file1

The first command sets the append-only flag. Since they are additive,
the second command sets the immutable flag AND append-only flag,
since they both coexist in i_diskflags. So the second command should
not return an error. This bug caused xfstests generic/545 to fail.

This patch simply removes the invalid checks.
I also eliminated an unused parm from do_gfs2_set_flags.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/file.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 84ec053d43b4..89ef6c2dc495 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -213,11 +213,9 @@ void gfs2_set_inode_flags(struct inode *inode)
  * @inode: The inode
  * @reqflags: The flags to set
  * @mask: Indicates which flags are valid
- * @fsflags: The FS_* inode flags passed in
  *
  */
-static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask,
-			     const u32 fsflags)
+static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask)
 {
 	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -237,10 +235,6 @@ static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask,
 		goto out;
 
 	error = -EPERM;
-	if (IS_IMMUTABLE(inode) && (new_flags & GFS2_DIF_IMMUTABLE))
-		goto out;
-	if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY))
-		goto out;
 	if (!IS_IMMUTABLE(inode)) {
 		error = gfs2_permission(&init_user_ns, inode, MAY_WRITE);
 		if (error)
@@ -313,7 +307,7 @@ int gfs2_fileattr_set(struct user_namespace *mnt_userns,
 		mask &= ~(GFS2_DIF_TOPDIR | GFS2_DIF_INHERIT_JDATA);
 	}
 
-	return do_gfs2_set_flags(inode, gfsflags, mask, fsflags);
+	return do_gfs2_set_flags(inode, gfsflags, mask);
 }
 
 static int gfs2_getlabel(struct file *filp, char __user *label)
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 02/13] gfs2: Save ip from gfs2_glock_nq_init
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 01/13] gfs2: Allow append and immutable bits to coexist Bob Peterson
@ 2021-10-11 19:39 ` Bob Peterson
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 03/13] gfs2: dequeue iopen holder in gfs2_inode_lookup error Bob Peterson
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:39 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Andreas Gruenbacher <agruenba@redhat.com>

Before this patch, when a glock was locked by function gfs2_glock_nq_init,
it initialized the holder gh_ip (return address) as gfs2_glock_nq_init.
That made it extremely difficult to track down problems because many
functions call gfs2_glock_nq_init. This patch changes the function so
that it saves gh_ip from the caller of gfs2_glock_nq_init, which makes
it easy to backtrack which holder took the lock.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
---
 fs/gfs2/glock.c |  8 ++++----
 fs/gfs2/glock.h | 13 ++++++++++---
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index b8248ceff3c3..983bfe50bb90 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -824,7 +824,7 @@ static void gfs2_glock_poke(struct gfs2_glock *gl)
 	struct gfs2_holder gh;
 	int error;
 
-	gfs2_holder_init(gl, LM_ST_SHARED, flags, &gh);
+	__gfs2_holder_init(gl, LM_ST_SHARED, flags, &gh, _RET_IP_);
 	error = gfs2_glock_nq(&gh);
 	if (!error)
 		gfs2_glock_dq(&gh);
@@ -1121,12 +1121,12 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
  *
  */
 
-void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags,
-		      struct gfs2_holder *gh)
+void __gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags,
+			struct gfs2_holder *gh, unsigned long ip)
 {
 	INIT_LIST_HEAD(&gh->gh_list);
 	gh->gh_gl = gl;
-	gh->gh_ip = _RET_IP_;
+	gh->gh_ip = ip;
 	gh->gh_owner_pid = get_pid(task_pid(current));
 	gh->gh_state = state;
 	gh->gh_flags = flags;
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 31a8f2f649b5..2a71e2068a95 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -188,8 +188,15 @@ extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
 extern void gfs2_glock_hold(struct gfs2_glock *gl);
 extern void gfs2_glock_put(struct gfs2_glock *gl);
 extern void gfs2_glock_queue_put(struct gfs2_glock *gl);
-extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
-			     u16 flags, struct gfs2_holder *gh);
+
+extern void __gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
+			       u16 flags, struct gfs2_holder *gh,
+			       unsigned long ip);
+static inline void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
+				    u16 flags, struct gfs2_holder *gh) {
+	__gfs2_holder_init(gl, state, flags, gh, _RET_IP_);
+}
+
 extern void gfs2_holder_reinit(unsigned int state, u16 flags,
 			       struct gfs2_holder *gh);
 extern void gfs2_holder_uninit(struct gfs2_holder *gh);
@@ -239,7 +246,7 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,
 {
 	int error;
 
-	gfs2_holder_init(gl, state, flags, gh);
+	__gfs2_holder_init(gl, state, flags, gh, _RET_IP_);
 
 	error = gfs2_glock_nq(gh);
 	if (error)
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 03/13] gfs2: dequeue iopen holder in gfs2_inode_lookup error
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 01/13] gfs2: Allow append and immutable bits to coexist Bob Peterson
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 02/13] gfs2: Save ip from gfs2_glock_nq_init Bob Peterson
@ 2021-10-11 19:39 ` Bob Peterson
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 04/13] gfs2: dump glocks from gfs2_consist_OBJ_i Bob Peterson
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:39 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Before this patch, if function gfs2_inode_lookup encountered an error
after it had locked the iopen glock, it never unlocked it, relying on
the evict code to do the cleanup.  The evict code then took the
inode glock while holding the iopen glock, which violates the locking
order.  For example,

 (1) node A does a gfs2_inode_lookup that fails, leaving the iopen glock
     locked.

 (2) node B calls delete_work_func -> gfs2_lookup_by_inum ->
     gfs2_inode_lookup.  It locks the inode glock and blocks trying to
     lock the iopen glock, which is held by node A.

 (3) node A eventually calls gfs2_evict_inode -> evict_should_delete.
     It blocks trying to lock the inode glock, which is now held by
     node B.

This patch introduces error handling to function gfs2_inode_lookup
so it properly dequeues held iopen glocks on errors.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/inode.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 6e15434b23ac..4f8e5c2bcf1f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -225,6 +225,10 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
 	return inode;
 
 fail:
+	if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
+		glock_clear_object(ip->i_iopen_gh.gh_gl, ip);
+		gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+	}
 	if (io_gl)
 		gfs2_glock_put(io_gl);
 	if (gfs2_holder_initialized(&i_gh))
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 04/13] gfs2: dump glocks from gfs2_consist_OBJ_i
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (2 preceding siblings ...)
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 03/13] gfs2: dequeue iopen holder in gfs2_inode_lookup error Bob Peterson
@ 2021-10-11 19:39 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 05/13] gfs2: change go_lock to go_instantiate Bob Peterson
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:39 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Before this patch, failed consistency checks printed out the object
that failed, but not the object's glock. This patch makes it also
print out the object glock so we can see the glock's holders and flags
to aid with debugging.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/util.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index cf345a86ef67..8241029a2a5d 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -454,6 +454,7 @@ void gfs2_consist_inode_i(struct gfs2_inode *ip,
 		(unsigned long long)ip->i_no_formal_ino,
 		(unsigned long long)ip->i_no_addr,
 		function, file, line);
+	gfs2_dump_glock(NULL, ip->i_gl, 1);
 	gfs2_withdraw(sdp);
 }
 
@@ -475,6 +476,7 @@ void gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd,
 		"  function = %s, file = %s, line = %u\n",
 		(unsigned long long)rgd->rd_addr,
 		function, file, line);
+	gfs2_dump_glock(NULL, rgd->rd_gl, 1);
 	gfs2_withdraw(sdp);
 }
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 05/13] gfs2: change go_lock to go_instantiate
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (3 preceding siblings ...)
  2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 04/13] gfs2: dump glocks from gfs2_consist_OBJ_i Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 06/13] gfs2: Remove 'first' trace_gfs2_promote argument Bob Peterson
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Before this patch, the go_lock glock operations (glops) did not do
any actual locking. They were used to instantiate objects, like reading
in dinodes and rgrps from the media.

This patch renames the functions to go_instantiate for clarity.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/glock.c  | 4 ++--
 fs/gfs2/glops.c  | 8 ++++----
 fs/gfs2/incore.h | 2 +-
 fs/gfs2/rgrp.c   | 2 +-
 fs/gfs2/rgrp.h   | 2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 983bfe50bb90..09eb7d4bdf80 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -402,11 +402,11 @@ __acquires(&gl->gl_lockref.lock)
 			continue;
 		if (may_grant(gl, gh)) {
 			if (gh->gh_list.prev == &gl->gl_holders &&
-			    glops->go_lock) {
+			    glops->go_instantiate) {
 				if (!(gh->gh_flags & GL_SKIP)) {
 					spin_unlock(&gl->gl_lockref.lock);
 					/* FIXME: eliminate this eventually */
-					ret = glops->go_lock(gh);
+					ret = glops->go_instantiate(gh);
 					spin_lock(&gl->gl_lockref.lock);
 					if (ret) {
 						if (ret == 1)
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 4b19f513570f..8452a83bd55a 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -482,13 +482,13 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
 }
 
 /**
- * inode_go_lock - operation done after an inode lock is locked by a process
+ * inode_go_instantiate - read in an inode if necessary
  * @gh: The glock holder
  *
  * Returns: errno
  */
 
-static int inode_go_lock(struct gfs2_holder *gh)
+static int inode_go_instantiate(struct gfs2_holder *gh)
 {
 	struct gfs2_glock *gl = gh->gh_gl;
 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
@@ -740,7 +740,7 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
 	.go_sync = inode_go_sync,
 	.go_inval = inode_go_inval,
 	.go_demote_ok = inode_go_demote_ok,
-	.go_lock = inode_go_lock,
+	.go_instantiate = inode_go_instantiate,
 	.go_dump = inode_go_dump,
 	.go_type = LM_TYPE_INODE,
 	.go_flags = GLOF_ASPACE | GLOF_LRU | GLOF_LVB,
@@ -750,7 +750,7 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
 const struct gfs2_glock_operations gfs2_rgrp_glops = {
 	.go_sync = rgrp_go_sync,
 	.go_inval = rgrp_go_inval,
-	.go_lock = gfs2_rgrp_go_lock,
+	.go_instantiate = gfs2_rgrp_go_instantiate,
 	.go_dump = gfs2_rgrp_go_dump,
 	.go_type = LM_TYPE_RGRP,
 	.go_flags = GLOF_LVB,
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 0fe49770166e..ae669ee7b1d8 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -220,7 +220,7 @@ struct gfs2_glock_operations {
 	int (*go_xmote_bh)(struct gfs2_glock *gl);
 	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);
+	int (*go_instantiate) (struct gfs2_holder *gh);
 	void (*go_dump)(struct seq_file *seq, struct gfs2_glock *gl,
 			const char *fs_id_buf);
 	void (*go_callback)(struct gfs2_glock *gl, bool remote);
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 96b2fbed6bf1..cdcbc822064d 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1288,7 +1288,7 @@ static int update_rgrp_lvb(struct gfs2_rgrpd *rgd)
 	return 0;
 }
 
-int gfs2_rgrp_go_lock(struct gfs2_holder *gh)
+int gfs2_rgrp_go_instantiate(struct gfs2_holder *gh)
 {
 	struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object;
 
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index a6855fd796e0..3e2ca1fb4305 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -31,7 +31,7 @@ extern struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd);
 extern void gfs2_clear_rgrpd(struct gfs2_sbd *sdp);
 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 int gfs2_rgrp_go_instantiate(struct gfs2_holder *gh);
 extern void gfs2_rgrp_brelse(struct gfs2_rgrpd *rgd);
 
 extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip);
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 06/13] gfs2: Remove 'first' trace_gfs2_promote argument
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (4 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 05/13] gfs2: change go_lock to go_instantiate Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 07/13] gfs2: re-factor function do_promote Bob Peterson
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Andreas Gruenbacher <agruenba@redhat.com>

Remove the 'first' argument of trace_gfs2_promote: with GL_SKIP, the
'first' holder isn't the one that instantiates the glock
(gl_instantiate), which is what the 'first' flag was apparently supposed
to indicate.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/glock.c      | 4 ++--
 fs/gfs2/trace_gfs2.h | 9 +++------
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 09eb7d4bdf80..7271b4dd6d6a 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -419,12 +419,12 @@ __acquires(&gl->gl_lockref.lock)
 					}
 				}
 				set_bit(HIF_HOLDER, &gh->gh_iflags);
-				trace_gfs2_promote(gh, 1);
+				trace_gfs2_promote(gh);
 				gfs2_holder_wake(gh);
 				goto restart;
 			}
 			set_bit(HIF_HOLDER, &gh->gh_iflags);
-			trace_gfs2_promote(gh, 0);
+			trace_gfs2_promote(gh);
 			gfs2_holder_wake(gh);
 			continue;
 		}
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h
index bd6c8e9e49db..a5deb9f86831 100644
--- a/fs/gfs2/trace_gfs2.h
+++ b/fs/gfs2/trace_gfs2.h
@@ -197,15 +197,14 @@ TRACE_EVENT(gfs2_demote_rq,
 /* Promotion/grant of a glock */
 TRACE_EVENT(gfs2_promote,
 
-	TP_PROTO(const struct gfs2_holder *gh, int first),
+	TP_PROTO(const struct gfs2_holder *gh),
 
-	TP_ARGS(gh, first),
+	TP_ARGS(gh),
 
 	TP_STRUCT__entry(
 		__field(        dev_t,  dev                     )
 		__field(	u64,	glnum			)
 		__field(	u32,	gltype			)
-		__field(	int,	first			)
 		__field(	u8,	state			)
 	),
 
@@ -213,14 +212,12 @@ TRACE_EVENT(gfs2_promote,
 		__entry->dev	= gh->gh_gl->gl_name.ln_sbd->sd_vfs->s_dev;
 		__entry->glnum	= gh->gh_gl->gl_name.ln_number;
 		__entry->gltype	= gh->gh_gl->gl_name.ln_type;
-		__entry->first	= first;
 		__entry->state	= glock_trace_state(gh->gh_state);
 	),
 
-	TP_printk("%u,%u glock %u:%llu promote %s %s",
+	TP_printk("%u,%u glock %u:%llu promote %s",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->gltype,
 		  (unsigned long long)__entry->glnum,
-		  __entry->first ? "first": "other",
 		  glock_trace_name(__entry->state))
 );
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 07/13] gfs2: re-factor function do_promote
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (5 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 06/13] gfs2: Remove 'first' trace_gfs2_promote argument Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 08/13] gfs2: further simplify do_promote Bob Peterson
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

This patch simply re-factors function do_promote to reduce the indents.
The logic should be unchanged. This makes future patches more readable.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/glock.c | 51 ++++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 7271b4dd6d6a..562dc3d3d9cd 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -400,38 +400,37 @@ __acquires(&gl->gl_lockref.lock)
 	list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
 		if (test_bit(HIF_HOLDER, &gh->gh_iflags))
 			continue;
-		if (may_grant(gl, 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;
-					}
+		if (!may_grant(gl, gh)) {
+			if (gh->gh_list.prev == &gl->gl_holders)
+				return 1;
+			do_error(gl, 0);
+			break;
+		}
+		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;
 				}
-				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);
-			continue;
+			goto restart;
 		}
-		if (gh->gh_list.prev == &gl->gl_holders)
-			return 1;
-		do_error(gl, 0);
-		break;
+		set_bit(HIF_HOLDER, &gh->gh_iflags);
+		trace_gfs2_promote(gh);
+		gfs2_holder_wake(gh);
 	}
 	return 0;
 }
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 08/13] gfs2: further simplify do_promote
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (6 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 07/13] gfs2: re-factor function do_promote Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 09/13] gfs2: split glock instantiation off from do_promote Bob Peterson
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

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>
---
 fs/gfs2/glock.c | 41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 562dc3d3d9cd..1d64b45d1ea9 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -394,10 +394,12 @@ __acquires(&gl->gl_lockref.lock)
 {
 	const struct gfs2_glock_operations *glops = gl->gl_ops;
 	struct gfs2_holder *gh, *tmp;
+	bool lock_released;
 	int ret;
 
 restart:
 	list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
+		lock_released = false;
 		if (test_bit(HIF_HOLDER, &gh->gh_iflags))
 			continue;
 		if (!may_grant(gl, gh)) {
@@ -407,30 +409,31 @@ __acquires(&gl->gl_lockref.lock)
 			break;
 		}
 		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;
 }
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 09/13] gfs2: split glock instantiation off from do_promote
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (7 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 08/13] gfs2: further simplify do_promote Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-12 21:48   ` Andreas Gruenbacher
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 10/13] gfs2: fix GL_SKIP node_scope problems Bob Peterson
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Before this patch, function do_promote had a section of code that did
the actual instantiation.  This patch splits that off into its own
function, gfs2_instantiate, which prepares us for the next patch that
will use that function.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/glock.c | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1d64b45d1ea9..39bfac34e8a4 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -380,6 +380,33 @@ static void do_error(struct gfs2_glock *gl, const int ret)
 	}
 }
 
+/**
+ * gfs2_instantiate - Call the glops instantiate function
+ * @gl: The glock
+ *
+ * Returns: 0 if instantiate was successful, 2 if type specific operation is
+ * underway, or error.
+ */
+static int gfs2_instantiate(struct gfs2_holder *gh)
+{
+	struct gfs2_glock *gl = gh->gh_gl;
+	const struct gfs2_glock_operations *glops = gl->gl_ops;
+	int ret;
+
+	ret = glops->go_instantiate(gh);
+	switch(ret) {
+	case 0:
+		break;
+	case 1:
+		ret = 2;
+		break;
+	default:
+		gh->gh_error = ret;
+		break;
+	}
+	return ret;
+}
+
 /**
  * do_promote - promote as many requests as possible on the current queue
  * @gl: The glock
@@ -392,7 +419,6 @@ static int do_promote(struct gfs2_glock *gl)
 __releases(&gl->gl_lockref.lock)
 __acquires(&gl->gl_lockref.lock)
 {
-	const struct gfs2_glock_operations *glops = gl->gl_ops;
 	struct gfs2_holder *gh, *tmp;
 	bool lock_released;
 	int ret;
@@ -409,19 +435,20 @@ __acquires(&gl->gl_lockref.lock)
 			break;
 		}
 		if (gh->gh_list.prev == &gl->gl_holders &&
-		    !(gh->gh_flags & GL_SKIP) && glops->go_instantiate) {
+		    !(gh->gh_flags & GL_SKIP) && gl->gl_ops->go_instantiate) {
 			lock_released = true;
 			spin_unlock(&gl->gl_lockref.lock);
-			ret = glops->go_instantiate(gh);
+			ret = gfs2_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;
+				if (ret == 2)
+					return ret;
+				else {
+					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);
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 10/13] gfs2: fix GL_SKIP node_scope problems
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (8 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 09/13] gfs2: split glock instantiation off from do_promote Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 11/13] gfs2: Eliminate GIF_INVALID flag Bob Peterson
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Before this patch, when a glock was locked, the very first holder on the
queue would unlock the lockref and call the go_instantiate glops function
(if one existed), unless GL_SKIP was specified. When we introduced the new
node-scope concept, we allowed multiple holders to lock glocks in EX mode
and share the lock.

But node-scope introduced a new problem: if the first holder has GL_SKIP
and the next one does NOT, since it is not the first holder on the queue,
the go_instantiate op was not called. Eventually the GL_SKIP holder may
call the instantiate sub-function (e.g. gfs2_rgrp_bh_get) but there was
still a window of time in which another non-GL_SKIP holder assumes the
instantiate function had been called by the first holder. In the case of
rgrp glocks, this led to a NULL pointer dereference on the buffer_heads.

This patch tries to fix the problem by introducing two new glock flags:

GLF_INSTANTIATE_NEEDED, which keeps track of when the instantiate function
needs to be called to "fill in" or "read in" the object before it is
referenced.

GLF_INSTANTIATE_IN_PROG which is used to determine when a process is
in the process of reading in the object. Whenever a function needs to
reference the object, it checks the GLF_INSTANTIATE_NEEDED flag, and if
set, it sets GLF_INSTANTIATE_IN_PROG and calls the glops "go_instantiate"
function.

As before, the gl_lockref spin_lock is unlocked during the IO operation,
which may take a relatively long amount of time to complete. While
unlocked, if another process determines go_instantiate is still needed,
it sees GLF_INSTANTIATE_IN_PROG is set, and waits for the go_instantiate
glop operation to be completed. Once GLF_INSTANTIATE_IN_PROG is cleared,
it needs to check GLF_INSTANTIATE_NEEDED again because the other process's
go_instantiate operation may not have been successful.

Functions that previously called the instantiate sub-functions now call
directly into gfs2_instantiate so the new bits are managed properly.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/glock.c  | 37 ++++++++++++++++++++++++++++++++++---
 fs/gfs2/glock.h  |  1 +
 fs/gfs2/glops.c  | 10 ++++++----
 fs/gfs2/incore.h |  2 ++
 fs/gfs2/inode.c  |  3 ++-
 fs/gfs2/rgrp.c   | 21 +++++++++++----------
 fs/gfs2/super.c  |  2 +-
 7 files changed, 57 insertions(+), 19 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 39bfac34e8a4..d76a8f2d69f1 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -387,15 +387,39 @@ static void do_error(struct gfs2_glock *gl, const int ret)
  * Returns: 0 if instantiate was successful, 2 if type specific operation is
  * underway, or error.
  */
-static int gfs2_instantiate(struct gfs2_holder *gh)
+int gfs2_instantiate(struct gfs2_holder *gh)
 {
 	struct gfs2_glock *gl = gh->gh_gl;
 	const struct gfs2_glock_operations *glops = gl->gl_ops;
 	int ret;
 
+again:
+	if (!test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags))
+		return 0;
+
+	/*
+	 * Since we unlock the lockref lock, we set a flag to indicate
+	 * instantiate is in progress.
+	 */
+	if (test_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags)) {
+		wait_on_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG,
+			    TASK_UNINTERRUPTIBLE);
+		/*
+		 * Here we just waited for a different instantiate to finish.
+		 * But that may not have been successful, as when a process
+		 * locks an inode glock _before_ it has an actual inode to
+		 * instantiate into. So we check again. This process might
+		 * have an inode to instantiate, so might be successful.
+		 */
+		goto again;
+	}
+
+	set_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
+
 	ret = glops->go_instantiate(gh);
 	switch(ret) {
 	case 0:
+		clear_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
 		break;
 	case 1:
 		ret = 2;
@@ -404,6 +428,9 @@ static int gfs2_instantiate(struct gfs2_holder *gh)
 		gh->gh_error = ret;
 		break;
 	}
+	clear_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
+	smp_mb__after_atomic();
+	wake_up_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG);
 	return ret;
 }
 
@@ -434,7 +461,7 @@ __acquires(&gl->gl_lockref.lock)
 			do_error(gl, 0);
 			break;
 		}
-		if (gh->gh_list.prev == &gl->gl_holders &&
+		if (test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags) &&
 		    !(gh->gh_flags & GL_SKIP) && gl->gl_ops->go_instantiate) {
 			lock_released = true;
 			spin_unlock(&gl->gl_lockref.lock);
@@ -1088,7 +1115,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
 
 	atomic_inc(&sdp->sd_glock_disposal);
 	gl->gl_node.next = NULL;
-	gl->gl_flags = 0;
+	gl->gl_flags = glops->go_instantiate ? BIT(GLF_INSTANTIATE_NEEDED) : 0;
 	gl->gl_name = name;
 	lockdep_set_subclass(&gl->gl_lockref.lock, glops->go_subclass);
 	gl->gl_lockref.count = 1;
@@ -2177,6 +2204,10 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)
 		*p++ = 'P';
 	if (test_bit(GLF_FREEING, gflags))
 		*p++ = 'x';
+	if (test_bit(GLF_INSTANTIATE_NEEDED, gflags))
+		*p++ = 'n';
+	if (test_bit(GLF_INSTANTIATE_IN_PROG, gflags))
+		*p++ = 'N';
 	*p = 0;
 	return buf;
 }
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 2a71e2068a95..0b774dcc408a 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -202,6 +202,7 @@ extern void gfs2_holder_reinit(unsigned int state, u16 flags,
 extern void gfs2_holder_uninit(struct gfs2_holder *gh);
 extern int gfs2_glock_nq(struct gfs2_holder *gh);
 extern int gfs2_glock_poll(struct gfs2_holder *gh);
+extern int gfs2_instantiate(struct gfs2_holder *gh);
 extern int gfs2_glock_wait(struct gfs2_holder *gh);
 extern int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs);
 extern void gfs2_glock_dq(struct gfs2_holder *gh);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 8452a83bd55a..e2656baf38a3 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -357,6 +357,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
 		truncate_inode_pages(mapping, 0);
 		if (ip) {
 			set_bit(GIF_INVALID, &ip->i_flags);
+			set_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
 			forget_all_cached_acls(&ip->i_inode);
 			security_inode_invalidate_secctx(&ip->i_inode);
 			gfs2_dir_hash_inval(ip);
@@ -495,13 +496,13 @@ static int inode_go_instantiate(struct gfs2_holder *gh)
 	struct gfs2_inode *ip = gl->gl_object;
 	int error = 0;
 
-	if (!ip)
-		return 0;
+	if (!ip) /* no inode to populate - read it in later */
+		goto out;
 
 	if (test_bit(GIF_INVALID, &ip->i_flags)) {
 		error = gfs2_inode_refresh(ip);
 		if (error)
-			return error;
+			goto out;
 	}
 
 	if (gh->gh_state != LM_ST_DEFERRED)
@@ -515,9 +516,10 @@ static int inode_go_instantiate(struct gfs2_holder *gh)
 			list_add(&ip->i_trunc_list, &sdp->sd_trunc_list);
 		spin_unlock(&sdp->sd_trunc_lock);
 		wake_up(&sdp->sd_quota_wait);
-		return 1;
+		error = 1;
 	}
 
+out:
 	return error;
 }
 
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index ae669ee7b1d8..e119b87128f4 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -315,6 +315,7 @@ struct gfs2_alloc_parms {
 
 enum {
 	GLF_LOCK			= 1,
+	GLF_INSTANTIATE_NEEDED		= 2, /* needs instantiate */
 	GLF_DEMOTE			= 3,
 	GLF_PENDING_DEMOTE		= 4,
 	GLF_DEMOTE_IN_PROGRESS		= 5,
@@ -324,6 +325,7 @@ enum {
 	GLF_REPLY_PENDING		= 9,
 	GLF_INITIAL			= 10,
 	GLF_FROZEN			= 11,
+	GLF_INSTANTIATE_IN_PROG		= 12, /* instantiate happening now */
 	GLF_LRU				= 13,
 	GLF_OBJECT			= 14, /* Used only for tracing */
 	GLF_BLOCKING			= 15,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 4f8e5c2bcf1f..8569142901f6 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -183,6 +183,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
 
 		glock_set_object(ip->i_gl, ip);
 		set_bit(GIF_INVALID, &ip->i_flags);
+		set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags);
 		error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
 		if (unlikely(error))
 			goto fail;
@@ -196,7 +197,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
 
 		if (type == DT_UNKNOWN) {
 			/* Inode glock must be locked already */
-			error = gfs2_inode_refresh(GFS2_I(inode));
+			error = gfs2_instantiate(&i_gh);
 			if (error)
 				goto fail;
 		} else {
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index cdcbc822064d..5ee7da3a450e 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1238,8 +1238,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
 		rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd));
 		gfs2_rgrp_ondisk2lvb(rgd->rd_rgl,
 				     rgd->rd_bits[0].bi_bh->b_data);
-	}
-	else if (sdp->sd_args.ar_rgrplvb) {
+	} else if (sdp->sd_args.ar_rgrplvb) {
 		if (!gfs2_rgrp_lvb_valid(rgd)){
 			gfs2_consist_rgrpd(rgd);
 			error = -EIO;
@@ -1257,11 +1256,10 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
 		bi->bi_bh = NULL;
 		gfs2_assert_warn(sdp, !bi->bi_clone);
 	}
-
 	return error;
 }
 
-static int update_rgrp_lvb(struct gfs2_rgrpd *rgd)
+static int update_rgrp_lvb(struct gfs2_rgrpd *rgd, struct gfs2_holder *gh)
 {
 	u32 rl_flags;
 
@@ -1269,7 +1267,7 @@ static int update_rgrp_lvb(struct gfs2_rgrpd *rgd)
 		return 0;
 
 	if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic)
-		return gfs2_rgrp_bh_get(rgd);
+		return gfs2_instantiate(gh);
 
 	rl_flags = be32_to_cpu(rgd->rd_rgl->rl_flags);
 	rl_flags &= ~GFS2_RDF_MASK;
@@ -1312,6 +1310,7 @@ void gfs2_rgrp_brelse(struct gfs2_rgrpd *rgd)
 			bi->bi_bh = NULL;
 		}
 	}
+	set_bit(GLF_INSTANTIATE_NEEDED, &rgd->rd_gl->gl_flags);
 }
 
 int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
@@ -2110,7 +2109,8 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap)
 			    gfs2_rgrp_congested(rs->rs_rgd, loops))
 				goto skip_rgrp;
 			if (sdp->sd_args.ar_rgrplvb) {
-				error = update_rgrp_lvb(rs->rs_rgd);
+				error = update_rgrp_lvb(rs->rs_rgd,
+							&ip->i_rgd_gh);
 				if (unlikely(error)) {
 					rgrp_unlock_local(rs->rs_rgd);
 					gfs2_glock_dq_uninit(&ip->i_rgd_gh);
@@ -2125,8 +2125,11 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap)
 		    (loops == 0 && target > rs->rs_rgd->rd_extfail_pt))
 			goto skip_rgrp;
 
-		if (sdp->sd_args.ar_rgrplvb)
-			gfs2_rgrp_bh_get(rs->rs_rgd);
+		if (sdp->sd_args.ar_rgrplvb) {
+			error = gfs2_instantiate(&ip->i_rgd_gh);
+			if (error)
+				goto skip_rgrp;
+		}
 
 		/* Get a reservation if we don't already have one */
 		if (!gfs2_rs_active(rs))
@@ -2762,8 +2765,6 @@ void gfs2_rlist_free(struct gfs2_rgrp_list *rlist)
 
 void rgrp_lock_local(struct gfs2_rgrpd *rgd)
 {
-	GLOCK_BUG_ON(rgd->rd_gl, !gfs2_glock_is_held_excl(rgd->rd_gl) &&
-		     !test_bit(SDF_NORECOVERY, &rgd->rd_sbd->sd_flags));
 	mutex_lock(&rgd->rd_mutex);
 }
 
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 6e00d15ef0a8..26c726580041 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1245,7 +1245,7 @@ static enum dinode_demise evict_should_delete(struct inode *inode,
 		return SHOULD_NOT_DELETE_DINODE;
 
 	if (test_bit(GIF_INVALID, &ip->i_flags)) {
-		ret = gfs2_inode_refresh(ip);
+		ret = gfs2_instantiate(gh);
 		if (ret)
 			return SHOULD_NOT_DELETE_DINODE;
 	}
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 11/13] gfs2: Eliminate GIF_INVALID flag
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (9 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 10/13] gfs2: fix GL_SKIP node_scope problems Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 12/13] gfs2: remove RDF_UPTODATE flag Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 13/13] gfs2: set glock object after nq Bob Peterson
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

With the addition of the new GLF_INSTANTIATE_NEEDED flag, the
GIF_INVALID flag is now redundant. This patch removes it.
Since inode_instantiate is only called when instantiation is needed,
the check in inode_instantiate is removed too.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/glops.c  | 11 +++--------
 fs/gfs2/incore.h |  1 -
 fs/gfs2/inode.c  |  1 -
 fs/gfs2/super.c  |  2 +-
 4 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index e2656baf38a3..0b6a59f71eef 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -356,7 +356,6 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
 		struct address_space *mapping = gfs2_glock2aspace(gl);
 		truncate_inode_pages(mapping, 0);
 		if (ip) {
-			set_bit(GIF_INVALID, &ip->i_flags);
 			set_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
 			forget_all_cached_acls(&ip->i_inode);
 			security_inode_invalidate_secctx(&ip->i_inode);
@@ -477,8 +476,6 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
 
 	error = gfs2_dinode_in(ip, dibh->b_data);
 	brelse(dibh);
-	clear_bit(GIF_INVALID, &ip->i_flags);
-
 	return error;
 }
 
@@ -499,11 +496,9 @@ static int inode_go_instantiate(struct gfs2_holder *gh)
 	if (!ip) /* no inode to populate - read it in later */
 		goto out;
 
-	if (test_bit(GIF_INVALID, &ip->i_flags)) {
-		error = gfs2_inode_refresh(ip);
-		if (error)
-			goto out;
-	}
+	error = gfs2_inode_refresh(ip);
+	if (error)
+		goto out;
 
 	if (gh->gh_state != LM_ST_DEFERRED)
 		inode_dio_wait(&ip->i_inode);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index e119b87128f4..183badadac85 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -372,7 +372,6 @@ struct gfs2_glock {
 };
 
 enum {
-	GIF_INVALID		= 0,
 	GIF_QD_LOCKED		= 1,
 	GIF_ALLOC_FAILED	= 2,
 	GIF_SW_PAGED		= 3,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 8569142901f6..700f577fe3ff 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -182,7 +182,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
 		}
 
 		glock_set_object(ip->i_gl, ip);
-		set_bit(GIF_INVALID, &ip->i_flags);
 		set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags);
 		error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
 		if (unlikely(error))
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 26c726580041..5b121371508a 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1244,7 +1244,7 @@ static enum dinode_demise evict_should_delete(struct inode *inode,
 	if (ret)
 		return SHOULD_NOT_DELETE_DINODE;
 
-	if (test_bit(GIF_INVALID, &ip->i_flags)) {
+	if (test_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags)) {
 		ret = gfs2_instantiate(gh);
 		if (ret)
 			return SHOULD_NOT_DELETE_DINODE;
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 12/13] gfs2: remove RDF_UPTODATE flag
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (10 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 11/13] gfs2: Eliminate GIF_INVALID flag Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 13/13] gfs2: set glock object after nq Bob Peterson
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

The new GLF_INSTANTIATE_NEEDED flag obsoletes the old rgrp flag
GFS2_RDF_UPTODATE, so this patch replaces it like we did with inodes.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/glops.c  |  2 +-
 fs/gfs2/incore.h |  1 -
 fs/gfs2/rgrp.c   | 36 ++++++++++++++----------------------
 3 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 0b6a59f71eef..650ad77c4d0b 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -228,7 +228,7 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
 	gfs2_rgrp_brelse(rgd);
 	WARN_ON_ONCE(!(flags & DIO_METADATA));
 	truncate_inode_pages_range(mapping, start, end);
-	rgd->rd_flags &= ~GFS2_RDF_UPTODATE;
+	set_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
 }
 
 static void gfs2_rgrp_go_dump(struct seq_file *seq, struct gfs2_glock *gl,
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 183badadac85..22a753be3a63 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -119,7 +119,6 @@ struct gfs2_rgrpd {
 	u32 rd_flags;
 	u32 rd_extfail_pt;		/* extent failure point */
 #define GFS2_RDF_CHECK		0x10000000 /* check for unlinked inodes */
-#define GFS2_RDF_UPTODATE	0x20000000 /* rg is up to date */
 #define GFS2_RDF_ERROR		0x40000000 /* error in rg */
 #define GFS2_RDF_PREFERRED	0x80000000 /* This rgrp is preferred */
 #define GFS2_RDF_MASK		0xf0000000 /* mask for internal flags */
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 5ee7da3a450e..0fb3c01bc557 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -932,7 +932,7 @@ static int read_rindex_entry(struct gfs2_inode *ip)
 		goto fail;
 
 	rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr;
-	rgd->rd_flags &= ~(GFS2_RDF_UPTODATE | GFS2_RDF_PREFERRED);
+	rgd->rd_flags &= ~GFS2_RDF_PREFERRED;
 	if (rgd->rd_data > sdp->sd_max_rg_data)
 		sdp->sd_max_rg_data = rgd->rd_data;
 	spin_lock(&sdp->sd_rindex_spin);
@@ -1185,8 +1185,8 @@ static void rgrp_set_bitmap_flags(struct gfs2_rgrpd *rgd)
 }
 
 /**
- * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps
- * @rgd: the struct gfs2_rgrpd describing the RG to read in
+ * gfs2_rgrp_go_instantiate - Read in a RG's header and bitmaps
+ * @gh: the glock holder representing the rgrpd to read in
  *
  * Read in all of a Resource Group's header and bitmap blocks.
  * Caller must eventually call gfs2_rgrp_brelse() to free the bitmaps.
@@ -1194,10 +1194,11 @@ static void rgrp_set_bitmap_flags(struct gfs2_rgrpd *rgd)
  * Returns: errno
  */
 
-static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
+int gfs2_rgrp_go_instantiate(struct gfs2_holder *gh)
 {
+	struct gfs2_glock *gl = gh->gh_gl;
+	struct gfs2_rgrpd *rgd = gl->gl_object;
 	struct gfs2_sbd *sdp = rgd->rd_sbd;
-	struct gfs2_glock *gl = rgd->rd_gl;
 	unsigned int length = rgd->rd_length;
 	struct gfs2_bitmap *bi;
 	unsigned int x, y;
@@ -1225,15 +1226,13 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
 		}
 	}
 
-	if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) {
-		gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data);
-		rgrp_set_bitmap_flags(rgd);
-		rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK);
-		rgd->rd_free_clone = rgd->rd_free;
-		GLOCK_BUG_ON(rgd->rd_gl, rgd->rd_reserved);
-		/* max out the rgrp allocation failure point */
-		rgd->rd_extfail_pt = rgd->rd_free;
-	}
+	gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data);
+	rgrp_set_bitmap_flags(rgd);
+	rgd->rd_flags |= GFS2_RDF_CHECK;
+	rgd->rd_free_clone = rgd->rd_free;
+	GLOCK_BUG_ON(rgd->rd_gl, rgd->rd_reserved);
+	/* max out the rgrp allocation failure point */
+	rgd->rd_extfail_pt = rgd->rd_free;
 	if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) {
 		rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd));
 		gfs2_rgrp_ondisk2lvb(rgd->rd_rgl,
@@ -1263,7 +1262,7 @@ static int update_rgrp_lvb(struct gfs2_rgrpd *rgd, struct gfs2_holder *gh)
 {
 	u32 rl_flags;
 
-	if (rgd->rd_flags & GFS2_RDF_UPTODATE)
+	if (!test_bit(GLF_INSTANTIATE_NEEDED, &gh->gh_gl->gl_flags))
 		return 0;
 
 	if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic)
@@ -1286,13 +1285,6 @@ static int update_rgrp_lvb(struct gfs2_rgrpd *rgd, struct gfs2_holder *gh)
 	return 0;
 }
 
-int gfs2_rgrp_go_instantiate(struct gfs2_holder *gh)
-{
-	struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object;
-
-	return gfs2_rgrp_bh_get(rgd);
-}
-
 /**
  * gfs2_rgrp_brelse - Release RG bitmaps read in with gfs2_rgrp_bh_get()
  * @rgd: The resource group
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 13/13] gfs2: set glock object after nq
  2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
                   ` (11 preceding siblings ...)
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 12/13] gfs2: remove RDF_UPTODATE flag Bob Peterson
@ 2021-10-11 19:40 ` Bob Peterson
  12 siblings, 0 replies; 15+ messages in thread
From: Bob Peterson @ 2021-10-11 19:40 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Before this patch, function gfs2_create_inode called glock_set_object to
set the gl_object for inode and iopen glocks before the glock was locked.
That's wrong because other competing processes like evict may be
blocked waiting for the glock and still have gl_object set before the
actual eviction can take place.

This patch moves the call to glock_set_object until after the glock is
acquire in function gfs2_create_inode, so it waits for possibly
competing evicts to finish their processing first.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/gfs2/inode.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 700f577fe3ff..aed4f476c97d 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -731,18 +731,17 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 	if (error)
 		goto fail_free_inode;
 	flush_delayed_work(&ip->i_gl->gl_work);
-	glock_set_object(ip->i_gl, ip);
 
 	error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
 	if (error)
 		goto fail_free_inode;
 	gfs2_cancel_delete_work(io_gl);
-	glock_set_object(io_gl, ip);
 
 	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
 	if (error)
 		goto fail_gunlock2;
 
+	glock_set_object(ip->i_gl, ip);
 	error = gfs2_trans_begin(sdp, blocks, 0);
 	if (error)
 		goto fail_gunlock2;
@@ -758,6 +757,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 	if (error)
 		goto fail_gunlock2;
 
+	glock_set_object(io_gl, ip);
 	gfs2_set_iop(inode);
 	insert_inode_hash(inode);
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Cluster-devel] [GFS2 v3 PATCH 09/13] gfs2: split glock instantiation off from do_promote
  2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 09/13] gfs2: split glock instantiation off from do_promote Bob Peterson
@ 2021-10-12 21:48   ` Andreas Gruenbacher
  0 siblings, 0 replies; 15+ messages in thread
From: Andreas Gruenbacher @ 2021-10-12 21:48 UTC (permalink / raw)
  To: cluster-devel.redhat.com

On Mon, Oct 11, 2021 at 9:41 PM Bob Peterson <rpeterso@redhat.com> wrote:
> Before this patch, function do_promote had a section of code that did
> the actual instantiation.  This patch splits that off into its own
> function, gfs2_instantiate, which prepares us for the next patch that
> will use that function.
>
> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> ---
>  fs/gfs2/glock.c | 47 +++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 37 insertions(+), 10 deletions(-)
>
> diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
> index 1d64b45d1ea9..39bfac34e8a4 100644
> --- a/fs/gfs2/glock.c
> +++ b/fs/gfs2/glock.c
> @@ -380,6 +380,33 @@ static void do_error(struct gfs2_glock *gl, const int ret)
>         }
>  }
>
> +/**
> + * gfs2_instantiate - Call the glops instantiate function
> + * @gl: The glock
> + *
> + * Returns: 0 if instantiate was successful, 2 if type specific operation is
> + * underway, or error.
> + */
> +static int gfs2_instantiate(struct gfs2_holder *gh)
> +{
> +       struct gfs2_glock *gl = gh->gh_gl;
> +       const struct gfs2_glock_operations *glops = gl->gl_ops;
> +       int ret;
> +
> +       ret = glops->go_instantiate(gh);
> +       switch(ret) {
> +       case 0:
> +               break;
> +       case 1:
> +               ret = 2;
> +               break;
> +       default:
> +               gh->gh_error = ret;
> +               break;
> +       }
> +       return ret;
> +}

Moving the return value tweaking here doesn't help, it only
complicates gfs2_instantiate. So let me revert that.

> +
>  /**
>   * do_promote - promote as many requests as possible on the current queue
>   * @gl: The glock
> @@ -392,7 +419,6 @@ static int do_promote(struct gfs2_glock *gl)
>  __releases(&gl->gl_lockref.lock)
>  __acquires(&gl->gl_lockref.lock)
>  {
> -       const struct gfs2_glock_operations *glops = gl->gl_ops;
>         struct gfs2_holder *gh, *tmp;
>         bool lock_released;
>         int ret;
> @@ -409,19 +435,20 @@ __acquires(&gl->gl_lockref.lock)
>                         break;
>                 }
>                 if (gh->gh_list.prev == &gl->gl_holders &&
> -                   !(gh->gh_flags & GL_SKIP) && glops->go_instantiate) {
> +                   !(gh->gh_flags & GL_SKIP) && gl->gl_ops->go_instantiate) {
>                         lock_released = true;
>                         spin_unlock(&gl->gl_lockref.lock);
> -                       ret = glops->go_instantiate(gh);
> +                       ret = gfs2_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;
> +                               if (ret == 2)
> +                                       return ret;
> +                               else {
> +                                       list_del_init(&gh->gh_list);
> +                                       trace_gfs2_glock_queue(gh, 0);
> +                                       gfs2_holder_wake(gh);
> +                                       goto restart;
> +                               }

We can replace the "else { XXX }" with "XXX" here.

>                         }
>                 }
>                 set_bit(HIF_HOLDER, &gh->gh_iflags);
> --
> 2.31.1
>

Thanks,
Andreas



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2021-10-12 21:48 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-11 19:39 [Cluster-devel] [GFS2 v3 PATCH 00/13] gfs2: fix bugs related to node_scope and go_lock Bob Peterson
2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 01/13] gfs2: Allow append and immutable bits to coexist Bob Peterson
2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 02/13] gfs2: Save ip from gfs2_glock_nq_init Bob Peterson
2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 03/13] gfs2: dequeue iopen holder in gfs2_inode_lookup error Bob Peterson
2021-10-11 19:39 ` [Cluster-devel] [GFS2 v3 PATCH 04/13] gfs2: dump glocks from gfs2_consist_OBJ_i Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 05/13] gfs2: change go_lock to go_instantiate Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 06/13] gfs2: Remove 'first' trace_gfs2_promote argument Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 07/13] gfs2: re-factor function do_promote Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 08/13] gfs2: further simplify do_promote Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 09/13] gfs2: split glock instantiation off from do_promote Bob Peterson
2021-10-12 21:48   ` Andreas Gruenbacher
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 10/13] gfs2: fix GL_SKIP node_scope problems Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 11/13] gfs2: Eliminate GIF_INVALID flag Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 12/13] gfs2: remove RDF_UPTODATE flag Bob Peterson
2021-10-11 19:40 ` [Cluster-devel] [GFS2 v3 PATCH 13/13] gfs2: set glock object after nq Bob Peterson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.