gfs2: init system threads before freeze lock
authorBob Peterson <rpeterso@redhat.com>
Fri, 14 May 2021 12:42:33 +0000 (07:42 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Sep 2021 07:50:42 +0000 (09:50 +0200)
commitb4bbb77d886b4d3b5915593a9d97a0d3da82ff8d
tree82f68cdac97385f9eab579977195ff00b83666ad
parentee029e3aa129572437c2d45082d5555d0ba7eb42
gfs2: init system threads before freeze lock

[ Upstream commit a28dc123fa66ba7f3eca7cffc4b01d96bfd35c27 ]

Patch 96b1454f2e ("gfs2: move freeze glock outside the make_fs_rw and _ro
functions") changed the gfs2 mount sequence so that it holds the freeze
lock before calling gfs2_make_fs_rw. Before this patch, gfs2_make_fs_rw
called init_threads to initialize the quotad and logd threads. That is a
problem if the system needs to withdraw due to IO errors early in the
mount sequence, for example, while initializing the system statfs inode:

1. An IO error causes the statfs glock to not sync properly after
   recovery, and leaves items on the ail list.
2. The leftover items on the ail list causes its do_xmote call to fail,
   which makes it want to withdraw. But since the glock code cannot
   withdraw (because the withdraw sequence uses glocks) it relies upon
   the logd daemon to initiate the withdraw.
3. The withdraw can never be performed by the logd daemon because all
   this takes place before the logd daemon is started.

This patch moves function init_threads from super.c to ops_fstype.c
and it changes gfs2_fill_super to start its threads before holding the
freeze lock, and if there's an error, stop its threads after releasing
it. This allows the logd to run unblocked by the freeze lock. Thus,
the logd daemon can perform its withdraw sequence properly.

Fixes: 96b1454f2e8e ("gfs2: move freeze glock outside the make_fs_rw and _ro functions")
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/gfs2/ops_fstype.c
fs/gfs2/super.c