pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS

Difference between
modified post b1c71ad by Anonymous on Thu 29th Feb 2024 15:59
original post bcf61 by Anonymous on Thu 29th Feb 2024 13:09
Download diff
Show old version | new version | both versions

    
11
diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c
22
index 9941ce2..f7b521b 100644
33
--- a/daemon/daemon_debug.c
44
+++ b/daemon/daemon_debug.c
55
@@ -802,3 +802,63 @@ void print_nfs41_file_info(
66
77
     dprintf_out("%s={ %s }\n", label, buf);
88
 }
99
+
1010
+#define NUM_RECENTLY_DELETED 64
1111
+static struct
1212
+{
1313
+    SRWLOCK lock;
1414
+    void *deleted_ptrs[NUM_RECENTLY_DELETED];
1515
+    size_t deleted_index;
1616
+} ptr_recently_deleted_data = {
1717
+    .lock = SRWLOCK_INIT,
1818
+};
1919
+
2020
+bool debug_ptr_was_recently_deleted(void *in_ptr)
2121
+{
2222
+    size_t i;
2323
+    bool_t res = false;
2424
+
2525
+    AcquireSRWLockShared(&ptr_recently_deleted_data.lock);
2626
+    for (i=0 ; i < NUM_RECENTLY_DELETED ; i++) {
2727
+        if (ptr_recently_deleted_data.deleted_ptrs[i] == in_ptr) {
2828
+            res = true;
2929
+            break;
3030
+        }
3131
+    }
3232
+    ReleaseSRWLockShared(&ptr_recently_deleted_data.lock);
3333
+    return res;
3434
+}
3535
+
3636
+void debug_ptr_add_recently_deleted(void *in_ptr)
3737
+{
3838
+    size_t i;
3939
+
4040
+    AcquireSRWLockExclusive(&ptr_recently_deleted_data.lock);
4141
+    i = ptr_recently_deleted_data.deleted_index++ % NUM_RECENTLY_DELETED;
4242
+    ptr_recently_deleted_data.deleted_ptrs[i] = in_ptr;
4343
+    ReleaseSRWLockExclusive(&ptr_recently_deleted_data.lock);
4444
+}
4545
+
4646
+#define NUM_DELAY_FREE 2048
4747
+static struct
4848
+{
4949
+    SRWLOCK lock;
5050
+    void *free_ptrs[NUM_DELAY_FREE];
5151
+    size_t free_ptrs_index;
5252
+} debug_delay_free_data = {
5353
+    .lock = SRWLOCK_INIT,
5454
+};
5555
+
5656
+void debug_delayed_free(void *in_ptr)
5757
+{
5858
+    size_t i;
5959
+
6060
+    AcquireSRWLockExclusive(&debug_delay_free_data.lock);
6161
+    i = debug_delay_free_data.free_ptrs_index++ % NUM_DELAY_FREE;
6262
+
6363
+    if (debug_delay_free_data.free_ptrs[i])
6464
+        free(debug_delay_free_data.free_ptrs[i]);
6565
+
6666
+    debug_delay_free_data.free_ptrs[i] = in_ptr;
6767
+    ReleaseSRWLockExclusive(&debug_delay_free_data.lock);
6868
+}
6969
diff --git a/daemon/daemon_debug.h b/daemon/daemon_debug.h
7070
index 1b693e3..2bb42b6 100644
7171
--- a/daemon/daemon_debug.h
7272
+++ b/daemon/daemon_debug.h
7373
@@ -31,6 +31,7 @@
7474
 #else
7575
 # include <stdlib.h>
7676
 #endif
7777
+#include <stdbool.h>
7878
7979
 #define DEFAULT_DEBUG_LEVEL 1
8080
8181
@@ -118,4 +119,9 @@ const char* pnfs_iomode_string(enum pnfs_iomode iomode);
8282
 void dprint_layout(int level, const struct __pnfs_file_layout *layout);
8383
 void dprint_device(int level, const struct __pnfs_file_device *device);
8484
8585
+bool debug_ptr_was_recently_deleted(void *in_ptr);
8686
+void debug_ptr_add_recently_deleted(void *in_ptr);
8787
+
8888
+void debug_delayed_free(void *in_ptr);
8989
+
9090
 #endif
