summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/mount_zfs/mount_zfs.c57
-rw-r--r--cmd/zpool/zpool_main.c32
-rw-r--r--module/zfs/zfs_vfsops.c7
3 files changed, 75 insertions, 21 deletions
diff --git a/cmd/mount_zfs/mount_zfs.c b/cmd/mount_zfs/mount_zfs.c
index 6cb23d1c6..b168f719a 100644
--- a/cmd/mount_zfs/mount_zfs.c
+++ b/cmd/mount_zfs/mount_zfs.c
@@ -363,6 +363,7 @@ main(int argc, char **argv)
{
zfs_handle_t *zhp;
char prop[ZFS_MAXPROPLEN];
+ uint64_t zfs_version = 0;
char mntopts[MNT_LINE_MAX] = { '\0' };
char badopt[MNT_LINE_MAX] = { '\0' };
char mtabopt[MNT_LINE_MAX] = { '\0' };
@@ -515,6 +516,18 @@ main(int argc, char **argv)
(void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop,
sizeof (prop), NULL, NULL, 0, B_FALSE);
+ /*
+ * Fetch the max supported zfs version in case we get ENOTSUP
+ * back from the mount command, since we need the zfs handle
+ * to do so.
+ */
+ zfs_version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
+ if (zfs_version == 0) {
+ fprintf(stderr, gettext("unable to fetch "
+ "ZFS version for filesystem '%s'\n"), dataset);
+ return (MOUNT_SYSERR);
+ }
+
zfs_close(zhp);
libzfs_fini(g_zfs);
@@ -551,22 +564,36 @@ main(int argc, char **argv)
if (!fake) {
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
mntflags, mntopts);
- if (error) {
- switch (errno) {
- case ENOENT:
- (void) fprintf(stderr, gettext("mount point "
- "'%s' does not exist\n"), mntpoint);
- return (MOUNT_SYSERR);
- case EBUSY:
- (void) fprintf(stderr, gettext("filesystem "
- "'%s' is already mounted\n"), dataset);
- return (MOUNT_BUSY);
- default:
- (void) fprintf(stderr, gettext("filesystem "
- "'%s' can not be mounted due to error "
- "%d\n"), dataset, errno);
- return (MOUNT_USAGE);
+ }
+
+ if (error) {
+ switch (errno) {
+ case ENOENT:
+ (void) fprintf(stderr, gettext("mount point "
+ "'%s' does not exist\n"), mntpoint);
+ return (MOUNT_SYSERR);
+ case EBUSY:
+ (void) fprintf(stderr, gettext("filesystem "
+ "'%s' is already mounted\n"), dataset);
+ return (MOUNT_BUSY);
+ case ENOTSUP:
+ if (zfs_version > ZPL_VERSION) {
+ (void) fprintf(stderr,
+ gettext("filesystem '%s' (v%d) is not "
+ "supported by this implementation of "
+ "ZFS (max v%d).\n"), dataset,
+ (int) zfs_version, (int) ZPL_VERSION);
+ } else {
+ (void) fprintf(stderr,
+ gettext("filesystem '%s' mount "
+ "failed for unknown reason.\n"), dataset);
}
+ return (MOUNT_SYSERR);
+ default:
+ (void) fprintf(stderr, gettext("filesystem "
+ "'%s' can not be mounted due to error "
+ "%d\n"), dataset, errno);
+ return (MOUNT_USAGE);
}
}
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c
index 952645ea5..1086f9555 100644
--- a/cmd/zpool/zpool_main.c
+++ b/cmd/zpool/zpool_main.c
@@ -4602,11 +4602,32 @@ typedef struct upgrade_cbdata {
} upgrade_cbdata_t;
static int
+check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
+{
+ int zfs_version = (int) zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
+ int *count = (int *)unsupp_fs;
+
+ if (zfs_version > ZPL_VERSION) {
+ (void) printf(gettext("%s (v%d) is not supported by this "
+ "implementation of ZFS.\n"),
+ zfs_get_name(zhp), zfs_version);
+ (*count)++;
+ }
+
+ zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs);
+
+ zfs_close(zhp);
+
+ return (0);
+}
+
+static int
upgrade_version(zpool_handle_t *zhp, uint64_t version)
{
int ret;
nvlist_t *config;
uint64_t oldversion;
+ int unsupp_fs = 0;
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
@@ -4615,6 +4636,17 @@ upgrade_version(zpool_handle_t *zhp, uint64_t version)
assert(SPA_VERSION_IS_SUPPORTED(oldversion));
assert(oldversion < version);
+ ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs);
+ if (ret != 0)
+ return (ret);
+
+ if (unsupp_fs) {
+ (void) printf(gettext("Upgrade not performed due to %d "
+ "unsupported filesystems (max v%d).\n"),
+ unsupp_fs, (int) ZPL_VERSION);
+ return (1);
+ }
+
ret = zpool_upgrade(zhp, version);
if (ret != 0)
return (ret);
diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c
index a27ac694d..eea78417a 100644
--- a/module/zfs/zfs_vfsops.c
+++ b/module/zfs/zfs_vfsops.c
@@ -679,12 +679,7 @@ zfs_sb_create(const char *osname, zfs_sb_t **zsbp)
error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zsb->z_version);
if (error) {
goto out;
- } else if (zsb->z_version >
- zfs_zpl_version_map(spa_version(dmu_objset_spa(os)))) {
- (void) printk("Can't mount a version %lld file system "
- "on a version %lld pool\n. Pool must be upgraded to mount "
- "this file system.", (u_longlong_t)zsb->z_version,
- (u_longlong_t)spa_version(dmu_objset_spa(os)));
+ } else if (zsb->z_version > ZPL_VERSION) {
error = SET_ERROR(ENOTSUP);
goto out;
}