Skip to content

Commit 20b3291

Browse files
AstralBobAndreas Gruenbacher
authored andcommitted
gfs2: Fix regression in freeze_go_sync
Patch 541656d ("gfs2: freeze should work on read-only mounts") changed the check for glock state in function freeze_go_sync() from "gl->gl_state == LM_ST_SHARED" to "gl->gl_req == LM_ST_EXCLUSIVE". That's wrong and it regressed gfs2's freeze/thaw mechanism because it caused only the freezing node (which requests the glock in EX) to queue freeze work. All nodes go through this go_sync code path during the freeze to drop their SHared hold on the freeze glock, allowing the freezing node to acquire it in EXclusive mode. But all the nodes must freeze access to the file system locally, so they ALL must queue freeze work. The freeze_work calls freeze_func, which makes a request to reacquire the freeze glock in SH, effectively blocking until the thaw from the EX holder. Once thawed, the freezing node drops its EX hold on the freeze glock, then the (blocked) freeze_func reacquires the freeze glock in SH again (on all nodes, including the freezer) so all nodes go back to a thawed state. This patch changes the check back to gl_state == LM_ST_SHARED like it was prior to 541656d. Fixes: 541656d ("gfs2: freeze should work on read-only mounts") Cc: stable@vger.kernel.org # v5.8+ Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
1 parent 09162bc commit 20b3291

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

fs/gfs2/glops.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,18 @@ static int freeze_go_sync(struct gfs2_glock *gl)
571571
int error = 0;
572572
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
573573

574-
if (gl->gl_req == LM_ST_EXCLUSIVE && !gfs2_withdrawn(sdp)) {
574+
/*
575+
* We need to check gl_state == LM_ST_SHARED here and not gl_req ==
576+
* LM_ST_EXCLUSIVE. That's because when any node does a freeze,
577+
* all the nodes should have the freeze glock in SH mode and they all
578+
* call do_xmote: One for EX and the others for UN. They ALL must
579+
* freeze locally, and they ALL must queue freeze work. The freeze_work
580+
* calls freeze_func, which tries to reacquire the freeze glock in SH,
581+
* effectively waiting for the thaw on the node who holds it in EX.
582+
* Once thawed, the work func acquires the freeze glock in
583+
* SH and everybody goes back to thawed.
584+
*/
585+
if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp)) {
575586
atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE);
576587
error = freeze_super(sdp->sd_vfs);
577588
if (error) {

0 commit comments

Comments
 (0)