gfs2: fix a deadlock on withdraw-during-mount
authorBob Peterson <rpeterso@redhat.com>
Tue, 18 May 2021 13:14:31 +0000 (09:14 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 18 Jun 2021 08:00:04 +0000 (10:00 +0200)
commit7a557de07917600a12bcb9867acad771e4b29837
tree898c67803ea868d03254a76a05760e9f3aa204dd
parentc3e9ea16adc1ce378e7c1416dace0c93631e2fcc
gfs2: fix a deadlock on withdraw-during-mount

[ Upstream commit 865cc3e9cc0b1d4b81c10d53174bced76decf888 ]

Before this patch, gfs2 would deadlock because of the following
sequence during mount:

mount
   gfs2_fill_super
      gfs2_make_fs_rw <--- Detects IO error with glock
         kthread_stop(sdp->sd_quotad_process);
            <--- Blocked waiting for quotad to finish

logd
   Detects IO error and the need to withdraw
   calls gfs2_withdraw
      gfs2_make_fs_ro
         kthread_stop(sdp->sd_quotad_process);
            <--- Blocked waiting for quotad to finish

gfs2_quotad
   gfs2_statfs_sync
      gfs2_glock_wait <---- Blocked waiting for statfs glock to be granted

glock_work_func
   do_xmote <---Detects IO error, can't release glock: blocked on withdraw
      glops->go_inval
      glock_blocked_by_withdraw
         requeue glock work & exit <--- work requeued, blocked by withdraw

This patch makes a special exception for the statfs system inode glock,
which allows the statfs glock UNLOCK to proceed normally. That allows the
quotad daemon to exit during the withdraw, which allows the logd daemon
to exit during the withdraw, which allows the mount to exit.

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