- diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c
- index 9941ce2..f7b521b 100644
- --- a/daemon/daemon_debug.c
- +++ b/daemon/daemon_debug.c
- @@ -802,3 +802,63 @@ void print_nfs41_file_info(
- dprintf_out("%s={ %s }\n", label, buf);
- }
- +
- +#define NUM_RECENTLY_DELETED 64
- +static struct
- +{
- + SRWLOCK lock;
- + void *deleted_ptrs[NUM_RECENTLY_DELETED];
- + size_t deleted_index;
- +} ptr_recently_deleted_data = {
- + .lock = SRWLOCK_INIT,
- +};
- +
- +bool debug_ptr_was_recently_deleted(void *in_ptr)
- +{
- + size_t i;
- + bool_t res = false;
- +
- + AcquireSRWLockShared(&ptr_recently_deleted_data.lock);
- + for (i=0 ; i < NUM_RECENTLY_DELETED ; i++) {
- + if (ptr_recently_deleted_data.deleted_ptrs[i] == in_ptr) {
- + res = true;
- + break;
- + }
- + }
- + ReleaseSRWLockShared(&ptr_recently_deleted_data.lock);
- + return res;
- +}
- +
- +void debug_ptr_add_recently_deleted(void *in_ptr)
- +{
- + size_t i;
- +
- + AcquireSRWLockExclusive(&ptr_recently_deleted_data.lock);
- + i = ptr_recently_deleted_data.deleted_index++ % NUM_RECENTLY_DELETED;
- + ptr_recently_deleted_data.deleted_ptrs[i] = in_ptr;
- + ReleaseSRWLockExclusive(&ptr_recently_deleted_data.lock);
- +}
- +
- +#define NUM_DELAY_FREE 2048
- +static struct
- +{
- + SRWLOCK lock;
- + void *free_ptrs[NUM_DELAY_FREE];
- + size_t free_ptrs_index;
- +} debug_delay_free_data = {
- + .lock = SRWLOCK_INIT,
- +};
- +
- +void debug_delayed_free(void *in_ptr)
- +{
- + size_t i;
- +
- + AcquireSRWLockExclusive(&debug_delay_free_data.lock);
- + i = debug_delay_free_data.free_ptrs_index++ % NUM_DELAY_FREE;
- +
- + if (debug_delay_free_data.free_ptrs[i])
- + free(debug_delay_free_data.free_ptrs[i]);
- +
- + debug_delay_free_data.free_ptrs[i] = in_ptr;
- + ReleaseSRWLockExclusive(&debug_delay_free_data.lock);
- +}
- diff --git a/daemon/daemon_debug.h b/daemon/daemon_debug.h
- index 1b693e3..2bb42b6 100644
- --- a/daemon/daemon_debug.h
- +++ b/daemon/daemon_debug.h
- @@ -31,6 +31,7 @@
- #else
- # include <stdlib.h>
- #endif
- +#include <stdbool.h>
- #define DEFAULT_DEBUG_LEVEL 1
- @@ -118,4 +119,9 @@ const char* pnfs_iomode_string(enum pnfs_iomode iomode);
- void dprint_layout(int level, const struct __pnfs_file_layout *layout);
- void dprint_device(int level, const struct __pnfs_file_device *device);
- +bool debug_ptr_was_recently_deleted(void *in_ptr);
- +void debug_ptr_add_recently_deleted(void *in_ptr);
- +
- +void debug_delayed_free(void *in_ptr);
- +
- #endif
- diff --git a/daemon/getattr.c b/daemon/getattr.c
- index 3c69db3..9d8db95 100644
- --- a/daemon/getattr.c
- +++ b/daemon/getattr.c
- @@ -68,6 +68,13 @@ static int parse_getattr(unsigned char *buffer, uint32_t length, nfs41_upcall *u
- goto out;
- }
- + if (debug_ptr_was_recently_deleted(upcall->state_ref)) {
- + eprintf("parse_getattr: upcall->state_ref(=0x%p) was "
- + "recently deleted\n", upcall->state_ref);
- + status = ERROR_INVALID_PARAMETER;
- + goto out;
- + }
- +
- EASSERT_IS_VALID_NON_NULL_PTR(upcall->state_ref);
- if (!DEBUG_IS_VALID_NON_NULL_PTR(upcall->state_ref)) {
- status = ERROR_INVALID_PARAMETER;
- diff --git a/daemon/nfs41.h b/daemon/nfs41.h
- index c8216dd..698e970 100644
- --- a/daemon/nfs41.h
- +++ b/daemon/nfs41.h
- @@ -84,7 +84,7 @@ typedef struct __nfs41_server {
- nfs41_superblock_list superblocks;
- struct nfs41_name_cache *name_cache;
- struct list_entry entry; /* position in global server list */
- - LONG ref_count;
- + __declspec(align(8)) volatile LONG ref_count;
- } nfs41_server;
- enum delegation_status {
- @@ -99,7 +99,7 @@ typedef struct __nfs41_delegation_state {
- nfs41_path_fh parent;
- nfs41_path_fh file;
- struct list_entry client_entry; /* entry in nfs41_client.delegations */
- - LONG ref_count;
- + __declspec(align(8)) volatile LONG ref_count;
- enum delegation_status status;
- SRWLOCK lock;
- @@ -138,7 +138,7 @@ typedef struct __nfs41_open_state {
- struct __pnfs_layout_state *layout;
- struct list_entry client_entry; /* entry in nfs41_client.opens */
- SRWLOCK lock;
- - LONG ref_count;
- + __declspec(align(8)) volatile LONG ref_count;
- uint32_t share_access;
- uint32_t share_deny;
- uint64_t pnfs_last_offset; /* for layoutcommit */
- @@ -296,7 +296,7 @@ typedef struct __nfs41_root {
- struct list_entry clients;
- uint32_t wsize;
- uint32_t rsize;
- - LONG ref_count;
- + __declspec(align(8)) volatile LONG ref_count;
- uint32_t uid;
- uint32_t gid;
- DWORD sec_flavor;
- diff --git a/daemon/open.c b/daemon/open.c
- index 0732aa2..3f1e516 100644
- --- a/daemon/open.c
- +++ b/daemon/open.c
- @@ -86,6 +86,10 @@ static void open_state_free(
- {
- struct list_entry *entry, *tmp;
- +#ifdef NFS41_DRIVER_STABILITY_HACKS
- + debug_ptr_add_recently_deleted(state);
- +#endif /* NFS41_DRIVER_STABILITY_HACKS */
- +
- EASSERT(waitcriticalsection(&state->ea.lock) == TRUE);
- EASSERT(waitcriticalsection(&state->locks.lock) == TRUE);
- @@ -105,10 +109,14 @@ static void open_state_free(
- EASSERT(state->ref_count == 0);
- +#ifdef NFS41_DRIVER_STABILITY_HACKS
- + (void)memset(state, 0, sizeof(nfs41_open_state));
- + debug_delayed_free(state);
- +#else
- free(state);
- +#endif /* NFS41_DRIVER_STABILITY_HACKS */
- }
- -
- /* open state reference counting */
- void nfs41_open_state_ref(
- IN nfs41_open_state *state)
- diff --git a/daemon/upcall.c b/daemon/upcall.c
- index 3a7047b..b35a8f9 100644
- --- a/daemon/upcall.c
- +++ b/daemon/upcall.c
- @@ -115,6 +115,18 @@ int upcall_parse(
- eprintf("unrecognized upcall opcode %d!\n", upcall->opcode);
- goto out;
- }
- +
- +#ifdef NFS41_DRIVER_STABILITY_HACKS
- + if (upcall->state_ref != INVALID_HANDLE_VALUE) {
- + if (upcall->state_ref->ref_count == 0) {
- + eprintf("upcall->state_ref(=0x%p).ref_count == 0, "
- + "opcode %d!\n", upcall->state_ref, upcall->opcode);
- + status = ERROR_INTERNAL_ERROR;
- + goto out;
- + }
- + }
- +#endif
- +
- if (upcall->root_ref != INVALID_HANDLE_VALUE)
- nfs41_root_ref(upcall->root_ref);
- if (upcall->state_ref != INVALID_HANDLE_VALUE)
- diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
- index 52c633c..99e4187 100644
- --- a/sys/nfs41_driver.c
- +++ b/sys/nfs41_driver.c
- @@ -1364,7 +1364,56 @@ NTSTATUS handle_upcall(
- ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
- unsigned char *pbOut = LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
- +#ifdef NFS41_DRIVER_STABILITY_HACKS
- + /*
- + * Workaround for random crashes like this while compiling
- + * the "gcc" compiler with a highly-parallel build.
- + * Stack trace usually looks like this:
- + * ---- snip ----
- + * nt!SeTokenCanImpersonate+0x47
- + * nt!PsImpersonateClient+0x126
- + * nt!SeImpersonateClientEx+0x35
- + * nfs41_driver!handle_upcall+0x59 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1367]
- + * nfs41_driver!nfs41_upcall+0xe7 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1578]
- + * nfs41_driver!nfs41_DevFcbXXXControlFile+0x128 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 2418]
- + * nfs41_driver!RxXXXControlFileCallthru+0x76 [base\fs\rdr2\rdbss\ntdevfcb.c @ 130]
- + * nfs41_driver!RxCommonDevFCBIoCtl+0x58 [base\fs\rdr2\rdbss\ntdevfcb.c @ 491]
- + * nfs41_driver!RxFsdCommonDispatch+0x442 [base\fs\rdr2\rdbss\ntfsd.c @ 848]
- + * nfs41_driver!RxFsdDispatch+0xfd [base\fs\rdr2\rdbss\ntfsd.c @ 442]
- + * nfs41_driver!nfs41_FsdDispatch+0x67 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 6863]
- + * nt!IofCallDriver+0x55
- + * mup!MupiCallUncProvider+0xb8
- + * mup!MupStateMachine+0x59
- + * mup!MupFsdIrpPassThrough+0x17e
- + * nt!IofCallDriver+0x55
- + * FLTMGR!FltpDispatch+0xd6
- + * nt!IofCallDriver+0x55
- + * nt!IopSynchronousServiceTail+0x34c
- + * nt!IopXxxControlFile+0xd13
- + * nt!NtDeviceIoControlFile+0x56
- + * nt!KiSystemServiceCopyEnd+0x25
- + * ntdll!NtDeviceIoControlFile+0x14
- + * KERNELBASE!DeviceIoControl+0x6b
- + * KERNEL32!DeviceIoControlImplementation+0x81
- + * nfsd_debug+0xc7b14
- + * nfsd_debug+0xc79fb
- + * nfsd_debug+0x171e80
- + * KERNEL32!BaseThreadInitThunk+0x14
- + * ntdll!RtlUserThreadStart+0x21
- + * ---- snip ----
- + */
- + __try {
- + status = SeImpersonateClientEx(entry->psec_ctx, NULL);
- + } __except(EXCEPTION_EXECUTE_HANDLER) {
- + NTSTATUS code;
- + code = GetExceptionCode();
- + print_error("handle_upcall: Call to SeImpersonateClientEx() "
- + "failed due to exception 0x%0x\n", (int)code);
- + status = STATUS_INTERNAL_ERROR;
- + }
- +#else
- status = SeImpersonateClientEx(entry->psec_ctx, NULL);
- +#endif /* NFS41_DRIVER_STABILITY_HACKS */
- if (status != STATUS_SUCCESS) {
- print_error("SeImpersonateClientEx failed %x\n", status);
- goto out;
delay_free+stability hacks prototype 2024-02-29-001
Posted by Anonymous on Thu 29th Feb 2024 15:59
raw | new post
modification of post by Anonymous (view diff)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.