diff --git a/include/os/windows/spl/sys/mod_os.h b/include/os/windows/spl/sys/mod_os.h index 144d4ef3ff38..1f7ee5cb8068 100644 --- a/include/os/windows/spl/sys/mod_os.h +++ b/include/os/windows/spl/sys/mod_os.h @@ -107,6 +107,19 @@ typedef enum { ZT_ZMOD_RW } ztunable_perm; +/* + * STRING is a bit awkward, Linux kernel use it as + * "char *s = NULL", so it is allocated elsewhere. + * But we also like to be able to use it with static + * areas, like *version = "openzfs-2.1.8", so we + * internally add a flag member, so we can know what to + * free. + */ +typedef enum { + ZT_FLAG_ALLOCATED = 0, + ZT_FLAG_STATIC = (1<<0), +} ztunable_flag; + /* * ZFS_MODULE_CALL() and VIRTUAL do not define a type (like ULONG) in the * MACRO so, they are set to ZT_TYPE_NOTSET. The call ZT_GET_VALUE( ..., &type) @@ -126,6 +139,9 @@ typedef enum { ZT_TYPE_U64, // Future expansion } ztunable_type; +// Enhance this to dynamic one day? +#define ZFS_MODULE_STRMAX 64 + static inline uint64_t ZT_TYPE_REGISTRY(ztunable_type t) { switch(t) { @@ -182,6 +198,7 @@ typedef struct ztunable_s { const char *zt_desc; ztunable_perm zt_perm; ztunable_type zt_type; + ztunable_flag zt_flag; } ztunable_t; static inline void @@ -205,8 +222,11 @@ ZT_SET_VALUE(ztunable_t *zt, void **ptr, ULONG *len, ULONG *type) *(uint64_t *)zt->zt_ptr = *(uint64_t *)*ptr; return; case ZT_TYPE_STRING: - ASSERT3U(*len, >= , sizeof(char *)); - *(char *)zt->zt_ptr = *(char *)*ptr; + if (zt->zt_flag & ZT_FLAG_STATIC) { + strlcpy(zt->zt_ptr, *ptr, ZFS_MODULE_STRMAX); + return; + } + zt->zt_ptr = (void *)*ptr; return; case ZT_TYPE_U64: ASSERT3U(*len, >= , sizeof(uint64_t)); @@ -237,10 +257,14 @@ ZT_GET_VALUE(ztunable_t *zt, void **ptr, ULONG *len, ULONG *type) case ZT_TYPE_UINT: case ZT_TYPE_LONG: case ZT_TYPE_ULONG: - case ZT_TYPE_STRING: case ZT_TYPE_U64: *ptr = zt->zt_ptr; return; + case ZT_TYPE_STRING: + *ptr = zt->zt_ptr; + if (zt->zt_ptr != NULL) + *len = strlen(zt->zt_ptr); + return; case ZT_TYPE_NOTSET: /* not reached */ ASSERT3U(zt->zt_type, != , ZT_TYPE_NOTSET); @@ -256,10 +280,25 @@ ZT_GET_VALUE(ztunable_t *zt, void **ptr, ULONG *len, ULONG *type) .zt_prefix = #scope_prefix, \ .zt_desc = #desc, \ .zt_perm = __CONCAT(ZT_, perm), \ - .zt_type = ZT_TYPE_ ## type \ + .zt_type = ZT_TYPE_ ## type, \ + .zt_flag = ZT_FLAG_STATIC \ }; \ SET_ENTRY(zt, zt_ ## name_prefix ## name) +/* Used only internally in Windows port */ +#define ZFS_MODULE_RAW(scope_prefix, name, variable, type, perm, flag, desc) \ + static ztunable_t zt_ ## variable = { \ + .zt_ptr = &variable, \ + .zt_func = NULL, \ + .zt_name = #name, \ + .zt_prefix = #scope_prefix, \ + .zt_desc = #desc, \ + .zt_perm = __CONCAT(ZT_, perm), \ + .zt_type = ZT_TYPE_ ## type, \ + .zt_flag = flag \ + }; \ + SET_ENTRY(zt, zt_ ## variable) + #define ZFS_MODULE_PARAM_CALL_IMPL(scope_prefix, name_prefix, name, perm, args, desc) \ static ztunable_t zt_ ## name_prefix ## name = { \ @@ -269,7 +308,8 @@ ZT_GET_VALUE(ztunable_t *zt, void **ptr, ULONG *len, ULONG *type) .zt_prefix = #scope_prefix, \ .zt_desc = #desc, \ .zt_perm = __CONCAT(ZT_, perm), \ - .zt_type = ZT_TYPE_NOTSET \ + .zt_type = ZT_TYPE_NOTSET, \ + .zt_flag = ZT_FLAG_STATIC \ }; \ SET_ENTRY(zt, zt_ ## name_prefix ## name) diff --git a/include/os/windows/zfs/sys/kstat_windows.h b/include/os/windows/zfs/sys/kstat_windows.h deleted file mode 100644 index 2031e2179495..000000000000 --- a/include/os/windows/zfs/sys/kstat_windows.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2014, 2016 Jorgen Lundman - */ - -#ifndef KSTAT_WINDOWS_INCLUDED -#define KSTAT_WINDOWS_INCLUDED - -typedef struct windows_kstat { - kstat_named_t spa_version; - kstat_named_t zpl_version; - - kstat_named_t win32_active_vnodes; - kstat_named_t win32_debug; - kstat_named_t win32_reclaim_nodes; - kstat_named_t win32_ignore_negatives; - kstat_named_t win32_ignore_positives; - kstat_named_t win32_create_negatives; - kstat_named_t win32_skip_unlinked_drain; - kstat_named_t win32_use_system_sync; - - kstat_named_t arc_zfs_arc_max; - kstat_named_t arc_zfs_arc_min; - kstat_named_t arc_zfs_arc_meta_limit; - kstat_named_t arc_zfs_arc_meta_min; - kstat_named_t arc_zfs_arc_grow_retry; - kstat_named_t arc_zfs_arc_shrink_shift; - kstat_named_t arc_zfs_arc_p_min_shift; - kstat_named_t arc_zfs_arc_average_blocksize; - - kstat_named_t l2arc_write_max; - kstat_named_t l2arc_write_boost; - kstat_named_t l2arc_headroom; - kstat_named_t l2arc_headroom_boost; - kstat_named_t l2arc_feed_secs; - kstat_named_t l2arc_feed_min_ms; - - kstat_named_t zfs_vdev_max_active; - kstat_named_t zfs_vdev_sync_read_min_active; - kstat_named_t zfs_vdev_sync_read_max_active; - kstat_named_t zfs_vdev_sync_write_min_active; - kstat_named_t zfs_vdev_sync_write_max_active; - kstat_named_t zfs_vdev_async_read_min_active; - kstat_named_t zfs_vdev_async_read_max_active; - kstat_named_t zfs_vdev_async_write_min_active; - kstat_named_t zfs_vdev_async_write_max_active; - kstat_named_t zfs_vdev_scrub_min_active; - kstat_named_t zfs_vdev_scrub_max_active; - kstat_named_t zfs_vdev_async_write_active_min_dirty_percent; - kstat_named_t zfs_vdev_async_write_active_max_dirty_percent; - kstat_named_t zfs_vdev_aggregation_limit; - kstat_named_t zfs_vdev_read_gap_limit; - kstat_named_t zfs_vdev_write_gap_limit; - - kstat_named_t arc_lotsfree_percent; - kstat_named_t zfs_dirty_data_max; - kstat_named_t zfs_delay_max_ns; - kstat_named_t zfs_delay_min_dirty_percent; - kstat_named_t zfs_delay_scale; - kstat_named_t spa_asize_inflation; - kstat_named_t zfs_prefetch_disable; - kstat_named_t zfetch_max_streams; - kstat_named_t zfetch_min_sec_reap; - kstat_named_t zfetch_array_rd_sz; - kstat_named_t zfs_default_bs; - kstat_named_t zfs_default_ibs; - kstat_named_t metaslab_aliquot; - kstat_named_t spa_max_replication_override; - kstat_named_t spa_mode_global; - kstat_named_t zfs_flags; - kstat_named_t zfs_txg_timeout; - kstat_named_t zfs_vdev_cache_max; - kstat_named_t zfs_vdev_cache_size; - kstat_named_t zfs_vdev_cache_bshift; - kstat_named_t vdev_mirror_shift; - kstat_named_t zfs_scrub_limit; - kstat_named_t zfs_no_scrub_io; - kstat_named_t zfs_no_scrub_prefetch; - kstat_named_t fzap_default_block_shift; - kstat_named_t zfs_immediate_write_sz; -// kstat_named_t zfs_read_chunk_size; - kstat_named_t zfs_nocacheflush; - kstat_named_t zil_replay_disable; - kstat_named_t metaslab_df_alloc_threshold; - kstat_named_t metaslab_df_free_pct; - kstat_named_t zio_injection_enabled; - kstat_named_t zvol_immediate_write_sz; - - kstat_named_t l2arc_noprefetch; - kstat_named_t l2arc_feed_again; - kstat_named_t l2arc_norw; - - kstat_named_t zfs_recover; - - kstat_named_t zfs_free_bpobj_enabled; - - kstat_named_t zfs_send_corrupt_data; - kstat_named_t zfs_send_queue_length; - kstat_named_t zfs_recv_queue_length; - - kstat_named_t zvol_inhibit_dev; - kstat_named_t zfs_send_set_freerecords_bit; - - kstat_named_t zfs_write_implies_delete_child; - kstat_named_t zfs_send_holes_without_birth_time; - - kstat_named_t dbuf_cache_max_bytes; - - kstat_named_t zfs_vdev_queue_depth_pct; - kstat_named_t zio_dva_throttle_enabled; - - kstat_named_t zfs_lua_max_instrlimit; - kstat_named_t zfs_lua_max_memlimit; - - kstat_named_t zfs_trim_extent_bytes_max; - kstat_named_t zfs_trim_extent_bytes_min; - kstat_named_t zfs_trim_metaslab_skip; - kstat_named_t zfs_trim_txg_batch; - kstat_named_t zfs_trim_queue_limit; - - kstat_named_t win32_hw_hostid; - kstat_named_t zfs_send_unmodified_spill_blocks; - kstat_named_t zfs_special_class_metadata_reserve_pct; - - kstat_named_t zfs_disable_wincache; - kstat_named_t zfs_disable_removablemedia; - - kstat_named_t zfs_vdev_initialize_value; - kstat_named_t zfs_autoimport_disable; - kstat_named_t zfs_total_memory_limit; -} windows_kstat_t; - - -extern unsigned int zfs_vnop_ignore_negatives; -extern unsigned int zfs_vnop_ignore_positives; -extern unsigned int zfs_vnop_create_negatives; -extern unsigned int zfs_vnop_skip_unlinked_drain; -extern uint64_t zfs_vfs_sync_paranoia; -extern uint64_t vnop_num_vnodes; -extern uint64_t vnop_num_reclaims; -extern uint32_t spl_hostid; - -extern uint64_t zfs_arc_max; -extern uint64_t zfs_arc_min; -extern uint64_t zfs_arc_meta_limit; -extern uint64_t zfs_arc_meta_min; -extern int zfs_arc_grow_retry; -extern int zfs_arc_shrink_shift; -extern int zfs_arc_p_min_shift; -extern int zfs_arc_average_blocksize; - -extern uint64_t l2arc_write_max; -extern uint64_t l2arc_write_boost; -extern uint64_t l2arc_headroom; -extern uint64_t l2arc_headroom_boost; -extern uint64_t l2arc_feed_secs; -extern uint64_t l2arc_feed_min_ms; - -extern uint32_t zfs_vdev_max_active; -extern uint32_t zfs_vdev_sync_read_min_active; -extern uint32_t zfs_vdev_sync_read_max_active; -extern uint32_t zfs_vdev_sync_write_min_active; -extern uint32_t zfs_vdev_sync_write_max_active; -extern uint32_t zfs_vdev_async_read_min_active; -extern uint32_t zfs_vdev_async_read_max_active; -extern uint32_t zfs_vdev_async_write_min_active; -extern uint32_t zfs_vdev_async_write_max_active; -extern uint32_t zfs_vdev_scrub_min_active; -extern uint32_t zfs_vdev_scrub_max_active; -extern int zfs_vdev_async_write_active_min_dirty_percent; -extern int zfs_vdev_async_write_active_max_dirty_percent; -extern int zfs_vdev_aggregation_limit; -extern int zfs_vdev_read_gap_limit; -extern int zfs_vdev_write_gap_limit; - -extern int arc_lotsfree_percent; -extern hrtime_t zfs_delay_max_ns; -extern int spa_asize_inflation; -extern unsigned int zfetch_max_streams; -extern unsigned int zfetch_min_sec_reap; -extern int zfs_default_bs; -extern int zfs_default_ibs; -extern uint64_t metaslab_aliquot; -extern int zfs_vdev_cache_max; -extern int spa_max_replication_override; -extern int zfs_no_scrub_io; -extern int zfs_no_scrub_prefetch; -extern ssize_t zfs_immediate_write_sz; -extern offset_t zfs_read_chunk_size; -extern uint64_t metaslab_df_alloc_threshold; -extern int metaslab_df_free_pct; -extern ssize_t zvol_immediate_write_sz; - -extern boolean_t l2arc_noprefetch; -extern boolean_t l2arc_feed_again; -extern boolean_t l2arc_norw; - -extern int zfs_top_maxinflight; -extern int zfs_resilver_delay; -extern int zfs_scrub_delay; -extern int zfs_scan_idle; - -extern int64_t zfs_free_bpobj_enabled; - -extern int zfs_send_corrupt_data; -extern int zfs_send_queue_length; -extern int zfs_recv_queue_length; - -extern uint64_t zvol_inhibit_dev; -extern uint64_t zfs_send_set_freerecords_bit; - -extern uint64_t zfs_write_implies_delete_child; -extern uint64_t send_holes_without_birth_time; -extern uint64_t zfs_send_holes_without_birth_time; - -extern uint64_t dbuf_cache_max_bytes; - -extern int zfs_vdev_queue_depth_pct; -extern boolean_t zio_dva_throttle_enabled; - -extern uint64_t zfs_lua_max_instrlimit; -extern uint64_t zfs_lua_max_memlimit; - - -extern uint64_t zfs_trim_extent_bytes_max; -extern uint64_t zfs_trim_extent_bytes_min; -extern unsigned int zfs_trim_metaslab_skip; -extern uint64_t zfs_trim_txg_batch; -extern uint64_t zfs_trim_queue_limit; - -extern uint64_t zfs_send_unmodified_spill_blocks; -extern uint64_t zfs_special_class_metadata_reserve_pct; - -extern uint64_t zfs_disable_wincache; -extern uint64_t zfs_disable_removablemedia; - -extern uint64_t zfs_initialize_value; -extern int zfs_autoimport_disable; - -int kstat_windows_init(void *); -void kstat_windows_fini(void); - -int arc_kstat_update(kstat_t *ksp, int rw); -int arc_kstat_update_windows(kstat_t *ksp, int rw); -int spl_kstat_registry(void *pRegistryPath, kstat_t *ksp); - -#endif diff --git a/module/os/windows/driver.c b/module/os/windows/driver.c index b3cfd499dfe3..c46ee2294d57 100644 --- a/module/os/windows/driver.c +++ b/module/os/windows/driver.c @@ -23,7 +23,6 @@ #include -#include #include #include @@ -85,7 +84,7 @@ OpenZFS_Fini(PDRIVER_OBJECT DriverObject) system_taskq_fini(); sysctl_os_fini(); - kstat_windows_fini(); + spl_stop(); finiDbgCircularBuffer(); @@ -127,8 +126,6 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, spl_start(pRegistryPath); - kstat_windows_init(pRegistryPath); - sysctl_os_init(pRegistryPath); system_taskq_init(); @@ -171,272 +168,3 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, return (STATUS_SUCCESS); } -extern int random_get_bytes(void *ptr, unsigned long len); - -void -spl_create_hostid(HANDLE h, PUNICODE_STRING pRegistryPath) -{ - NTSTATUS Status; - - UNICODE_STRING AttachKey; - RtlInitUnicodeString(&AttachKey, L"hostid"); - - random_get_bytes(&spl_hostid, sizeof (spl_hostid)); - - Status = ZwSetValueKey( - h, - &AttachKey, - 0, - REG_DWORD, - &spl_hostid, - sizeof (spl_hostid)); - - if (!NT_SUCCESS(Status)) { - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: Unable to create Registry %wZ/hostid: 0x%x." - " hostid unset.\n", __func__, pRegistryPath, Status)); - spl_hostid = 0; - } - - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "SPL: created hostid 0x%04x\n", spl_hostid)); -} - -// Whenever we start up, write the version string to registry. - -void -spl_update_version(HANDLE h, PUNICODE_STRING pRegistryPath) -{ - NTSTATUS Status; - - UNICODE_STRING AttachKey; - UNICODE_STRING ValueKey; - // FIX me - RtlInitUnicodeString(&AttachKey, L"version"); - RtlInitUnicodeString(&ValueKey, L"fixme"); - // RtlInitUnicodeString(&ValueKey, - // L"fixme"ZFS_META_VERSION "-" ZFS_META_RELEASE); - - Status = ZwSetValueKey( - h, - &AttachKey, - 0, - REG_SZ, - ValueKey.Buffer, - ValueKey.Length); - - if (!NT_SUCCESS(Status)) { - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: Unable to create Registry %wZ/version: 0x%x." - " hostid unset.\n", __func__, pRegistryPath, Status)); - } -} - -int -spl_check_assign_types(kstat_named_t *kold, - PKEY_VALUE_FULL_INFORMATION regBuffer) -{ - - switch (kold->data_type) { - - case KSTAT_DATA_UINT64: - case KSTAT_DATA_INT64: - { - if (regBuffer->Type != REG_QWORD || - regBuffer->DataLength != sizeof (uint64_t)) { - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: registry '%s' matched in kstat. " - "Type needs to be REG_QWORD. (8 bytes)\n", __func__, - kold->name)); - return (0); - } - uint64_t newvalue = - *(uint64_t *)((uint8_t *)regBuffer + regBuffer->DataOffset); - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: kstat '%s': 0x%llx -> 0x%llx\n", __func__, - kold->name, - kold->value.ui64, - newvalue)); - kold->value.ui64 = newvalue; - return (1); - } - - case KSTAT_DATA_UINT32: - case KSTAT_DATA_INT32: - { - if (regBuffer->Type != REG_DWORD || - regBuffer->DataLength != sizeof (uint32_t)) { - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: registry '%s' matched in kstat. " - "Type needs to be REG_DWORD. (4 bytes)\n", __func__, - kold->name)); - return (0); - } - uint32_t newvalue = - *(uint32_t *)((uint8_t *)regBuffer + regBuffer->DataOffset); - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: kstat '%s': 0x%lx -> 0x%lx\n", __func__, - kold->name, - kold->value.ui32, - newvalue)); - kold->value.ui32 = newvalue; - return (1); - } - default: - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: registry '%s' matched in kstat of unsupported type." - "Only INT32 and INT64 types supported.\n", __func__, - kold->name)); - } - return (0); -} - -extern wchar_t zfs_vdev_protection_filter[64]; -int -spl_kstat_registry(void *arg, kstat_t *ksp) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE h; - NTSTATUS Status; - PUNICODE_STRING pRegistryPath = arg; - - InitializeObjectAttributes(&ObjectAttributes, - pRegistryPath, - OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = ZwOpenKey(&h, // KeyHandle - KEY_ALL_ACCESS, // DesiredAccess - &ObjectAttributes); // ObjectAttributes - - if (!NT_SUCCESS(Status)) { - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: Unable to open Registry %wZ: 0x%x." - "Going with defaults.\n", __func__, pRegistryPath, Status)); - return (0); - } - - // Iterate all Registry entries. - NTSTATUS status = 0; - ULONG index = 0; - ULONG length; - PKEY_VALUE_FULL_INFORMATION regBuffer; - char keyname[KSTAT_STRLEN + 1]; - int changed = 0; - - for (index = 0; status != STATUS_NO_MORE_ENTRIES; index++) { - // Get the buffer size necessary - status = ZwEnumerateValueKey(h, index, KeyValueFullInformation, - NULL, 0, &length); - - if ((status != STATUS_BUFFER_TOO_SMALL) && - (status != STATUS_BUFFER_OVERFLOW)) - break; // Something is wrong - or we finished - - // Allocate space to hold - regBuffer = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePoolWithTag( - NonPagedPoolNx, length, 'zfsr'); - - if (regBuffer == NULL) - continue; - - status = ZwEnumerateValueKey(h, index, KeyValueFullInformation, - regBuffer, length, &length); - if (!NT_SUCCESS(status)) { - ExFreePool(regBuffer); - continue; - } - - // Convert name to straight ascii so we compare with kstat - ULONG outlen; - status = RtlUnicodeToUTF8N(keyname, KSTAT_STRLEN, &outlen, - regBuffer->Name, regBuffer->NameLength); - - // Conversion failed? move along.. - if (status != STATUS_SUCCESS && - status != STATUS_SOME_NOT_MAPPED) { - ExFreePool(regBuffer); - continue; - } - - // Output string is only null terminated if input is, do so now. - keyname[outlen] = 0; - - // Support registry values that are not tunable through kstat. - // Those bypass the kstat name matching loop - // and get directly set in the corresponding code variable. - // - if (strcasecmp("zfs_vdev_protection_filter", keyname) == 0) { - if (regBuffer->Type != REG_SZ || - regBuffer->DataLength > - (sizeof (zfs_vdev_protection_filter) - - sizeof (wchar_t))) { - // will be NULL terminated - KdPrintEx((DPFLTR_IHVDRIVER_ID, - DPFLTR_ERROR_LEVEL, - "%s: registry '%s'. " - "Type needs to be REG_SZ (63 wchar max)\n", - __func__, - keyname)); - ExFreePool(regBuffer); - continue; - } - char *newvalue = (char *)((uint8_t *)regBuffer + - regBuffer->DataOffset); - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "%s: registry '%s': %S\n", __func__, - keyname, newvalue)); - - bzero(zfs_vdev_protection_filter, - sizeof (zfs_vdev_protection_filter)); - bcopy(newvalue, zfs_vdev_protection_filter, - min(sizeof (zfs_vdev_protection_filter), - regBuffer->DataLength)); - } else { - // Now iterate kstats and match name with 'keyname'. - kstat_named_t *kold; - kold = ksp->ks_data; - for (unsigned int i = 0; i < ksp->ks_ndata; - i++, kold++) { - - // Find name? - if (kold != NULL && - !strcasecmp(kold->name, keyname)) { - - // Check types match and are supported - if (!spl_check_assign_types(kold, - regBuffer)) - break; - - // Special case 'hostid' is - // automatically generated if - // not set, so if we read it - // in, signal to not set it. - // KSTAT_UPDATE is called after - // this function completes. - if (spl_hostid == 0 && - strcasecmp("hostid", keyname) == 0) - spl_hostid = 1; // Non-zero - - changed++; - break; - } - } - } - - ExFreePool(regBuffer); - } // for() all keys - - // Now check that hostid was read it, if it wasn't, - // make up a random one. - if (spl_hostid == 0) { - spl_create_hostid(h, pRegistryPath); - } - - // Make sure version is updated - spl_update_version(h, pRegistryPath); - - ZwClose(h); - return (changed); -} diff --git a/module/os/windows/spl/spl-windows.c b/module/os/windows/spl/spl-windows.c index 8fde2988f3af..430110821922 100644 --- a/module/os/windows/spl/spl-windows.c +++ b/module/os/windows/spl/spl-windows.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #define DEBUG 1 // for backtrace debugging info @@ -61,9 +63,26 @@ extern uint64_t segkmem_total_mem_allocated; #define MAXHOSTNAMELEN 64 extern char hostname[MAXHOSTNAMELEN]; -uint32_t spl_hostid = 0; #define ZFS_MIN_MEMORY_LIMIT 2ULL * 1024ULL * 1024ULL * 1024ULL +/* + * Windows internal tunables, we use the RAW method when + * we want more control over "name" and "variable" used. + * First argument is the "subfolder" wanted in the Registry, + * and most will most likely be in "root". + */ +uint32_t spl_hostid = 0; +ZFS_MODULE_RAW(, hostid, spl_hostid, + UINT, ZMOD_RW, 0, "The system hostid."); + +extern uchar_t zfs_vdev_protection_filter[ZFS_MODULE_STRMAX]; +ZFS_MODULE_RAW(, zfs_vdev_protection_filter, zfs_vdev_protection_filter, + STRING, ZMOD_RW, ZT_FLAG_STATIC, "vdev_protection_filter"); + +static uchar_t zfs_version[] = ZFS_META_GITREV; +ZFS_MODULE_RAW(, zfs_version, zfs_version, + STRING, ZMOD_RD, ZT_FLAG_STATIC, "OpenZFS Windows Driver Version"); + #if defined(__clang__) /* * Try to figure out why we fail linking with these two missing @@ -511,6 +530,10 @@ spl_start(PUNICODE_STRING RegistryPath) vm_page_free_count = (unsigned int)(physmem / 2ULL); vm_page_speculative_count = vm_page_free_count; + // Set hostid here, it will be overwritten if it is in registry + if (spl_hostid == 0) + random_get_bytes(&spl_hostid, sizeof(spl_hostid)); + /* * For some reason, (CTLFLAG_KERN is not set) looking up hostname * returns 1. So we set it to uuid just to give it *something*. diff --git a/module/os/windows/zfs/CMakeLists.txt b/module/os/windows/zfs/CMakeLists.txt index 6ef2d32f22c0..fe2b4ce893bd 100644 --- a/module/os/windows/zfs/CMakeLists.txt +++ b/module/os/windows/zfs/CMakeLists.txt @@ -20,7 +20,6 @@ zfs_dir.c zfs_file_os.c zfs_fuid_os.c zfs_ioctl_os.c -zfs_kstat_windows.c zfs_vfsops.c zfs_vnops_os.c zfs_vnops_windows.c diff --git a/module/os/windows/zfs/arc_os.c b/module/os/windows/zfs/arc_os.c index da27b7628af2..b7a69dc3a76d 100644 --- a/module/os/windows/zfs/arc_os.c +++ b/module/os/windows/zfs/arc_os.c @@ -55,7 +55,6 @@ #include #include #include -#include extern arc_stats_t arc_stats; diff --git a/module/os/windows/zfs/sysctl_os.c b/module/os/windows/zfs/sysctl_os.c index dd433c4acb9e..80e243f9f975 100644 --- a/module/os/windows/zfs/sysctl_os.c +++ b/module/os/windows/zfs/sysctl_os.c @@ -43,6 +43,8 @@ static UNICODE_STRING sysctl_os_RegistryPath; void sysctl_os_init(PUNICODE_STRING RegistryPath); +extern uint32_t spl_hostid; + HANDLE sysctl_os_open_registry(PUNICODE_STRING pRegistryPath) { @@ -132,7 +134,7 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) // Open registry regfd = sysctl_os_open_registry(&entry); if (regfd == 0) - return; + return; // create key entry name Status = RtlUTF8ToUnicodeN(entry.Buffer, LINUX_MAX_MODULE_PARAM_LEN, @@ -142,7 +144,7 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) // If we failed to convert it, just skip it. if (Status != STATUS_SUCCESS && Status != STATUS_SOME_NOT_MAPPED) - return; + return; // Do we have key? Status = ZwQueryValueKey( @@ -157,7 +159,7 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) void *val = NULL; ULONG len = 0; ULONG type = 0; // Registry type - DECLARE_UNICODE_STRING_SIZE(str, 20); // Max string, macro me? + UNICODE_STRING str = { 0 }; ZT_GET_VALUE(zt, &val, &len, &type); @@ -165,7 +167,22 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) ASSERT3U(len, > , 0); if (type == ZT_TYPE_STRING) { - // We need to ascii -> utf8 any string. + + /* + * STRINGS: from zfs/ZT struct to write out to Registry + * Check how much space convert will need, allocate buffer + * Convert ascii -> utf8 the string + * Assign to Registry update. + */ + Status = RtlUTF8ToUnicodeN(NULL, 0, + &length, val, len); + if (!NT_SUCCESS(Status)) + goto skip; + str.Length = str.MaximumLength = length; + str.Buffer = ExAllocatePoolWithTag(PagedPool, length, 'ZTST'); + if (str.Buffer == NULL) + goto skip; + Status = RtlUTF8ToUnicodeN(str.Buffer, str.MaximumLength, &length, val, len); str.Length = length; @@ -173,9 +190,8 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) len = length; val = str.Buffer; - if (Status != STATUS_SUCCESS && - Status != STATUS_SOME_NOT_MAPPED) - return; + if (!NT_SUCCESS(Status)) + goto skip; } // No entry, add it @@ -187,21 +203,18 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) val, len); -#if 0 - if (NT_SUCCESS(Status)) - KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, - "tunable: created Registry entry\n", - zt->zt_prefix, zt->zt_name, - zt->zt_type, - zt->zt_ptr)); -#endif +skip: + if ((type == ZT_TYPE_STRING) && + str.Buffer != NULL) + ExFreePool(str.Buffer); + } else { // Has entry in Registry, read it, and update tunable // Biggest value we store at the moment is uint64_t uchar_t *buffer; buffer = ExAllocatePoolWithTag(PagedPool, length, '!SFZ'); if (buffer == NULL) - return; + goto failed; Status = ZwQueryValueKey( regfd, @@ -212,7 +225,7 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) &length); if (NT_SUCCESS(Status)) { - char strval[20]; // macro? + char *strval = NULL; KEY_VALUE_FULL_INFORMATION *kv = (KEY_VALUE_FULL_INFORMATION *)buffer; void *val = NULL; ULONG len = 0; @@ -220,7 +233,8 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) // _CALL style has to 'type', so look it up first. if (zt->zt_perm == ZT_ZMOD_RW) { - ZT_GET_VALUE(zt, &val, &len, &type); + char **maybestr = NULL; + ZT_GET_VALUE(zt, &maybestr, &len, &type); // Set up buffers to SET value. val = &buffer[kv->DataOffset]; @@ -228,32 +242,56 @@ sysctl_os_process(PUNICODE_STRING pRegistryPath, ztunable_t *zt) // If string, make ascii if (type == ZT_TYPE_STRING) { - - Status = RtlUnicodeToUTF8N(strval, sizeof (strval), &length, + /* + * STRINGS: + * + * Static? Convert into buffer assuming static MAX. + * Dynamic? + * First if it has a value and ALLOCATED, then free(). + * Check string kength needed, allocate + * Then convert ascii -> utf8 the string + */ + /* Already set? free it */ + if (!(zt->zt_flag & ZT_FLAG_STATIC)) { + + if (maybestr != NULL && *maybestr != NULL) + ExFreePool(*maybestr); + + *maybestr = NULL; + } + /* How much space needed? */ + Status = RtlUnicodeToUTF8N(NULL, 0, &length, val, len); + if (!NT_SUCCESS(Status)) + goto failed; - if (Status != STATUS_SUCCESS && - Status != STATUS_SOME_NOT_MAPPED) - return; + /* Get space */ + strval = ExAllocatePoolWithTag(PagedPool, length, 'ZTST'); + if (strval == NULL) + goto failed; + + /* Convert to ascii */ + Status = RtlUnicodeToUTF8N(strval, length, &length, + val, len); + if (!NT_SUCCESS(Status)) + goto failed; strval[length] = 0; val = strval; + } ZT_SET_VALUE(zt, &val, &len, &type); - } // RD vs RW - } - - ExFreePoolWithTag(buffer, '!SFZ'); - - if (Status == STATUS_BUFFER_OVERFLOW || - Status == STATUS_BUFFER_TOO_SMALL) { - dprintf( - "tunable: buffer too small %d < %d\n", - sizeof(buffer), length); + if ((zt->zt_flag & ZT_FLAG_STATIC) && strval != NULL) { + ExFreePoolWithTag(strval, '!SFZ'); + } + } // RD vs RW } +failed: + if (buffer != NULL) + ExFreePoolWithTag(buffer, '!SFZ'); } // Close registry @@ -669,3 +707,4 @@ param_set_multihost_interval(ZFS_MODULE_PARAM_ARGS) return (0); } + diff --git a/module/os/windows/zfs/vdev_disk.c b/module/os/windows/zfs/vdev_disk.c index 1123f883eb89..6c2f831b1641 100644 --- a/module/os/windows/zfs/vdev_disk.c +++ b/module/os/windows/zfs/vdev_disk.c @@ -42,7 +42,7 @@ */ -wchar_t zfs_vdev_protection_filter[64] = { L"\0" }; +wchar_t zfs_vdev_protection_filter[ZFS_MODULE_STRMAX] = { L"\0" }; static void vdev_disk_close(vdev_t *); diff --git a/module/os/windows/zfs/zfs_ioctl_os.c b/module/os/windows/zfs/zfs_ioctl_os.c index 08b90b356a62..296ee2258003 100644 --- a/module/os/windows/zfs/zfs_ioctl_os.c +++ b/module/os/windows/zfs/zfs_ioctl_os.c @@ -48,7 +48,6 @@ #include #include #include -#include #include diff --git a/module/os/windows/zfs/zfs_kstat_windows.c b/module/os/windows/zfs/zfs_kstat_windows.c deleted file mode 100644 index da0e9c16a848..000000000000 --- a/module/os/windows/zfs/zfs_kstat_windows.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2017 Jorgen Lundman - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _KERNEL -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -/* - * In Solaris the tunable are set via /etc/system. Until we have a load - * time configuration, we add them to writable kstat tunables. - * - * - */ - -windows_kstat_t windows_kstat = { - { "spa_version", KSTAT_DATA_UINT64 }, - { "zpl_version", KSTAT_DATA_UINT64 }, - - { "active_vnodes", KSTAT_DATA_UINT64 }, - { "vnop_debug", KSTAT_DATA_UINT64 }, - { "reclaim_nodes", KSTAT_DATA_UINT64 }, - { "ignore_negatives", KSTAT_DATA_UINT64 }, - { "ignore_positives", KSTAT_DATA_UINT64 }, - { "create_negatives", KSTAT_DATA_UINT64 }, - { "skip_unlinked_drain", KSTAT_DATA_UINT64 }, - { "use_system_sync", KSTAT_DATA_UINT64 }, - - { "zfs_arc_max", KSTAT_DATA_UINT64 }, - { "zfs_arc_min", KSTAT_DATA_UINT64 }, - { "zfs_arc_meta_limit", KSTAT_DATA_UINT64 }, - { "zfs_arc_meta_min", KSTAT_DATA_UINT64 }, - { "zfs_arc_grow_retry", KSTAT_DATA_UINT64 }, - { "zfs_arc_shrink_shift", KSTAT_DATA_UINT64 }, - { "zfs_arc_p_min_shift", KSTAT_DATA_UINT64 }, - { "zfs_arc_average_blocksize", KSTAT_DATA_UINT64 }, - - { "l2arc_write_max", KSTAT_DATA_UINT64 }, - { "l2arc_write_boost", KSTAT_DATA_UINT64 }, - { "l2arc_headroom", KSTAT_DATA_UINT64 }, - { "l2arc_headroom_boost", KSTAT_DATA_UINT64 }, - { "l2arc_feed_secs", KSTAT_DATA_UINT64 }, - { "l2arc_feed_min_ms", KSTAT_DATA_UINT64 }, - - { "max_active", KSTAT_DATA_UINT64 }, - { "sync_read_min_active", KSTAT_DATA_UINT64 }, - { "sync_read_max_active", KSTAT_DATA_UINT64 }, - { "sync_write_min_active", KSTAT_DATA_UINT64 }, - { "sync_write_max_active", KSTAT_DATA_UINT64 }, - { "async_read_min_active", KSTAT_DATA_UINT64 }, - { "async_read_max_active", KSTAT_DATA_UINT64 }, - { "async_write_min_active", KSTAT_DATA_UINT64 }, - { "async_write_max_active", KSTAT_DATA_UINT64 }, - { "scrub_min_active", KSTAT_DATA_UINT64 }, - { "scrub_max_active", KSTAT_DATA_UINT64 }, - { "async_write_min_dirty_pct", KSTAT_DATA_INT64 }, - { "async_write_max_dirty_pct", KSTAT_DATA_INT64 }, - { "aggregation_limit", KSTAT_DATA_INT64 }, - { "read_gap_limit", KSTAT_DATA_INT64 }, - { "write_gap_limit", KSTAT_DATA_INT64 }, - - {"arc_lotsfree_percent", KSTAT_DATA_INT64 }, - {"zfs_dirty_data_max", KSTAT_DATA_INT64 }, - {"zfs_delay_max_ns", KSTAT_DATA_INT64 }, - {"zfs_delay_min_dirty_percent", KSTAT_DATA_INT64 }, - {"zfs_delay_scale", KSTAT_DATA_INT64 }, - {"spa_asize_inflation", KSTAT_DATA_INT64 }, - {"zfs_prefetch_disable", KSTAT_DATA_INT64 }, - {"zfetch_max_streams", KSTAT_DATA_INT64 }, - {"zfetch_min_sec_reap", KSTAT_DATA_INT64 }, - {"zfetch_array_rd_sz", KSTAT_DATA_INT64 }, - {"zfs_default_bs", KSTAT_DATA_INT64 }, - {"zfs_default_ibs", KSTAT_DATA_INT64 }, - {"metaslab_aliquot", KSTAT_DATA_INT64 }, - {"spa_max_replication_override", KSTAT_DATA_INT64 }, - {"spa_mode_global", KSTAT_DATA_INT64 }, - {"zfs_flags", KSTAT_DATA_INT64 }, - {"zfs_txg_timeout", KSTAT_DATA_INT64 }, - {"zfs_vdev_cache_max", KSTAT_DATA_INT64 }, - {"zfs_vdev_cache_size", KSTAT_DATA_INT64 }, - {"zfs_vdev_cache_bshift", KSTAT_DATA_INT64 }, - {"vdev_mirror_shift", KSTAT_DATA_INT64 }, - {"zfs_scrub_limit", KSTAT_DATA_INT64 }, - {"zfs_no_scrub_io", KSTAT_DATA_INT64 }, - {"zfs_no_scrub_prefetch", KSTAT_DATA_INT64 }, - {"fzap_default_block_shift", KSTAT_DATA_INT64 }, - {"zfs_immediate_write_sz", KSTAT_DATA_INT64 }, -// {"zfs_read_chunk_size", KSTAT_DATA_INT64 }, - {"zfs_nocacheflush", KSTAT_DATA_INT64 }, - {"zil_replay_disable", KSTAT_DATA_INT64 }, - {"metaslab_df_alloc_threshold", KSTAT_DATA_INT64 }, - {"metaslab_df_free_pct", KSTAT_DATA_INT64 }, - {"zio_injection_enabled", KSTAT_DATA_INT64 }, - {"zvol_immediate_write_sz", KSTAT_DATA_INT64 }, - - { "l2arc_noprefetch", KSTAT_DATA_INT64 }, - { "l2arc_feed_again", KSTAT_DATA_INT64 }, - { "l2arc_norw", KSTAT_DATA_INT64 }, - - {"zfs_recover", KSTAT_DATA_INT64 }, - - {"zfs_free_bpobj_enabled", KSTAT_DATA_INT64 }, - - {"zfs_send_corrupt_data", KSTAT_DATA_UINT64 }, - {"zfs_send_queue_length", KSTAT_DATA_UINT64 }, - {"zfs_recv_queue_length", KSTAT_DATA_UINT64 }, - - {"zvol_inhibit_dev", KSTAT_DATA_UINT64 }, - {"zfs_send_set_freerecords_bit", KSTAT_DATA_UINT64 }, - - {"zfs_write_implies_delete_child", KSTAT_DATA_UINT64 }, - {"zfs_send_holes_without_brth_tme", KSTAT_DATA_UINT64 }, - - {"dbuf_cache_max_bytes", KSTAT_DATA_UINT64 }, - - {"zfs_vdev_queue_depth_pct", KSTAT_DATA_UINT64 }, - {"zio_dva_throttle_enabled", KSTAT_DATA_UINT64 }, - - {"zfs_lua_max_instrlimit", KSTAT_DATA_UINT64 }, - {"zfs_lua_max_memlimit", KSTAT_DATA_UINT64 }, - - {"zfs_trim_extent_bytes_max", KSTAT_DATA_UINT64 }, - {"zfs_trim_extent_bytes_min", KSTAT_DATA_UINT64 }, - {"zfs_trim_metaslab_skip", KSTAT_DATA_UINT64 }, - {"zfs_trim_txg_batch", KSTAT_DATA_UINT64 }, - {"zfs_trim_queue_limit", KSTAT_DATA_UINT64 }, - - {"hostid", KSTAT_DATA_UINT32 }, - {"send_unmodified_spill_blocks", KSTAT_DATA_UINT64 }, - {"special_class_metadata_rsrv_pct", KSTAT_DATA_UINT64 }, - - { "zfs_disable_wincache", KSTAT_DATA_UINT64 }, - { "zfs_disable_removablemedia", KSTAT_DATA_UINT64 }, - { "zfs_vdev_initialize_value", KSTAT_DATA_UINT64 }, - { "zfs_autoimport_disable", KSTAT_DATA_UINT64 }, - { "zfs_total_memory_limit", KSTAT_DATA_UINT64 }, -}; - - - - -static kstat_t *windows_kstat_ksp; - -#if !defined(__OPTIMIZE__) -#pragma GCC diagnostic ignored "-Wframe-larger-than=" -#endif - -static int -windows_kstat_update(kstat_t *ksp, int rw) -{ - windows_kstat_t *ks = ksp->ks_data; - - if (rw == KSTAT_WRITE) { - - /* win32 */ - - extern void saveBuffer(void); - if (ks->win32_debug.value.ui64 == 1337) - saveBuffer(); - if (ks->win32_debug.value.ui64 == 9119) - panic("ZFS: User requested panic\n"); - zfs_vnop_ignore_negatives = - ks->win32_ignore_negatives.value.ui64; - zfs_vnop_ignore_positives = - ks->win32_ignore_positives.value.ui64; - zfs_vnop_create_negatives = - ks->win32_create_negatives.value.ui64; - zfs_vnop_skip_unlinked_drain = - ks->win32_skip_unlinked_drain.value.ui64; - zfs_vfs_sync_paranoia = ks->win32_use_system_sync.value.ui64; -#if 0 - /* L2ARC */ - l2arc_write_max = ks->l2arc_write_max.value.ui64; - l2arc_write_boost = ks->l2arc_write_boost.value.ui64; - l2arc_headroom = ks->l2arc_headroom.value.ui64; - l2arc_headroom_boost = ks->l2arc_headroom_boost.value.ui64; - l2arc_feed_secs = ks->l2arc_feed_secs.value.ui64; - l2arc_feed_min_ms = ks->l2arc_feed_min_ms.value.ui64; - - l2arc_noprefetch = ks->l2arc_noprefetch.value.i64; - l2arc_feed_again = ks->l2arc_feed_again.value.i64; - l2arc_norw = ks->l2arc_norw.value.i64; - - /* vdev_queue */ - - zfs_vdev_max_active = - ks->zfs_vdev_max_active.value.ui64; - zfs_vdev_sync_read_min_active = - ks->zfs_vdev_sync_read_min_active.value.ui64; - zfs_vdev_sync_read_max_active = - ks->zfs_vdev_sync_read_max_active.value.ui64; - zfs_vdev_sync_write_min_active = - ks->zfs_vdev_sync_write_min_active.value.ui64; - zfs_vdev_sync_write_max_active = - ks->zfs_vdev_sync_write_max_active.value.ui64; - zfs_vdev_async_read_min_active = - ks->zfs_vdev_async_read_min_active.value.ui64; - zfs_vdev_async_read_max_active = - ks->zfs_vdev_async_read_max_active.value.ui64; - zfs_vdev_async_write_min_active = - ks->zfs_vdev_async_write_min_active.value.ui64; - zfs_vdev_async_write_max_active = - ks->zfs_vdev_async_write_max_active.value.ui64; - zfs_vdev_scrub_min_active = - ks->zfs_vdev_scrub_min_active.value.ui64; - zfs_vdev_scrub_max_active = - ks->zfs_vdev_scrub_max_active.value.ui64; - zfs_vdev_async_write_active_min_dirty_percent = - ks->zfs_vdev_async_write_active_min_dirty_percent.value.i64; - zfs_vdev_async_write_active_max_dirty_percent = - ks->zfs_vdev_async_write_active_max_dirty_percent.value.i64; - zfs_vdev_aggregation_limit = - ks->zfs_vdev_aggregation_limit.value.i64; - zfs_vdev_read_gap_limit = - ks->zfs_vdev_read_gap_limit.value.i64; - zfs_vdev_write_gap_limit = - ks->zfs_vdev_write_gap_limit.value.i64; - - arc_lotsfree_percent = - ks->arc_lotsfree_percent.value.i64; - zfs_dirty_data_max = - ks->zfs_dirty_data_max.value.i64; - zfs_delay_max_ns = - ks->zfs_delay_max_ns.value.i64; - zfs_delay_min_dirty_percent = - ks->zfs_delay_min_dirty_percent.value.i64; - zfs_delay_scale = - ks->zfs_delay_scale.value.i64; - spa_asize_inflation = - ks->spa_asize_inflation.value.i64; - //zfs_prefetch_disable = - // ks->zfs_prefetch_disable.value.i64; - zfetch_max_streams = - ks->zfetch_max_streams.value.i64; - zfetch_min_sec_reap = - ks->zfetch_min_sec_reap.value.i64; - zfetch_array_rd_sz = - ks->zfetch_array_rd_sz.value.i64; - zfs_default_bs = - ks->zfs_default_bs.value.i64; - zfs_default_ibs = - ks->zfs_default_ibs.value.i64; - metaslab_aliquot = - ks->metaslab_aliquot.value.i64; - spa_max_replication_override = - ks->spa_max_replication_override.value.i64; - spa_mode_global = - ks->spa_mode_global.value.i64; - zfs_flags = - ks->zfs_flags.value.i64; - zfs_txg_timeout = - ks->zfs_txg_timeout.value.i64; - zfs_vdev_cache_max = - ks->zfs_vdev_cache_max.value.i64; - // zfs_vdev_cache_size = - // ks->zfs_vdev_cache_size.value.i64; - zfs_no_scrub_io = - ks->zfs_no_scrub_io.value.i64; - zfs_no_scrub_prefetch = - ks->zfs_no_scrub_prefetch.value.i64; - fzap_default_block_shift = - ks->fzap_default_block_shift.value.i64; - zfs_immediate_write_sz = - ks->zfs_immediate_write_sz.value.i64; -// zfs_read_chunk_size = -// ks->zfs_read_chunk_size.value.i64; - zfs_nocacheflush = - ks->zfs_nocacheflush.value.i64; - zil_replay_disable = - ks->zil_replay_disable.value.i64; - metaslab_df_alloc_threshold = - ks->metaslab_df_alloc_threshold.value.i64; - metaslab_df_free_pct = - ks->metaslab_df_free_pct.value.i64; - zio_injection_enabled = - ks->zio_injection_enabled.value.i64; - zvol_immediate_write_sz = - ks->zvol_immediate_write_sz.value.i64; - - zfs_recover = - ks->zfs_recover.value.i64; - - zfs_free_bpobj_enabled = - ks->zfs_free_bpobj_enabled.value.i64; - - zfs_send_corrupt_data = - ks->zfs_send_corrupt_data.value.ui64; - zfs_send_queue_length = - ks->zfs_send_queue_length.value.ui64; - zfs_recv_queue_length = - ks->zfs_recv_queue_length.value.ui64; - - zvol_inhibit_dev = - ks->zvol_inhibit_dev.value.ui64; - zfs_send_set_freerecords_bit = - ks->zfs_send_set_freerecords_bit.value.ui64; - - zfs_write_implies_delete_child = - ks->zfs_write_implies_delete_child.value.ui64; - send_holes_without_birth_time = - ks->zfs_send_holes_without_birth_time.value.ui64; - - dbuf_cache_max_bytes = - ks->dbuf_cache_max_bytes.value.ui64; - - zfs_vdev_queue_depth_pct = - ks->zfs_vdev_queue_depth_pct.value.ui64; - - zio_dva_throttle_enabled = - (boolean_t)ks->zio_dva_throttle_enabled.value.ui64; - - zfs_lua_max_instrlimit = - ks->zfs_lua_max_instrlimit.value.ui64; - zfs_lua_max_memlimit = - ks->zfs_lua_max_memlimit.value.ui64; - - zfs_trim_extent_bytes_max = - ks->zfs_trim_extent_bytes_max.value.ui64; - zfs_trim_extent_bytes_min = - ks->zfs_trim_extent_bytes_min.value.ui64; - zfs_trim_metaslab_skip = - ks->zfs_trim_metaslab_skip.value.ui64; - zfs_trim_txg_batch = - ks->zfs_trim_txg_batch.value.ui64; - zfs_trim_queue_limit = - ks->zfs_trim_queue_limit.value.ui64; - - spl_hostid = ks->win32_hw_hostid.value.ui32; - zfs_send_unmodified_spill_blocks = - ks->zfs_send_unmodified_spill_blocks.value.ui64; - zfs_special_class_metadata_reserve_pct = - ks->zfs_special_class_metadata_reserve_pct.value.ui64; - - zfs_disable_wincache = - ks->zfs_disable_wincache.value.ui64; - zfs_disable_removablemedia = - ks->zfs_disable_removablemedia.value.ui64; - zfs_initialize_value = - ks->zfs_vdev_initialize_value.value.ui64; - zfs_autoimport_disable = - ks->zfs_autoimport_disable.value.ui64; -#endif - } else { - - /* kstat READ */ - ks->spa_version.value.ui64 = SPA_VERSION; - ks->zpl_version.value.ui64 = ZPL_VERSION; - - /* win32 */ - ks->win32_active_vnodes.value.ui64 = vnop_num_vnodes; - ks->win32_reclaim_nodes.value.ui64 = vnop_num_reclaims; - ks->win32_ignore_negatives.value.ui64 = - zfs_vnop_ignore_negatives; - ks->win32_ignore_positives.value.ui64 = - zfs_vnop_ignore_positives; - ks->win32_create_negatives.value.ui64 = - zfs_vnop_create_negatives; - ks->win32_skip_unlinked_drain.value.ui64 = - zfs_vnop_skip_unlinked_drain; - ks->win32_use_system_sync.value.ui64 = zfs_vfs_sync_paranoia; -#if 0 - /* L2ARC */ - ks->l2arc_write_max.value.ui64 = l2arc_write_max; - ks->l2arc_write_boost.value.ui64 = l2arc_write_boost; - ks->l2arc_headroom.value.ui64 = l2arc_headroom; - ks->l2arc_headroom_boost.value.ui64 = l2arc_headroom_boost; - ks->l2arc_feed_secs.value.ui64 = l2arc_feed_secs; - ks->l2arc_feed_min_ms.value.ui64 = l2arc_feed_min_ms; - - ks->l2arc_noprefetch.value.i64 = l2arc_noprefetch; - ks->l2arc_feed_again.value.i64 = l2arc_feed_again; - ks->l2arc_norw.value.i64 = l2arc_norw; - - /* vdev_queue */ - ks->zfs_vdev_max_active.value.ui64 = - zfs_vdev_max_active; - ks->zfs_vdev_sync_read_min_active.value.ui64 = - zfs_vdev_sync_read_min_active; - ks->zfs_vdev_sync_read_max_active.value.ui64 = - zfs_vdev_sync_read_max_active; - ks->zfs_vdev_sync_write_min_active.value.ui64 = - zfs_vdev_sync_write_min_active; - ks->zfs_vdev_sync_write_max_active.value.ui64 = - zfs_vdev_sync_write_max_active; - ks->zfs_vdev_async_read_min_active.value.ui64 = - zfs_vdev_async_read_min_active; - ks->zfs_vdev_async_read_max_active.value.ui64 = - zfs_vdev_async_read_max_active; - ks->zfs_vdev_async_write_min_active.value.ui64 = - zfs_vdev_async_write_min_active; - ks->zfs_vdev_async_write_max_active.value.ui64 = - zfs_vdev_async_write_max_active; - ks->zfs_vdev_scrub_min_active.value.ui64 = - zfs_vdev_scrub_min_active; - ks->zfs_vdev_scrub_max_active.value.ui64 = - zfs_vdev_scrub_max_active; - ks->zfs_vdev_async_write_active_min_dirty_percent.value.i64 = - zfs_vdev_async_write_active_min_dirty_percent; - ks->zfs_vdev_async_write_active_max_dirty_percent.value.i64 = - zfs_vdev_async_write_active_max_dirty_percent; - ks->zfs_vdev_aggregation_limit.value.i64 = - zfs_vdev_aggregation_limit; - ks->zfs_vdev_read_gap_limit.value.i64 = - zfs_vdev_read_gap_limit; - ks->zfs_vdev_write_gap_limit.value.i64 = - zfs_vdev_write_gap_limit; - - ks->arc_lotsfree_percent.value.i64 = - arc_lotsfree_percent; - ks->zfs_dirty_data_max.value.i64 = - zfs_dirty_data_max; - ks->zfs_delay_max_ns.value.i64 = - zfs_delay_max_ns; - ks->zfs_delay_min_dirty_percent.value.i64 = - zfs_delay_min_dirty_percent; - ks->zfs_delay_scale.value.i64 = - zfs_delay_scale; - ks->spa_asize_inflation.value.i64 = - spa_asize_inflation; - //ks->zfs_prefetch_disable.value.i64 = - // zfs_prefetch_disable; - ks->zfetch_max_streams.value.i64 = - zfetch_max_streams; - ks->zfetch_min_sec_reap.value.i64 = - zfetch_min_sec_reap; - ks->zfetch_array_rd_sz.value.i64 = - zfetch_array_rd_sz; - ks->zfs_default_bs.value.i64 = - zfs_default_bs; - ks->zfs_default_ibs.value.i64 = - zfs_default_ibs; - ks->metaslab_aliquot.value.i64 = - metaslab_aliquot; - ks->spa_max_replication_override.value.i64 = - spa_max_replication_override; - ks->spa_mode_global.value.i64 = - spa_mode_global; - ks->zfs_flags.value.i64 = - zfs_flags; - ks->zfs_txg_timeout.value.i64 = - zfs_txg_timeout; - ks->zfs_vdev_cache_max.value.i64 = - zfs_vdev_cache_max; - // ks->zfs_vdev_cache_size.value.i64 = - // zfs_vdev_cache_size; - ks->zfs_no_scrub_io.value.i64 = - zfs_no_scrub_io; - ks->zfs_no_scrub_prefetch.value.i64 = - zfs_no_scrub_prefetch; - ks->fzap_default_block_shift.value.i64 = - fzap_default_block_shift; - ks->zfs_immediate_write_sz.value.i64 = - zfs_immediate_write_sz; -// ks->zfs_read_chunk_size.value.i64 = -// zfs_read_chunk_size; - ks->zfs_nocacheflush.value.i64 = - zfs_nocacheflush; - ks->zil_replay_disable.value.i64 = - zil_replay_disable; - ks->metaslab_df_alloc_threshold.value.i64 = - metaslab_df_alloc_threshold; - ks->metaslab_df_free_pct.value.i64 = - metaslab_df_free_pct; - ks->zio_injection_enabled.value.i64 = - zio_injection_enabled; - ks->zvol_immediate_write_sz.value.i64 = - zvol_immediate_write_sz; - - ks->zfs_recover.value.i64 = - zfs_recover; - - ks->zfs_free_bpobj_enabled.value.i64 = - zfs_free_bpobj_enabled; - - ks->zfs_send_corrupt_data.value.ui64 = - zfs_send_corrupt_data; - ks->zfs_send_queue_length.value.ui64 = - zfs_send_queue_length; - ks->zfs_recv_queue_length.value.ui64 = - zfs_recv_queue_length; - - ks->zvol_inhibit_dev.value.ui64 = - zvol_inhibit_dev; - ks->zfs_send_set_freerecords_bit.value.ui64 = - zfs_send_set_freerecords_bit; - - ks->zfs_write_implies_delete_child.value.ui64 = - zfs_write_implies_delete_child; - ks->zfs_send_holes_without_birth_time.value.ui64 = - send_holes_without_birth_time; - - ks->dbuf_cache_max_bytes.value.ui64 = dbuf_cache_max_bytes; - - ks->zfs_vdev_queue_depth_pct.value.ui64 = - zfs_vdev_queue_depth_pct; - ks->zio_dva_throttle_enabled.value.ui64 = - (uint64_t)zio_dva_throttle_enabled; - - ks->zfs_lua_max_instrlimit.value.ui64 = zfs_lua_max_instrlimit; - ks->zfs_lua_max_memlimit.value.ui64 = zfs_lua_max_memlimit; - - ks->zfs_trim_extent_bytes_max.value.ui64 = - zfs_trim_extent_bytes_max; - ks->zfs_trim_extent_bytes_min.value.ui64 = - zfs_trim_extent_bytes_min; - ks->zfs_trim_metaslab_skip.value.ui64 = - zfs_trim_metaslab_skip; - ks->zfs_trim_txg_batch.value.ui64 = - zfs_trim_txg_batch; - ks->zfs_trim_queue_limit.value.ui64 = - zfs_trim_queue_limit; - - ks->win32_hw_hostid.value.ui32 = spl_hostid; - ks->zfs_send_unmodified_spill_blocks.value.ui64 = - zfs_send_unmodified_spill_blocks; - ks->zfs_special_class_metadata_reserve_pct.value.ui64 = - zfs_special_class_metadata_reserve_pct; - - ks->zfs_disable_wincache.value.ui64 = - zfs_disable_wincache; - ks->zfs_disable_removablemedia.value.ui64 = - zfs_disable_removablemedia; - ks->zfs_vdev_initialize_value.value.ui64 = - zfs_initialize_value; - ks->zfs_autoimport_disable.value.ui64 = - zfs_autoimport_disable; -#endif - } - // arc_kstat_update_windows(ksp, rw); - return (0); -} - -int -kstat_windows_init(void *arg) -{ - int error = 0; - PUNICODE_STRING RegistryPath = arg; - - windows_kstat_ksp = kstat_create("zfs", 0, "tunable", "win32", - KSTAT_TYPE_NAMED, sizeof (windows_kstat) / sizeof (kstat_named_t), - KSTAT_FLAG_VIRTUAL|KSTAT_FLAG_WRITABLE); - - if (windows_kstat_ksp != NULL) { - windows_kstat_ksp->ks_data = &windows_kstat; - windows_kstat_ksp->ks_update = windows_kstat_update; - kstat_install(windows_kstat_ksp); - - // We don't hold the ksp here, only call at init, so there are - // no other threads. - KSTAT_ENTER(windows_kstat_ksp); - error = KSTAT_UPDATE(windows_kstat_ksp, KSTAT_READ); - if (error != 0) goto out; - - // Returns number of changed, zero means nothing to do. - error = spl_kstat_registry(RegistryPath, windows_kstat_ksp); - if (error == 0) goto out; - - error = KSTAT_UPDATE(windows_kstat_ksp, KSTAT_WRITE); - - out: - KSTAT_EXIT(windows_kstat_ksp); - } - - return (0); -} - -void -kstat_windows_fini(void) -{ - if (windows_kstat_ksp != NULL) { - kstat_delete(windows_kstat_ksp); - windows_kstat_ksp = NULL; - } -} diff --git a/module/os/windows/zfs/zfs_vnops_windows_lib.c b/module/os/windows/zfs/zfs_vnops_windows_lib.c index d4595d8dd2e4..eddfa3b29ff8 100644 --- a/module/os/windows/zfs/zfs_vnops_windows_lib.c +++ b/module/os/windows/zfs/zfs_vnops_windows_lib.c @@ -447,6 +447,10 @@ int AsciiStringToUnicodeString(char *in, PUNICODE_STRING out) { ANSI_STRING conv; + if (in == NULL) { + memset(out, 0, sizeof(UNICODE_STRING)); + return (0); + } conv.Buffer = in; conv.Length = strlen(in); conv.MaximumLength = PATH_MAX;