From 426d07d64c006c361c4faa11e8b88cb557f68c7f Mon Sep 17 00:00:00 2001 From: Rich Ercolani <214141+rincebrain@users.noreply.github.com> Date: Mon, 13 Feb 2023 19:40:13 -0500 Subject: [PATCH] quick fix for lingering snapdir unmount problems Unfortunately, even after e79b6807, I still, much more rarely, tripped asserts when playing with many ctldir mounts at once. Since this appears to happen if we dispatched twice too fast, just ignore it. We don't actually need to do anything if someone already started doing it for us. Reviewed-by: Brian Behlendorf Signed-off-by: Rich Ercolani Closes #14462 --- module/os/linux/zfs/zfs_ctldir.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/module/os/linux/zfs/zfs_ctldir.c b/module/os/linux/zfs/zfs_ctldir.c index 93b2b18028a1..0a3069210a95 100644 --- a/module/os/linux/zfs/zfs_ctldir.c +++ b/module/os/linux/zfs/zfs_ctldir.c @@ -392,7 +392,20 @@ zfsctl_snapshot_unmount_delay_impl(zfs_snapentry_t *se, int delay) zfsctl_snapshot_hold(se); rw_enter(&se->se_taskqid_lock, RW_WRITER); - ASSERT3S(se->se_taskqid, ==, TASKQID_INVALID); + /* + * If this condition happens, we managed to: + * - dispatch once + * - want to dispatch _again_ before it returned + * + * So let's just return - if that task fails at unmounting, + * we'll eventually dispatch again, and if it succeeds, + * no problem. + */ + if (se->se_taskqid != TASKQID_INVALID) { + rw_exit(&se->se_taskqid_lock); + zfsctl_snapshot_rele(se); + return; + } se->se_taskqid = taskq_dispatch_delay(system_delay_taskq, snapentry_expire, se, TQ_SLEEP, ddi_get_lbolt() + delay * HZ); rw_exit(&se->se_taskqid_lock);