From f5ada6538dbc07f4589cbeff8f84228d1575bb03 Mon Sep 17 00:00:00 2001 From: Don Brady Date: Mon, 8 Mar 2021 09:46:45 -0700 Subject: [PATCH] Return finer grain errors in libzfs unmount_one Added errno mappings to unmount_one() in libzfs. Changed do_unmount() implementation to return errno errors directly like is done for do_mount() and others. Reviewed-by: Mark Maybee Reviewed-by: Brian Behlendorf Signed-off-by: Don Brady Closes #11681 --- lib/libzfs/libzfs_mount.c | 25 +++++++++++++++++++++++-- lib/libzfs/os/freebsd/libzfs_zmount.c | 5 +++-- lib/libzfs/os/linux/libzfs_mount_os.c | 6 ++++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 6d11016bc..2a543daac 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -22,7 +22,7 @@ /* * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2020 by Delphix. All rights reserved. + * Copyright (c) 2014, 2021 by Delphix. All rights reserved. * Copyright 2016 Igor Kozhukhov * Copyright 2017 RackTop Systems. * Copyright (c) 2018 Datto Inc. @@ -553,7 +553,28 @@ unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags) error = do_unmount(mountpoint, flags); if (error != 0) { - return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, + int libzfs_err; + + switch (error) { + case EBUSY: + libzfs_err = EZFS_BUSY; + break; + case EIO: + libzfs_err = EZFS_IO; + break; + case ENOENT: + libzfs_err = EZFS_NOENT; + break; + case ENOMEM: + libzfs_err = EZFS_NOMEM; + break; + case EPERM: + libzfs_err = EZFS_PERM; + break; + default: + libzfs_err = EZFS_UMOUNTFAILED; + } + return (zfs_error_fmt(hdl, libzfs_err, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), mountpoint)); } diff --git a/lib/libzfs/os/freebsd/libzfs_zmount.c b/lib/libzfs/os/freebsd/libzfs_zmount.c index 2207fffc5..e114b1e0c 100644 --- a/lib/libzfs/os/freebsd/libzfs_zmount.c +++ b/lib/libzfs/os/freebsd/libzfs_zmount.c @@ -128,8 +128,9 @@ do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, int flags) int do_unmount(const char *mntpt, int flags) { - - return (unmount(mntpt, flags)); + if (unmount(mntpt, flags) < 0) + return (errno); + return (0); } int diff --git a/lib/libzfs/os/linux/libzfs_mount_os.c b/lib/libzfs/os/linux/libzfs_mount_os.c index 92052f28f..21d640538 100644 --- a/lib/libzfs/os/linux/libzfs_mount_os.c +++ b/lib/libzfs/os/linux/libzfs_mount_os.c @@ -22,7 +22,7 @@ /* * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2020 by Delphix. All rights reserved. + * Copyright (c) 2014, 2021 by Delphix. All rights reserved. * Copyright 2016 Igor Kozhukhov * Copyright 2017 RackTop Systems. * Copyright (c) 2018 Datto Inc. @@ -377,7 +377,9 @@ int do_unmount(const char *mntpt, int flags) { if (!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { - return (umount2(mntpt, flags)); + int rv = umount2(mntpt, flags); + + return (rv < 0 ? errno : 0); } char force_opt[] = "-f";