]> granicus.if.org Git - zfs/commitdiff
Add zfs module feature and property compatibility
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 3 Jan 2019 23:19:37 +0000 (15:19 -0800)
committerGitHub <noreply@github.com>
Thu, 3 Jan 2019 23:19:37 +0000 (15:19 -0800)
This change is required to ease the transition when upgrading
from 0.7.x to 0.8.x.  It allows 0.8.x user space utilities to
remain compatible with 0.7.x and older kernel modules.

Reviewed-by: Don Brady <don.brady@delphix.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #8231

module/zcommon/zfeature_common.c

index 40ce01b947483249880deeb5e089aa3b65a24fc9..80f4a056288fccc6fa930c4723c9dbc6cd2cb343 100644 (file)
@@ -163,25 +163,49 @@ deps_contains_feature(const spa_feature_t *deps, const spa_feature_t feature)
 static boolean_t
 zfs_mod_supported_impl(const char *scope, const char *name, const char *sysfs)
 {
-       struct stat64 statbuf;
-       char *path;
        boolean_t supported = B_FALSE;
-       int len;
-
-       len = asprintf(&path, "%s/%s/%s", sysfs, scope, name);
+       char *path;
 
+       int len = asprintf(&path, "%s%s%s%s%s", sysfs,
+           scope == NULL ? "" : "/", scope == NULL ? "" : scope,
+           name == NULL ? "" : "/", name == NULL ? "" : name);
        if (len > 0) {
+               struct stat64 statbuf;
                supported = !!(stat64(path, &statbuf) == 0);
                free(path);
        }
+
        return (supported);
 }
 
 boolean_t
 zfs_mod_supported(const char *scope, const char *name)
 {
-       return (zfs_mod_supported_impl(scope, name, ZFS_SYSFS_DIR) ||
+       boolean_t supported;
+
+       /*
+        * Check both the primary and alternate sysfs locations to determine
+        * if the required functionality is supported.
+        */
+       supported = (zfs_mod_supported_impl(scope, name, ZFS_SYSFS_DIR) ||
            zfs_mod_supported_impl(scope, name, ZFS_SYSFS_ALT_DIR));
+
+       /*
+        * For backwards compatibility with kernel modules that predate
+        * supported feature/property checking.  Report the feature/property
+        * as supported if the kernel module is loaded but the requested
+        * scope directory does not exist.
+        */
+       if (supported == B_FALSE) {
+               struct stat64 statbuf;
+               if ((stat64(ZFS_SYSFS_DIR, &statbuf) == 0) &&
+                   !zfs_mod_supported_impl(scope, NULL, ZFS_SYSFS_DIR) &&
+                   !zfs_mod_supported_impl(scope, NULL, ZFS_SYSFS_ALT_DIR)) {
+                       supported = B_TRUE;
+               }
+       }
+
+       return (supported);
 }
 #endif