gfs2: Fix glock recursion in freeze_go_xmote_bh
authorBob Peterson <rpeterso@redhat.com>
Tue, 1 Jun 2021 14:41:40 +0000 (09:41 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 18 Sep 2021 11:40:25 +0000 (13:40 +0200)
[ Upstream commit 9d9b16054b7d357afde69a027514c695092b0d22 ]

We must not call gfs2_consist (which does a file system withdraw) from
the freeze glock's freeze_go_xmote_bh function because the withdraw
will try to use the freeze glock, thus causing a glock recursion error.

This patch changes freeze_go_xmote_bh to call function
gfs2_assert_withdraw_delayed instead of gfs2_consist to avoid recursion.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/gfs2/glops.c

index 3faa421..bf539ea 100644 (file)
@@ -623,16 +623,13 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh)
                j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
 
                error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
-               if (error)
-                       gfs2_consist(sdp);
-               if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT))
-                       gfs2_consist(sdp);
-
-               /*  Initialize some head of the log stuff  */
-               if (!gfs2_withdrawn(sdp)) {
-                       sdp->sd_log_sequence = head.lh_sequence + 1;
-                       gfs2_log_pointers_init(sdp, head.lh_blkno);
-               }
+               if (gfs2_assert_withdraw_delayed(sdp, !error))
+                       return error;
+               if (gfs2_assert_withdraw_delayed(sdp, head.lh_flags &
+                                                GFS2_LOG_HEAD_UNMOUNT))
+                       return -EIO;
+               sdp->sd_log_sequence = head.lh_sequence + 1;
+               gfs2_log_pointers_init(sdp, head.lh_blkno);
        }
        return 0;
 }