pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


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)

  1. diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c
  2. index 9941ce2..f7b521b 100644
  3. --- a/daemon/daemon_debug.c
  4. +++ b/daemon/daemon_debug.c
  5. @@ -802,3 +802,63 @@ void print_nfs41_file_info(
  6.  
  7.      dprintf_out("%s={ %s }\n", label, buf);
  8.  }
  9. +
  10. +#define NUM_RECENTLY_DELETED 64
  11. +static struct
  12. +{
  13. +    SRWLOCK lock;
  14. +    void *deleted_ptrs[NUM_RECENTLY_DELETED];
  15. +    size_t deleted_index;
  16. +} ptr_recently_deleted_data = {
  17. +    .lock = SRWLOCK_INIT,
  18. +};
  19. +
  20. +bool debug_ptr_was_recently_deleted(void *in_ptr)
  21. +{
  22. +    size_t i;
  23. +    bool_t res = false;
  24. +
  25. +    AcquireSRWLockShared(&ptr_recently_deleted_data.lock);
  26. +    for (i=0 ; i < NUM_RECENTLY_DELETED ; i++) {
  27. +        if (ptr_recently_deleted_data.deleted_ptrs[i] == in_ptr) {
  28. +            res = true;
  29. +            break;
  30. +        }
  31. +    }
  32. +    ReleaseSRWLockShared(&ptr_recently_deleted_data.lock);
  33. +    return res;
  34. +}
  35. +
  36. +void debug_ptr_add_recently_deleted(void *in_ptr)
  37. +{
  38. +    size_t i;
  39. +
  40. +    AcquireSRWLockExclusive(&ptr_recently_deleted_data.lock);
  41. +    i = ptr_recently_deleted_data.deleted_index++ % NUM_RECENTLY_DELETED;
  42. +    ptr_recently_deleted_data.deleted_ptrs[i] = in_ptr;
  43. +    ReleaseSRWLockExclusive(&ptr_recently_deleted_data.lock);
  44. +}
  45. +
  46. +#define NUM_DELAY_FREE 2048
  47. +static struct
  48. +{
  49. +    SRWLOCK lock;
  50. +    void *free_ptrs[NUM_DELAY_FREE];
  51. +    size_t free_ptrs_index;
  52. +} debug_delay_free_data = {
  53. +    .lock = SRWLOCK_INIT,
  54. +};
  55. +
  56. +void debug_delayed_free(void *in_ptr)
  57. +{
  58. +    size_t i;
  59. +
  60. +    AcquireSRWLockExclusive(&debug_delay_free_data.lock);
  61. +    i = debug_delay_free_data.free_ptrs_index++ % NUM_DELAY_FREE;
  62. +
  63. +    if (debug_delay_free_data.free_ptrs[i])
  64. +        free(debug_delay_free_data.free_ptrs[i]);
  65. +
  66. +    debug_delay_free_data.free_ptrs[i] = in_ptr;
  67. +    ReleaseSRWLockExclusive(&debug_delay_free_data.lock);
  68. +}
  69. diff --git a/daemon/daemon_debug.h b/daemon/daemon_debug.h
  70. index 1b693e3..2bb42b6 100644
  71. --- a/daemon/daemon_debug.h
  72. +++ b/daemon/daemon_debug.h
  73. @@ -31,6 +31,7 @@
  74.  #else
  75.  # include <stdlib.h>
  76.  #endif
  77. +#include <stdbool.h>
  78.  
  79.  #define DEFAULT_DEBUG_LEVEL 1
  80.  
  81. @@ -118,4 +119,9 @@ const char* pnfs_iomode_string(enum pnfs_iomode iomode);
  82.  void dprint_layout(int level, const struct __pnfs_file_layout *layout);
  83.  void dprint_device(int level, const struct __pnfs_file_device *device);
  84.  
  85. +bool debug_ptr_was_recently_deleted(void *in_ptr);
  86. +void debug_ptr_add_recently_deleted(void *in_ptr);
  87. +
  88. +void debug_delayed_free(void *in_ptr);
  89. +
  90.  #endif
  91. diff --git a/daemon/getattr.c b/daemon/getattr.c
  92. index 3c69db3..9d8db95 100644
  93. --- a/daemon/getattr.c
  94. +++ b/daemon/getattr.c
  95. @@ -68,6 +68,13 @@ static int parse_getattr(unsigned char *buffer, uint32_t length, nfs41_upcall *u
  96.          goto out;
  97.      }
  98.  
  99. +    if (debug_ptr_was_recently_deleted(upcall->state_ref)) {
  100. +        eprintf("parse_getattr: upcall->state_ref(=0x%p) was "
  101. +            "recently deleted\n", upcall->state_ref);
  102. +        status = ERROR_INVALID_PARAMETER;
  103. +        goto out;
  104. +    }
  105. +
  106.      EASSERT_IS_VALID_NON_NULL_PTR(upcall->state_ref);
  107.      if (!DEBUG_IS_VALID_NON_NULL_PTR(upcall->state_ref)) {
  108.          status = ERROR_INVALID_PARAMETER;
  109. diff --git a/daemon/nfs41.h b/daemon/nfs41.h
  110. index c8216dd..698e970 100644
  111. --- a/daemon/nfs41.h
  112. +++ b/daemon/nfs41.h
  113. @@ -84,7 +84,7 @@ typedef struct __nfs41_server {
  114.      nfs41_superblock_list superblocks;
  115.      struct nfs41_name_cache *name_cache;
  116.      struct list_entry entry; /* position in global server list */
  117. -    LONG ref_count;
  118. +    __declspec(align(8)) volatile LONG ref_count;
  119.  } nfs41_server;
  120.  
  121.  enum delegation_status {
  122. @@ -99,7 +99,7 @@ typedef struct __nfs41_delegation_state {
  123.      nfs41_path_fh parent;
  124.      nfs41_path_fh file;
  125.      struct list_entry client_entry; /* entry in nfs41_client.delegations */
  126. -    LONG ref_count;
  127. +    __declspec(align(8)) volatile LONG ref_count;
  128.  
  129.      enum delegation_status status;
  130.      SRWLOCK lock;
  131. @@ -138,7 +138,7 @@ typedef struct __nfs41_open_state {
  132.      struct __pnfs_layout_state *layout;
  133.      struct list_entry client_entry; /* entry in nfs41_client.opens */
  134.      SRWLOCK lock;
  135. -    LONG ref_count;
  136. +    __declspec(align(8)) volatile LONG ref_count;
  137.      uint32_t share_access;
  138.      uint32_t share_deny;
  139.      uint64_t pnfs_last_offset; /* for layoutcommit */
  140. @@ -296,7 +296,7 @@ typedef struct __nfs41_root {
  141.      struct list_entry clients;
  142.      uint32_t wsize;
  143.      uint32_t rsize;
  144. -    LONG ref_count;
  145. +    __declspec(align(8)) volatile LONG ref_count;
  146.      uint32_t uid;
  147.      uint32_t gid;
  148.      DWORD sec_flavor;
  149. diff --git a/daemon/open.c b/daemon/open.c
  150. index 0732aa2..3f1e516 100644
  151. --- a/daemon/open.c
  152. +++ b/daemon/open.c
  153. @@ -86,6 +86,10 @@ static void open_state_free(
  154.  {
  155.      struct list_entry *entry, *tmp;
  156.  
  157. +#ifdef NFS41_DRIVER_STABILITY_HACKS
  158. +    debug_ptr_add_recently_deleted(state);
  159. +#endif /* NFS41_DRIVER_STABILITY_HACKS */
  160. +
  161.      EASSERT(waitcriticalsection(&state->ea.lock) == TRUE);
  162.      EASSERT(waitcriticalsection(&state->locks.lock) == TRUE);
  163.  
  164. @@ -105,10 +109,14 @@ static void open_state_free(
  165.  
  166.      EASSERT(state->ref_count == 0);
  167.  
  168. +#ifdef NFS41_DRIVER_STABILITY_HACKS
  169. +    (void)memset(state, 0, sizeof(nfs41_open_state));
  170. +    debug_delayed_free(state);
  171. +#else
  172.      free(state);
  173. +#endif /* NFS41_DRIVER_STABILITY_HACKS */
  174.  }
  175.  
  176. -
  177.  /* open state reference counting */
  178.  void nfs41_open_state_ref(
  179.      IN nfs41_open_state *state)
  180. diff --git a/daemon/upcall.c b/daemon/upcall.c
  181. index 3a7047b..b35a8f9 100644
  182. --- a/daemon/upcall.c
  183. +++ b/daemon/upcall.c
  184. @@ -115,6 +115,18 @@ int upcall_parse(
  185.          eprintf("unrecognized upcall opcode %d!\n", upcall->opcode);
  186.          goto out;
  187.      }
  188. +
  189. +#ifdef NFS41_DRIVER_STABILITY_HACKS
  190. +    if (upcall->state_ref != INVALID_HANDLE_VALUE) {
  191. +        if (upcall->state_ref->ref_count == 0) {
  192. +            eprintf("upcall->state_ref(=0x%p).ref_count == 0, "
  193. +                "opcode %d!\n", upcall->state_ref, upcall->opcode);
  194. +            status = ERROR_INTERNAL_ERROR;
  195. +            goto out;
  196. +        }
  197. +    }
  198. +#endif
  199. +
  200.      if (upcall->root_ref != INVALID_HANDLE_VALUE)
  201.          nfs41_root_ref(upcall->root_ref);
  202.      if (upcall->state_ref != INVALID_HANDLE_VALUE)
  203. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  204. index 52c633c..99e4187 100644
  205. --- a/sys/nfs41_driver.c
  206. +++ b/sys/nfs41_driver.c
  207. @@ -1364,7 +1364,56 @@ NTSTATUS handle_upcall(
  208.      ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
  209.      unsigned char *pbOut = LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
  210.  
  211. +#ifdef NFS41_DRIVER_STABILITY_HACKS
  212. +    /*
  213. +     * Workaround for random crashes like this while compiling
  214. +     * the "gcc" compiler with a highly-parallel build.
  215. +     * Stack trace usually looks like this:
  216. +     * ---- snip ----
  217. +     * nt!SeTokenCanImpersonate+0x47
  218. +     * nt!PsImpersonateClient+0x126
  219. +     * nt!SeImpersonateClientEx+0x35
  220. +     * nfs41_driver!handle_upcall+0x59 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1367]
  221. +     * nfs41_driver!nfs41_upcall+0xe7 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1578]
  222. +     * nfs41_driver!nfs41_DevFcbXXXControlFile+0x128 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 2418]
  223. +     * nfs41_driver!RxXXXControlFileCallthru+0x76 [base\fs\rdr2\rdbss\ntdevfcb.c @ 130]
  224. +     * nfs41_driver!RxCommonDevFCBIoCtl+0x58 [base\fs\rdr2\rdbss\ntdevfcb.c @ 491]
  225. +     * nfs41_driver!RxFsdCommonDispatch+0x442 [base\fs\rdr2\rdbss\ntfsd.c @ 848]
  226. +     * nfs41_driver!RxFsdDispatch+0xfd [base\fs\rdr2\rdbss\ntfsd.c @ 442]
  227. +     * nfs41_driver!nfs41_FsdDispatch+0x67 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 6863]
  228. +     * nt!IofCallDriver+0x55
  229. +     * mup!MupiCallUncProvider+0xb8
  230. +     * mup!MupStateMachine+0x59
  231. +     * mup!MupFsdIrpPassThrough+0x17e
  232. +     * nt!IofCallDriver+0x55
  233. +     * FLTMGR!FltpDispatch+0xd6
  234. +     * nt!IofCallDriver+0x55
  235. +     * nt!IopSynchronousServiceTail+0x34c
  236. +     * nt!IopXxxControlFile+0xd13
  237. +     * nt!NtDeviceIoControlFile+0x56
  238. +     * nt!KiSystemServiceCopyEnd+0x25
  239. +     * ntdll!NtDeviceIoControlFile+0x14
  240. +     * KERNELBASE!DeviceIoControl+0x6b
  241. +     * KERNEL32!DeviceIoControlImplementation+0x81
  242. +     * nfsd_debug+0xc7b14
  243. +     * nfsd_debug+0xc79fb
  244. +     * nfsd_debug+0x171e80
  245. +     * KERNEL32!BaseThreadInitThunk+0x14
  246. +     * ntdll!RtlUserThreadStart+0x21
  247. +     * ---- snip ----
  248. +     */
  249. +    __try {
  250. +        status = SeImpersonateClientEx(entry->psec_ctx, NULL);
  251. +    } __except(EXCEPTION_EXECUTE_HANDLER) {
  252. +        NTSTATUS code;
  253. +        code = GetExceptionCode();
  254. +        print_error("handle_upcall: Call to SeImpersonateClientEx() "
  255. +            "failed due to exception 0x%0x\n", (int)code);
  256. +        status = STATUS_INTERNAL_ERROR;
  257. +    }
  258. +#else
  259.      status = SeImpersonateClientEx(entry->psec_ctx, NULL);
  260. +#endif /* NFS41_DRIVER_STABILITY_HACKS */
  261.      if (status != STATUS_SUCCESS) {
  262.          print_error("SeImpersonateClientEx failed %x\n", status);
  263.          goto out;

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