9191
diff --git a/daemon/getattr.c b/daemon/getattr.c
9292
index 3c69db3..9d8db95 100644
9393
--- a/daemon/getattr.c
9494
+++ b/daemon/getattr.c
9595
@@ -68,6 +68,13 @@ static int parse_getattr(unsigned char *buffer, uint32_t length, nfs41_upcall *u
9696
         goto out;
9797
     }
9898
9999
+    if (debug_ptr_was_recently_deleted(upcall->state_ref)) {
100100
+        eprintf("parse_getattr: upcall->state_ref(=0x%p) was "
101101
+            "recently deleted\n", upcall->state_ref);
102102
+        status = ERROR_INVALID_PARAMETER;
103103
+        goto out;
104104
+    }
105105
+
106106
     EASSERT_IS_VALID_NON_NULL_PTR(upcall->state_ref);
107107
     if (!DEBUG_IS_VALID_NON_NULL_PTR(upcall->state_ref)) {
108108
         status = ERROR_INVALID_PARAMETER;
109109
diff --git a/daemon/nfs41.h b/daemon/nfs41.h
110110
index c8216dd..698e970 100644
111111
--- a/daemon/nfs41.h
112112
+++ b/daemon/nfs41.h
113113
@@ -84,7 +84,7 @@ typedef struct __nfs41_server {
114114
     nfs41_superblock_list superblocks;
115115
     struct nfs41_name_cache *name_cache;
116116
     struct list_entry entry; /* position in global server list */
117117
-    LONG ref_count;
118118
+    __declspec(align(8)) volatile LONG ref_count;
119119
 } nfs41_server;
120120
121121
 enum delegation_status {
122122
@@ -99,7 +99,7 @@ typedef struct __nfs41_delegation_state {
123123
     nfs41_path_fh parent;
124124
     nfs41_path_fh file;
125125
     struct list_entry client_entry; /* entry in nfs41_client.delegations */
126126
-    LONG ref_count;
127127
+    __declspec(align(8)) volatile LONG ref_count;
128128
129129
     enum delegation_status status;
130130
     SRWLOCK lock;
131131
@@ -138,7 +138,7 @@ typedef struct __nfs41_open_state {
132132
     struct __pnfs_layout_state *layout;
133133
     struct list_entry client_entry; /* entry in nfs41_client.opens */
134134
     SRWLOCK lock;
135135
-    LONG ref_count;
136136
+    __declspec(align(8)) volatile LONG ref_count;
137137
     uint32_t share_access;
138138
     uint32_t share_deny;
139139
     uint64_t pnfs_last_offset; /* for layoutcommit */
140140
@@ -296,7 +296,7 @@ typedef struct __nfs41_root {
141141
     struct list_entry clients;
142142
     uint32_t wsize;
143143
     uint32_t rsize;
144144
-    LONG ref_count;
145145
+    __declspec(align(8)) volatile LONG ref_count;
146146
     uint32_t uid;
147147
     uint32_t gid;
148148
     DWORD sec_flavor;
149149
diff --git a/daemon/open.c b/daemon/open.c
150-
index 0732aa2..1b9ef26 100644
150+
index 0732aa2..3f1e516 100644
151151
--- a/daemon/open.c
152152
+++ b/daemon/open.c
153153
@@ -86,6 +86,10 @@ static void open_state_free(
154154
 {
155155
     struct list_entry *entry, *tmp;
156156
157157
+#ifdef NFS41_DRIVER_STABILITY_HACKS
158158
+    debug_ptr_add_recently_deleted(state);
159159
+#endif /* NFS41_DRIVER_STABILITY_HACKS */
160160
+
161161
     EASSERT(waitcriticalsection(&state->ea.lock) == TRUE);
162162
     EASSERT(waitcriticalsection(&state->locks.lock) == TRUE);
163163
164-
@@ -105,10 +109,13 @@ static void open_state_free(
164+
@@ -105,10 +109,14 @@ static void open_state_free(
165165
166166
     EASSERT(state->ref_count == 0);
167167
168168
+#ifdef NFS41_DRIVER_STABILITY_HACKS
169+
+    (void)memset(state, 0, sizeof(nfs41_open_state));
169170
+    debug_delayed_free(state);
170171
+#else
171172
     free(state);
172173
+#endif /* NFS41_DRIVER_STABILITY_HACKS */
173174
 }
174175
175176
-
176177
 /* open state reference counting */
177178
 void nfs41_open_state_ref(
178179
     IN nfs41_open_state *state)
179-
diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
180+
diff --git a/daemon/upcall.c b/daemon/upcall.c
180-
index 52c633c..99e4187 100644
181+
index 3a7047b..b35a8f9 100644
181-
--- a/sys/nfs41_driver.c
182+
--- a/daemon/upcall.c
182-
+++ b/sys/nfs41_driver.c
183+
+++ b/daemon/upcall.c
183-
@@ -1364,7 +1364,56 @@ NTSTATUS handle_upcall(
184+
@@ -115,6 +115,18 @@ int upcall_parse(
184-
     ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
185+
         eprintf("unrecognized upcall opcode %d!\n", upcall->opcode);
185-
     unsigned char *pbOut = LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
186+
         goto out;
186-
187+
     }
188+
+
187189
+#ifdef NFS41_DRIVER_STABILITY_HACKS
188-
+    /*
190+
+    if (upcall->state_ref != INVALID_HANDLE_VALUE) {
189-
+     * Workaround for random crashes like this while compiling
191+
+        if (upcall->state_ref->ref_count == 0) {
190-
+     * the "gcc" compiler with a highly-parallel build.
192+
+            eprintf("upcall->state_ref(=0x%p).ref_count == 0, "
191-
+     * Stack trace usually looks like this:
193+
+                "opcode %d!\n", upcall->state_ref, upcall->opcode);
192-
+     * ---- snip ----
194+
+            status = ERROR_INTERNAL_ERROR;
193-
+     * nt!SeTokenCanImpersonate+0x47
195+
+            goto out;
194-
+     * nt!PsImpersonateClient+0x126
196+
+        }
195-
+     * nt!SeImpersonateClientEx+0x35
197+
+    }
196-
+     * nfs41_driver!handle_upcall+0x59 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1367]
198+
+#endif
197-
+     * nfs41_driver!nfs41_upcall+0xe7 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1578]
199+
+
198-
+     * nfs41_driver!nfs41_DevFcbXXXControlFile+0x128 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 2418]
200+
     if (upcall->root_ref != INVALID_HANDLE_VALUE)
199-
+     * nfs41_driver!RxXXXControlFileCallthru+0x76 [base\fs\rdr2\rdbss\ntdevfcb.c @ 130]
201+
         nfs41_root_ref(upcall->root_ref);
200-
+     * nfs41_driver!RxCommonDevFCBIoCtl+0x58 [base\fs\rdr2\rdbss\ntdevfcb.c @ 491]
202+
     if (upcall->state_ref != INVALID_HANDLE_VALUE)
201-
+     * nfs41_driver!RxFsdCommonDispatch+0x442 [base\fs\rdr2\rdbss\ntfsd.c @ 848]
203+
diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
202-
+     * nfs41_driver!RxFsdDispatch+0xfd [base\fs\rdr2\rdbss\ntfsd.c @ 442]
204+
index 52c633c..99e4187 100644
203-
+     * nfs41_driver!nfs41_FsdDispatch+0x67 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 6863]
205+
--- a/sys/nfs41_driver.c
204-
+     * nt!IofCallDriver+0x55
206+
+++ b/sys/nfs41_driver.c
205-
+     * mup!MupiCallUncProvider+0xb8
207+
@@ -1364,7 +1364,56 @@ NTSTATUS handle_upcall(
206-
+     * mup!MupStateMachine+0x59
208+
     ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
207-
+     * mup!MupFsdIrpPassThrough+0x17e
209+
     unsigned char *pbOut = LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
208-
+     * nt!IofCallDriver+0x55
210+
209-
+     * FLTMGR!FltpDispatch+0xd6
211+
+#ifdef NFS41_DRIVER_STABILITY_HACKS
210-
+     * nt!IofCallDriver+0x55
212+
+    /*
211-
+     * nt!IopSynchronousServiceTail+0x34c
213+
+     * Workaround for random crashes like this while compiling
212-
+     * nt!IopXxxControlFile+0xd13
214+
+     * the "gcc" compiler with a highly-parallel build.
213-
+     * nt!NtDeviceIoControlFile+0x56
215+
+     * Stack trace usually looks like this:
223216
+     * ---- snip ----
224-
+     */
217+
+     * nt!SeTokenCanImpersonate+0x47
225-
+    __try {
218+
+     * nt!PsImpersonateClient+0x126
226-
+        status = SeImpersonateClientEx(entry->psec_ctx, NULL);
219+
+     * nt!SeImpersonateClientEx+0x35
227-
+    } __except(EXCEPTION_EXECUTE_HANDLER) {
220+
+     * nfs41_driver!handle_upcall+0x59 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1367]
228-
+        NTSTATUS code;
221+
+     * nfs41_driver!nfs41_upcall+0xe7 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1578]
229-
+        code = GetExceptionCode();
222+
+     * nfs41_driver!nfs41_DevFcbXXXControlFile+0x128 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 2418]
230-
+        print_error("handle_upcall: Call to SeImpersonateClientEx() "
223+
+     * nfs41_driver!RxXXXControlFileCallthru+0x76 [base\fs\rdr2\rdbss\ntdevfcb.c @ 130]
231-
+            "failed due to exception 0x%0x\n", (int)code);
224+
+     * nfs41_driver!RxCommonDevFCBIoCtl+0x58 [base\fs\rdr2\rdbss\ntdevfcb.c @ 491]
232-
+        status = STATUS_INTERNAL_ERROR;
225+
+     * nfs41_driver!RxFsdCommonDispatch+0x442 [base\fs\rdr2\rdbss\ntfsd.c @ 848]
233-
+    }
226+
+     * nfs41_driver!RxFsdDispatch+0xfd [base\fs\rdr2\rdbss\ntfsd.c @ 442]
234-
+#else
227+
+     * nfs41_driver!nfs41_FsdDispatch+0x67 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 6863]
235-
     status = SeImpersonateClientEx(entry->psec_ctx, NULL);
228+
+     * nt!IofCallDriver+0x55
236-
+#endif /* NFS41_DRIVER_STABILITY_HACKS */
229+
+     * mup!MupiCallUncProvider+0xb8
237-
     if (status != STATUS_SUCCESS) {
230+
+     * mup!MupStateMachine+0x59
238-
         print_error("SeImpersonateClientEx failed %x\n", status);
231+
+     * mup!MupFsdIrpPassThrough+0x17e
239-
         goto out;
232+
+     * nt!IofCallDriver+0x55
240-
233+
+     * FLTMGR!FltpDispatch+0xd6
241-
234+
+     * nt!IofCallDriver+0x55
242-
235+
+     * nt!IopSynchronousServiceTail+0x34c
243-
236+
+     * nt!IopXxxControlFile+0xd13
244-
237+
+     * nt!NtDeviceIoControlFile+0x56
245-
238+
+     * nt!KiSystemServiceCopyEnd+0x25
246-
239+
+     * ntdll!NtDeviceIoControlFile+0x14
247-
240+
+     * KERNELBASE!DeviceIoControl+0x6b
248-
241+
+     * KERNEL32!DeviceIoControlImplementation+0x81
249-
242+
+     * nfsd_debug+0xc7b14
250-
243+
+     * nfsd_debug+0xc79fb
251-
244+
+     * nfsd_debug+0x171e80
252-
245+
+     * KERNEL32!BaseThreadInitThunk+0x14
253-
246+
+     * ntdll!RtlUserThreadStart+0x21
254-
247+
+     * ---- snip ----
255-
248+
+     */
256-
249+
+    __try {
257-
250+
+        status = SeImpersonateClientEx(entry->psec_ctx, NULL);
258-
251+
+    } __except(EXCEPTION_EXECUTE_HANDLER) {
259-
252+
+        NTSTATUS code;
260-
253+
+        code = GetExceptionCode();
261-
254+
+        print_error("handle_upcall: Call to SeImpersonateClientEx() "
262-
255+
+            "failed due to exception 0x%0x\n", (int)code);
263-
256+
+        status = STATUS_INTERNAL_ERROR;
264-
257+
+    }
265-
258+
+#else
266-
259+
     status = SeImpersonateClientEx(entry->psec_ctx, NULL);
267-
260+
+#endif /* NFS41_DRIVER_STABILITY_HACKS */
268-
261+
     if (status != STATUS_SUCCESS) {
269-
262+
         print_error("SeImpersonateClientEx failed %x\n", status);
270-
263+
         goto out;
271264

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at