#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"
#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 */
return (B_FALSE);
}
+#if !defined(_KERNEL) && !defined(LIB_ZPOOL_BUILD)
static boolean_t
-zfs_mod_supported_feature(const char *name)
+zfs_mod_supported_impl(const char *scope, const char *name, const char *sysfs)
{
- /*
- * The zfs module spa_feature_table[], whether in-kernel or in
- * libzpool, always supports all the features. libzfs needs to
- * query the running module, via sysfs, to determine which
- * features are supported.
- */
-#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);
+ 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)
+{
+ /*
+ * The zfs module spa_feature_table[], whether in-kernel or in
+ * libzpool, always supports all the features. libzfs needs to
+ * query the running module, via sysfs, to determine which
+ * features are supported.
+ */
+#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD)
+ return (B_TRUE);
+#else
+ return (zfs_mod_supported(ZFS_SYSFS_POOL_FEATURES, name));
#endif
}
#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
}
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)