From b9007997682fac4a4272f2d59fc3df4875db2df0 Mon Sep 17 00:00:00 2001 From: youzhongyang Date: Mon, 24 Aug 2020 20:33:02 -0400 Subject: [PATCH] Fix inability to destroy snapshot used over NFS The cache of struct svc_export and struct svc_expkey by nfsd and rpc.mountd for the snapshot holds references to the mount point. We need to flush them out before unmounting, otherwise umount would fail with EBUSY. Reviewed-by: Don Brady Reviewed-by: Brian Behlendorf Signed-off-by: Youzhong Yang Closes #6000 Closes #10783 --- module/os/linux/zfs/zfs_ctldir.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/module/os/linux/zfs/zfs_ctldir.c b/module/os/linux/zfs/zfs_ctldir.c index c2748ce450..26e785a0d4 100644 --- a/module/os/linux/zfs/zfs_ctldir.c +++ b/module/os/linux/zfs/zfs_ctldir.c @@ -31,6 +31,7 @@ * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2018 George Melikov. All Rights Reserved. * Copyright (c) 2019 Datto, Inc. All rights reserved. + * Copyright (c) 2020 The MathWorks, Inc. All rights reserved. */ /* @@ -977,6 +978,22 @@ out: return (error); } +/* + * Flush everything out of the kernel's export table and such. + * This is needed as once the snapshot is used over NFS, its + * entries in svc_export and svc_expkey caches hold reference + * to the snapshot mount point. There is no known way of flushing + * only the entries related to the snapshot. + */ +static void +exportfs_flush(void) +{ + char *argv[] = { "/usr/sbin/exportfs", "-f", NULL }; + char *envp[] = { NULL }; + + (void) call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); +} + /* * Attempt to unmount a snapshot by making a call to user space. * There is no assurance that this can or will succeed, is just a @@ -999,6 +1016,8 @@ zfsctl_snapshot_unmount(char *snapname, int flags) } rw_exit(&zfs_snapshot_lock); + exportfs_flush(); + if (flags & MNT_FORCE) argv[4] = "-fn"; argv[5] = se->se_path;