Add zfs module feature and property compatibility

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
This commit is contained in:
Brian Behlendorf 2019-01-03 15:19:37 -08:00 committed by GitHub
parent 5365b0747a
commit 0b8e4418b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 30 additions and 6 deletions

View 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