diff --git a/include/sys/zfs_sysfs.h b/include/sys/zfs_sysfs.h index 7c4a0304f..925d7ad54 100644 --- a/include/sys/zfs_sysfs.h +++ b/include/sys/zfs_sysfs.h @@ -35,6 +35,7 @@ void zfs_sysfs_fini(void); #define zfs_sysfs_init() #define zfs_sysfs_fini() +boolean_t zfs_mod_supported(const char *, const char *); #endif #define ZFS_SYSFS_POOL_PROPERTIES "properties.pool" @@ -43,5 +44,7 @@ void zfs_sysfs_fini(void); #define ZFS_SYSFS_POOL_FEATURES "features.pool" #define ZFS_SYSFS_DIR "/sys/module/zfs" +/* Alternate location when ZFS is built as part of the kernel (rare) */ +#define ZFS_SYSFS_ALT_DIR "/sys/fs/zfs" #endif /* _SYS_ZFS_SYSFS_H */ diff --git a/module/zcommon/zfeature_common.c b/module/zcommon/zfeature_common.c index c86f98ac2..e630481cb 100644 --- a/module/zcommon/zfeature_common.c +++ b/module/zcommon/zfeature_common.c @@ -159,6 +159,32 @@ deps_contains_feature(const spa_feature_t *deps, const spa_feature_t feature) return (B_FALSE); } +#if !defined(_KERNEL) && !defined(LIB_ZPOOL_BUILD) +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); + + if (len > 0) { + 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) || + zfs_mod_supported_impl(scope, name, ZFS_SYSFS_ALT_DIR)); +} +#endif + static boolean_t zfs_mod_supported_feature(const char *name) { @@ -171,19 +197,7 @@ zfs_mod_supported_feature(const char *name) #if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) return (B_TRUE); #else - struct stat64 statbuf; - char *path; - boolean_t supported = B_FALSE; - int len; - - len = asprintf(&path, "%s/%s/%s", ZFS_SYSFS_DIR, - ZFS_SYSFS_POOL_FEATURES, name); - - if (len > 0) { - supported = !!(stat64(path, &statbuf) == 0); - free(path); - } - return (supported); + return (zfs_mod_supported(ZFS_SYSFS_POOL_FEATURES, name)); #endif } diff --git a/module/zcommon/zprop_common.c b/module/zcommon/zprop_common.c index 0ce2ee762..4d856cec1 100644 --- a/module/zcommon/zprop_common.c +++ b/module/zcommon/zprop_common.c @@ -81,20 +81,8 @@ zfs_mod_supported_prop(const char *name, zfs_type_t type) #if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) return (B_TRUE); #else - struct stat64 statbuf; - char *path; - boolean_t supported = B_FALSE; - int len; - - len = asprintf(&path, "%s/%s/%s", ZFS_SYSFS_DIR, - (type == ZFS_TYPE_POOL) ? ZFS_SYSFS_POOL_PROPERTIES : - ZFS_SYSFS_DATASET_PROPERTIES, name); - - if (len > 0) { - supported = !!(stat64(path, &statbuf) == 0); - free(path); - } - return (supported); + return (zfs_mod_supported(type == ZFS_TYPE_POOL ? + ZFS_SYSFS_POOL_PROPERTIES : ZFS_SYSFS_DATASET_PROPERTIES, name)); #endif } diff --git a/module/zfs/zfs_sysfs.c b/module/zfs/zfs_sysfs.c index 1eb7f9448..42822b2f2 100644 --- a/module/zfs/zfs_sysfs.c +++ b/module/zfs/zfs_sysfs.c @@ -572,11 +572,16 @@ zfs_sysfs_properties_init(zfs_mod_kobj_t *zfs_kobj, struct kobject *parent, void zfs_sysfs_init(void) { - struct kobject *parent = - &(((struct module *)(THIS_MODULE))->mkobj).kobj; + struct kobject *parent; +#if defined(CONFIG_ZFS) && !defined(CONFIG_ZFS_MODULE) + parent = kobject_create_and_add("zfs", fs_kobj); +#else + parent = &(((struct module *)(THIS_MODULE))->mkobj).kobj; +#endif int err; - ASSERT(parent != NULL); + if (parent == NULL) + return; err = zfs_kernel_features_init(&kernel_features_kobj, parent); if (err)