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)
committerBob Peterson <rpeterso@redhat.com>
Wed, 4 Aug 2021 19:59:02 +0000 (14:59 -0500)
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>
fs/gfs2/glops.c

index 54d3fbe..384565d 100644 (file)
@@ -610,16 +610,13 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl)
                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;
 }