From 1fdd768d7f5516cee0fca56cd545685e2bdcae12 Mon Sep 17 00:00:00 2001 From: Ryan Moeller Date: Fri, 18 Feb 2022 16:09:03 -0500 Subject: [PATCH] libzfs: Fail making a dataset handle gracefully When a dataset is in the process of being received it gets marked as inconsistent and should not be used. We should check for this when opening a dataset handle in libzfs and return with an appropriate error set, rather than hitting an abort because of the incomplete data. zfs_open() passes errno to zfs_standard_error() after observing make_dataset_handle() fail, which ends up aborting if errno is 0. Set errno before returning where we know it has not been set already. Reviewed-by: Brian Behlendorf Signed-off-by: Ryan Moeller Closes #13077 --- lib/libzfs/libzfs_dataset.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 8251c434f8..f2219d1c3d 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -449,14 +449,19 @@ make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc) * We've managed to open the dataset and gather statistics. Determine * the high-level type. */ - if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) + if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) { zhp->zfs_head_type = ZFS_TYPE_VOLUME; - else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) + } else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) { zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM; - else if (zhp->zfs_dmustats.dds_type == DMU_OST_OTHER) + } else if (zhp->zfs_dmustats.dds_type == DMU_OST_OTHER) { + errno = EINVAL; return (-1); - else + } else if (zhp->zfs_dmustats.dds_inconsistent) { + errno = EBUSY; + return (-1); + } else { abort(); + } if (zhp->zfs_dmustats.dds_is_snapshot) zhp->zfs_type = ZFS_TYPE_SNAPSHOT;