pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


nfs41_writeonly_experiments20260218.diff
Posted by Anonymous on Wed 18th Feb 2026 16:25
raw | new post

  1. diff --git a/daemon/setattr.c b/daemon/setattr.c
  2. index 3c01a47..4ba0789 100644
  3. --- a/daemon/setattr.c
  4. +++ b/daemon/setattr.c
  5. @@ -32,7 +32,10 @@
  6.  #undef _malloca
  7.  #endif /* _DEBUG */
  8.  #include <strsafe.h>
  9. -
  10. +
  11. +#include <devioctl.h>
  12. +#include "nfs41_driver.h" /* for |mark_filename_as_stale()| */
  13. +
  14.  #include "nfs41_build_features.h"
  15.  #include "from_kernel.h"
  16.  #include "nfs41_ops.h"
  17. @@ -335,6 +338,44 @@ static int is_dst_name_opened(nfs41_abs_path *dst_path, nfs41_session *dst_sessi
  18.      return status;
  19.  }
  20.  
  21. +static int mark_filename_as_stale(
  22. +    IN nfs41_open_state *srcfile_state,
  23. +    IN nfs41_abs_path *dst_path)
  24. +{
  25. +    if (srcfile_state->srv_open == NULL) {
  26. +        eprintf("mark_filename_as_stale: srcfile_state->srv_open == NULL\n");
  27. +        return ERROR_INVALID_PARAMETER;
  28. +    }
  29. +
  30. +    /* make an upcall to the kernel: invalide data cache */
  31. +    HANDLE pipe;
  32. +    unsigned char inbuf[sizeof(HANDLE)+4096], *buffer = inbuf;
  33. +    DWORD inbuf_len = sizeof(HANDLE)+sizeof(DWORD)+dst_path->len, outbuf_len, dstatus;
  34. +    uint32_t length;
  35. +
  36. +    pipe = create_nfs41sys_device_pipe();
  37. +    if (pipe == INVALID_HANDLE_VALUE) {
  38. +        eprintf("mark_filename_as_stale: "
  39. +            "Unable to open downcall pipe, lasterr=%d\n",
  40. +            (int)GetLastError());
  41. +        return ERROR_INVALID_PARAMETER;
  42. +    }
  43. +    length = inbuf_len;
  44. +    DWORD dst_path_len = dst_path->len;
  45. +
  46. +    safe_write(&buffer, &length, &srcfile_state->srv_open, sizeof(HANDLE));
  47. +    safe_write(&buffer, &length, &dst_path_len, sizeof(DWORD));
  48. +    safe_write(&buffer, &length, dst_path->path, dst_path_len);
  49. +
  50. +    dstatus = DeviceIoControl(pipe, IOCTL_NFS41_SET_STALE, inbuf, inbuf_len,
  51. +        NULL, 0, (LPDWORD)&outbuf_len, NULL);
  52. +    if (!dstatus)
  53. +        eprintf("IOCTL_NFS41_SET_STALE failed %d\n", (int)GetLastError());
  54. +    close_nfs41sys_device_pipe(pipe);
  55. +
  56. +    return NO_ERROR;
  57. +}
  58. +
  59.  static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  60.  {
  61.      nfs41_open_state *state = args->state;
  62. @@ -349,6 +390,7 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  63.  #endif /* NFS41_REJECT_CYGWIN_SILLYRENAME_FOR_DIRS */
  64.      int status;
  65.  
  66. +    args->rename_stale_dst_path_overwritten = false;
  67.      src_name = &state->file.name;
  68.  
  69.      if (rename->FileNameLength == 0) {
  70. @@ -721,6 +763,16 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  71.              nfs_error_string(status)));
  72.          status = nfs_to_windows_error(status, ERROR_ACCESS_DENIED);
  73.      } else {
  74. +#if 1
  75. +        args->rename_stale_dst_path_overwritten = true;
  76. +        abs_path_copy(&args->rename_stale_dst_path, &dst_path);
  77. +#else
  78. +        /*
  79. +         * Inform the kernel that the original destnation path is now stale,
  80. +         * and cannot be used for SRVOPEN collapsing
  81. +         */
  82. +        mark_filename_as_stale(state, &dst_path);
  83. +#endif
  84.          /* rename state->path on success */
  85.          open_state_rename(state, &dst_path);
  86.      }
  87. @@ -1080,8 +1132,28 @@ static int marshall_setattr(
  88.      uint32_t *restrict length,
  89.      nfs41_upcall *restrict upcall)
  90.  {
  91. +    int status;
  92.      const setattr_upcall_args *args = &upcall->args.setattr;
  93. -    return safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
  94. +    status = safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
  95. +    if (status) goto out;
  96. +
  97. +    if (args->set_class == FileRenameInformation) {
  98. +        status = safe_write(&buffer, length,
  99. +            &args->rename_stale_dst_path_overwritten,
  100. +            sizeof(args->rename_stale_dst_path_overwritten));
  101. +        if (status) goto out;
  102. +        if (args->rename_stale_dst_path_overwritten) {
  103. +            USHORT dst_path_len = args->rename_stale_dst_path.len;
  104. +            status = safe_write(&buffer, length, &dst_path_len, sizeof(dst_path_len));
  105. +            if (status) goto out;
  106. +            status = safe_write(&buffer, length,
  107. +                &args->rename_stale_dst_path.path[0], dst_path_len);
  108. +            if (status) goto out;
  109. +        }
  110. +    }
  111. +
  112. +out:
  113. +    return status;
  114.  }
  115.  
  116.  
  117. diff --git a/daemon/upcall.h b/daemon/upcall.h
  118. index 01a84ed..c75ca62 100644
  119. --- a/daemon/upcall.h
  120. +++ b/daemon/upcall.h
  121. @@ -140,6 +140,9 @@ typedef struct __setattr_upcall_args {
  122.      uint32_t buf_len;
  123.      int set_class;
  124.      ULONGLONG ctime;
  125. +    /* Downcall info */
  126. +    BOOLEAN rename_stale_dst_path_overwritten;
  127. +    nfs41_abs_path rename_stale_dst_path;
  128.  } setattr_upcall_args;
  129.  
  130.  typedef struct __getexattr_upcall_args {
  131. diff --git a/include/nfs41_driver.h b/include/nfs41_driver.h
  132. index 12f14bf..91cf7e1 100644
  133. --- a/include/nfs41_driver.h
  134. +++ b/include/nfs41_driver.h
  135. @@ -53,6 +53,7 @@
  136.  #define IOCTL_NFS41_DELAYXID    _RDR_CTL_CODE(8, METHOD_BUFFERED)
  137.  #define IOCTL_NFS41_INVALCACHE  _RDR_CTL_CODE(9, METHOD_BUFFERED)
  138.  #define IOCTL_NFS41_SET_DAEMON_DEBUG_LEVEL  _RDR_CTL_CODE(10, METHOD_BUFFERED)
  139. +#define IOCTL_NFS41_SET_STALE   _RDR_CTL_CODE(11, METHOD_BUFFERED)
  140.  
  141.  /*
  142.   * NFS41_SYS_MAX_PATH_LEN - Maximum path length
  143. diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
  144. index 091e61a..4f92098 100644
  145. --- a/sys/nfs41sys_driver.c
  146. +++ b/sys/nfs41sys_driver.c
  147. @@ -467,6 +467,83 @@ out:
  148.      return status;
  149.  }
  150.  
  151. +NTSTATUS nfs41_set_stale(
  152. +    IN PRX_CONTEXT RxContext)
  153. +{
  154. +    PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  155. +    const unsigned char *inbuf = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
  156. +    PMRX_SRV_OPEN srv_open;
  157. +    PNET_ROOT pnet_root;
  158. +    DWORD stale_utf8filename_bytelen = 0;
  159. +    NTSTATUS status;
  160. +
  161. +    RtlCopyMemory(&srv_open, inbuf, sizeof(HANDLE));
  162. +    inbuf += sizeof(HANDLE);
  163. +
  164. +    DbgP("nfs41_set_stale: received srv_open=0x%p srcfilename='%wZ'\n",
  165. +        srv_open, srv_open->pAlreadyPrefixedName);
  166. +
  167. +#if 0
  168. +    __try {
  169. +#endif
  170. +        DbgP("nfs41_set_stale: #mark1\n");
  171. +
  172. +        pnet_root = (PNET_ROOT)srv_open->pFcb->pNetRoot;
  173. +
  174. +        DbgP("nfs41_set_stale: #mark2\n");
  175. +
  176. +        RtlCopyMemory(&stale_utf8filename_bytelen, inbuf,
  177. +            sizeof(stale_utf8filename_bytelen));
  178. +        inbuf += sizeof(stale_utf8filename_bytelen);
  179. +
  180. +        DbgP("nfs41_set_stale: #mark3\n");
  181. +
  182. +        DbgP("nfs41_set_stale: stale_utf8filename_bytelen=%ld\n",
  183. +            (long)stale_utf8filename_bytelen);
  184. +
  185. +        DbgP("nfs41_set_stale: inbuf='%.*s'\n",
  186. +            (int)stale_utf8filename_bytelen, inbuf);
  187. +
  188. +        UTF8_STRING stale_utf8filename = {
  189. +            .Length = (USHORT)stale_utf8filename_bytelen,
  190. +            .MaximumLength = (USHORT)stale_utf8filename_bytelen,
  191. +            .Buffer = (PCHAR)inbuf
  192. +        };
  193. +
  194. +        DbgP("nfs41_set_stale: #mark4\n");
  195. +
  196. +        UNICODE_STRING stale_filename;
  197. +
  198. +        status = RtlUTF8StringToUnicodeString(&stale_filename,
  199. +            &stale_utf8filename, TRUE);
  200. +        if (NT_SUCCESS(status)) {
  201. +            DbgP("nfs41_set_stale: stale_filename='%wZ'\n",
  202. +                &stale_filename);
  203. +
  204. +            nfs41_mark_file_as_non_collapsible(pnet_root,
  205. +                &stale_filename);
  206. +
  207. +            RtlFreeUnicodeString(&stale_filename);
  208. +            status = STATUS_SUCCESS;
  209. +        }
  210. +
  211. +        DbgP("nfs41_set_stale: DONE\n");
  212. +#if 0
  213. +    } __except(EXCEPTION_EXECUTE_HANDLER) {
  214. +        NTSTATUS code;
  215. +        code = GetExceptionCode();
  216. +        print_error("nfs41_set_stale: srv_open=0x%p '%wZ': "
  217. +            "exception 0x%lx\n",
  218. +            srv_open,
  219. +            srv_open->pAlreadyPrefixedName,
  220. +            (long)code);
  221. +        status = STATUS_INTERNAL_ERROR;
  222. +    }
  223. +#endif
  224. +
  225. +    return status;
  226. +}
  227. +
  228.  NTSTATUS nfs41_shutdown_daemon(
  229.      DWORD version)
  230.  {
  231. @@ -639,6 +716,9 @@ NTSTATUS nfs41_DevFcbXXXControlFile(
  232.          case IOCTL_NFS41_INVALCACHE:
  233.              status = nfs41_invalidate_cache(RxContext);
  234.              break;
  235. +        case IOCTL_NFS41_SET_STALE:
  236. +            status = nfs41_set_stale(RxContext);
  237. +            break;
  238.          case IOCTL_NFS41_READ:
  239.              status = nfs41_upcall(RxContext);
  240.              break;
  241. @@ -988,6 +1068,21 @@ NTSTATUS nfs41_IsValidDirectory (
  242.      return STATUS_SUCCESS;
  243.  }
  244.  
  245. +void nfs41_MungeBufferingIfWriteOnlyHandles(
  246. +    PMRX_SRV_OPEN srvopen,
  247. +    ULONG writeonly_srvopen_count)
  248. +{
  249. +    if (writeonly_srvopen_count != 0) {
  250. +        srvopen->BufferingFlags &=
  251. +            ~(FCB_STATE_WRITECACHING_ENABLED  |
  252. +            FCB_STATE_FILESIZECACHEING_ENABLED |
  253. +            FCB_STATE_FILETIMECACHEING_ENABLED |
  254. +            FCB_STATE_LOCK_BUFFERING_ENABLED |
  255. +            FCB_STATE_READCACHING_ENABLED |
  256. +            FCB_STATE_COLLAPSING_ENABLED);
  257. +    }
  258. +}
  259. +
  260.  NTSTATUS nfs41_ComputeNewBufferingState(
  261.      IN OUT PMRX_SRV_OPEN pSrvOpen,
  262.      IN PVOID pMRxContext,
  263. @@ -998,6 +1093,7 @@ NTSTATUS nfs41_ComputeNewBufferingState(
  264.  #ifdef DEBUG_TIME_BASED_COHERENCY
  265.      ULONG oldFlags = pSrvOpen->BufferingFlags;
  266.  #endif
  267. +    PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(pSrvOpen->pFcb);
  268.  
  269.      switch(flag) {
  270.      case DISABLE_CACHING:
  271. @@ -1031,6 +1127,9 @@ NTSTATUS nfs41_ComputeNewBufferingState(
  272.          break;
  273.      }
  274.  
  275. +    nfs41_MungeBufferingIfWriteOnlyHandles(pSrvOpen,
  276. +        nfs41_fcb->writeonly_srvopen_count);
  277. +
  278.  #ifdef DEBUG_TIME_BASED_COHERENCY
  279.      DbgP("nfs41_ComputeNewBufferingState: '%wZ' pSrvOpen 0x%p Old %08x New %08x\n",
  280.           pSrvOpen->pAlreadyPrefixedName, pSrvOpen, oldFlags,
  281. diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
  282. index 441d8f7..a43d002 100644
  283. --- a/sys/nfs41sys_driver.h
  284. +++ b/sys/nfs41sys_driver.h
  285. @@ -276,6 +276,9 @@ typedef struct _updowncall_entry {
  286.              FILE_INFORMATION_CLASS InfoClass;
  287.              PVOID buf;
  288.              ULONG buf_len;
  289. +            BOOLEAN rename_stale_dst_path_overwritten;
  290. +            USHORT rename_stale_dst_path_len;
  291. +            const void *rename_stale_dst_path_buf;
  292.          } SetFile;
  293.          struct {
  294.              DWORD mode;
  295. @@ -488,7 +491,9 @@ typedef struct _NFS41_FCB {
  296.      ULONGLONG               fsid_major, fsid_minor;
  297.      BOOLEAN                 Renamed;
  298.      BOOLEAN                 DeletePending;
  299. +    BOOLEAN                 stale;
  300.      DWORD                   mode;
  301. +    LONG                    writeonly_srvopen_count;
  302.  #ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  303.      DWORD                   owner_local_uid;       /* owner mapped into local uid */
  304.      DWORD                   owner_group_local_gid; /* owner group mapped into local gid */
  305. @@ -507,6 +512,7 @@ typedef struct _NFS41_FCB {
  306.  
  307.  typedef struct _NFS41_SRV_OPEN {
  308.      BOOLEAN         initialised;
  309. +    BOOLEAN         writeonly_srvopen;
  310.      /*
  311.       * |sec_ctx| must be per |SRV_OPEN| to handle newgrp()/|setgid()|
  312.       * support. But this only works if we prevent |SRV_OPEN| collapsing
  313. @@ -721,6 +727,9 @@ void enable_caching(
  314.  VOID nfs41_update_fcb_list(
  315.      PMRX_FCB fcb,
  316.      ULONGLONG ChangeTime);
  317. +void nfs41_MungeBufferingIfWriteOnlyHandles(
  318. +    PMRX_SRV_OPEN srvopen,
  319. +    ULONG writeonly_srvopen_count);
  320.  
  321.  /* nfs41sys_ea.c */
  322.  NTSTATUS marshal_nfs41_easet(
  323. @@ -975,15 +984,21 @@ NTSTATUS marshal_nfs41_fileset(
  324.      unsigned char *buf,
  325.      ULONG buf_len,
  326.      ULONG *len);
  327. -void unmarshal_nfs41_setattr(
  328. +void unmarshal_nfs41_getchangetime(
  329.      nfs41_updowncall_entry *cur,
  330.      PULONGLONG dest_buf,
  331.      const unsigned char *restrict *restrict buf);
  332. +void unmarshal_nfs41_setattr(
  333. +    nfs41_updowncall_entry *cur,
  334. +    const unsigned char *restrict *restrict buf);
  335.  void unmarshal_nfs41_getattr(
  336.      nfs41_updowncall_entry *cur,
  337.      const unsigned char *restrict *restrict buf);
  338.  NTSTATUS nfs41_QueryFileInformation(
  339.      IN OUT PRX_CONTEXT RxContext);
  340. +VOID nfs41_mark_file_as_non_collapsible(
  341. +    PNET_ROOT netroot,
  342. +    PUNICODE_STRING nonc_filename);
  343.  NTSTATUS nfs41_SetFileInformation(
  344.      IN OUT PRX_CONTEXT RxContext);
  345.  NTSTATUS nfs41_SetFileInformationAtCleanup(
  346. diff --git a/sys/nfs41sys_fileinfo.c b/sys/nfs41sys_fileinfo.c
  347. index b7ef8ec..a1ea0dd 100644
  348. --- a/sys/nfs41sys_fileinfo.c
  349. +++ b/sys/nfs41sys_fileinfo.c
  350. @@ -160,8 +160,14 @@ NTSTATUS marshal_nfs41_fileset(
  351.          }
  352.  #endif /* NFS41_DRIVER_STOMP_CYGWIN_SILLYRENAME_INVALID_UTF16_SEQUENCE_SUPPORT */
  353.  
  354. +        /*
  355. +         * We use %lu here for |ReplaceIfExists| because of
  356. +         * |FileRenameInformationEx| uses a ULONG flags field
  357. +         */
  358.          DbgP("marshal_nfs41_fileset: "
  359. -            "FILE_RENAME_INFORMATION.(FileNameLength=%d FileName='%.*ls')\n",
  360. +            "FILE_RENAME_INFORMATION."
  361. +            "(ReplaceIfExists=%lu FileNameLength=%d FileName='%.*ls')\n",
  362. +            (unsigned long)fri->ReplaceIfExists,
  363.              (int)fri->FileNameLength,
  364.              (int)(fri->FileNameLength/sizeof(wchar_t)), fri->FileName);
  365.      }
  366. @@ -205,7 +211,7 @@ out:
  367.      return status;
  368.  }
  369.  
  370. -void unmarshal_nfs41_setattr(
  371. +void unmarshal_nfs41_getchangetime(
  372.      nfs41_updowncall_entry *cur,
  373.      PULONGLONG dest_buf,
  374.      const unsigned char *restrict *restrict buf)
  375. @@ -213,10 +219,38 @@ void unmarshal_nfs41_setattr(
  376.      RtlCopyMemory(dest_buf, *buf, sizeof(*dest_buf));
  377.      *buf += sizeof(*dest_buf);
  378.  #ifdef DEBUG_MARSHAL_DETAIL
  379. -    DbgP("unmarshal_nfs41_setattr: returned ChangeTime %llu\n", *dest_buf);
  380. +    DbgP("unmarshal_nfs41_getchangetime: returned ChangeTime %llu\n", *dest_buf);
  381.  #endif
  382.  }
  383.  
  384. +void unmarshal_nfs41_setattr(
  385. +    nfs41_updowncall_entry *cur,
  386. +    const unsigned char *restrict *restrict buf)
  387. +{
  388. +    RtlCopyMemory(&cur->ChangeTime, *buf, sizeof(cur->ChangeTime));
  389. +    *buf += sizeof(cur->ChangeTime);
  390. +
  391. +    if (cur->u.SetFile.InfoClass == FileRenameInformation) {
  392. +        RtlCopyMemory(&cur->u.SetFile.rename_stale_dst_path_overwritten,
  393. +            *buf, sizeof(cur->u.SetFile.rename_stale_dst_path_overwritten));
  394. +        *buf += sizeof(cur->u.SetFile.rename_stale_dst_path_overwritten);
  395. +
  396. +        if (cur->u.SetFile.rename_stale_dst_path_overwritten) {
  397. +            RtlCopyMemory(&cur->u.SetFile.rename_stale_dst_path_len,
  398. +                *buf, sizeof(cur->u.SetFile.rename_stale_dst_path_len));
  399. +            *buf += sizeof(cur->u.SetFile.rename_stale_dst_path_len);
  400. +
  401. +            cur->u.SetFile.rename_stale_dst_path_buf = *buf;
  402. +            *buf += cur->u.SetFile.rename_stale_dst_path_len;
  403. +            
  404. +            if (((char *)cur->u.SetFile.rename_stale_dst_path_buf)[cur->u.SetFile.rename_stale_dst_path_len-1] == '\0') {
  405. +                DbgP("unmarshal_nfs41_setattr: fixing rename_stale_dst_path_len\n");
  406. +                cur->u.SetFile.rename_stale_dst_path_len--;
  407. +            }
  408. +        }
  409. +    }
  410. +}
  411. +
  412.  void unmarshal_nfs41_getattr(
  413.      nfs41_updowncall_entry *cur,
  414.      const unsigned char *restrict *restrict buf)
  415. @@ -737,6 +771,68 @@ out:
  416.      return status;
  417.  }
  418.  
  419. +VOID nfs41_mark_file_as_non_collapsible(
  420. +    PNET_ROOT netroot,
  421. +    PUNICODE_STRING nonc_filename)
  422. +{
  423. +    PFCB fcb;
  424. +//    bool is_locked;
  425. +
  426. +    DbgP("nfs41_mark_file_as_non_collapsible: "
  427. +        "argument filename='%wZ'\n",
  428. +        nonc_filename);
  429. +#if 0
  430. +    is_locked = RxIsFcbTableLockAcquired(&netroot->FcbTable);
  431. +
  432. +    DbgP("nfs41_mark_file_as_non_collapsible: "
  433. +        "is_locked=%dm shared=%ld, exclusive=%ld\n", (int)is_locked,
  434. +        (long)ExIsResourceAcquiredSharedLite(&netroot->FcbTable.TableLock),
  435. +        (long)ExIsResourceAcquiredExclusiveLite(&netroot->FcbTable.TableLock));
  436. +#endif
  437. +
  438. +#if 1
  439. +    RxAcquireFcbTableLockExclusive(&netroot->FcbTable, TRUE);
  440. +#else
  441. +//    RxAcquireFcbTableLockShared(&netroot->FcbTable, TRUE);
  442. +    if (is_locked == false)
  443. +        RxAcquireFcbTableLockExclusive(&netroot->FcbTable, TRUE);
  444. +#endif
  445. +    DbgP("nfs41_mark_file_as_non_collapsible: #mark X1\n");
  446. +
  447. +    fcb = RxFcbTableLookupFcb(&netroot->FcbTable, nonc_filename);
  448. +
  449. +    DbgP("nfs41_mark_file_as_non_collapsible: #mark X2, fcb=0x%p\n",
  450. +        (void *)fcb);
  451. +
  452. +#if 1
  453. +    RxReleaseFcbTableLock(&netroot->FcbTable);
  454. +#else
  455. +    if (is_locked == false)
  456. +        RxReleaseFcbTableLock(&netroot->FcbTable);
  457. +#endif
  458. +
  459. +    DbgP("nfs41_mark_file_as_non_collapsible: #mark X3\n");
  460. +
  461. +    if (fcb) {
  462. +        PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(fcb);
  463. +
  464. +        DbgP("nfs41_mark_file_as_non_collapsible: #mark X4\n");
  465. +
  466. +        nfs41_fcb->stale = TRUE;
  467. +
  468. +        RxpDereferenceNetFcb(fcb);
  469. +
  470. +        DbgP("nfs41_mark_file_as_non_collapsible: "
  471. +            "marking filename='%wZ' as stale\n",
  472. +            nonc_filename);
  473. +    }
  474. +    else {
  475. +        DbgP("nfs41_mark_file_as_non_collapsible: "
  476. +            "nothing found for filename='%wZ'\n",
  477. +            nonc_filename);
  478. +    }
  479. +}
  480. +
  481.  static
  482.  NTSTATUS nfs41_SetFileInformationImpl(
  483.      IN OUT PRX_CONTEXT RxContext,
  484. @@ -765,7 +861,7 @@ NTSTATUS nfs41_SetFileInformationImpl(
  485.      DbgEn();
  486.      print_debug_filedirquery_header(RxContext);
  487.  #endif
  488. -    FsRtlEnterFileSystem();
  489. +//    FsRtlEnterFileSystem();
  490.  
  491.      status = check_nfs41_setattr_args(RxContext);
  492.      if (status) goto out;
  493. @@ -858,6 +954,8 @@ NTSTATUS nfs41_SetFileInformationImpl(
  494.                  status = STATUS_SUCCESS;
  495.                  goto out;
  496.              }
  497. +
  498. +            (void)RxFlushFcbInSystemCache((PFCB)RxContext->pFcb, TRUE);
  499.          }
  500.      }
  501.  
  502. @@ -902,6 +1000,68 @@ NTSTATUS nfs41_SetFileInformationImpl(
  503.                  (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
  504.              nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
  505.          nfs41_fcb->changeattr = entry->ChangeTime;
  506. +
  507. +#if 1
  508. +        if (RxContext->Info.FileInformationClass == FileRenameInformation) {
  509. +            DbgP("marshal_nfs41_fileset: "
  510. +                "finishig FileRenameInformation for filename='%wZ', "
  511. +                "rename_stale_dst_path_overwritten=%d\n",
  512. +                entry->filename,
  513. +                (int)entry->u.SetFile.rename_stale_dst_path_overwritten);
  514. +
  515. +            if (entry->u.SetFile.rename_stale_dst_path_overwritten) {
  516. +                DbgP("nfs41_set_stale: rename_stale_dst_path_len=%d inbuf='%.*s'\n",
  517. +                    (int)entry->u.SetFile.rename_stale_dst_path_len,
  518. +                    (int)entry->u.SetFile.rename_stale_dst_path_len,
  519. +                    entry->u.SetFile.rename_stale_dst_path_buf);
  520. +                UTF8_STRING stale_utf8filename = {
  521. +                    .Length = (USHORT)entry->u.SetFile.rename_stale_dst_path_len,
  522. +                    .MaximumLength = (USHORT)entry->u.SetFile.rename_stale_dst_path_len,
  523. +                    .Buffer = (PCHAR)entry->u.SetFile.rename_stale_dst_path_buf
  524. +                };
  525. +
  526. +                DbgP("marshal_nfs41_fileset/stale: #mark4\n");
  527. +
  528. +                UNICODE_STRING stale_filename;
  529. +
  530. +                status = RtlUTF8StringToUnicodeString(&stale_filename,
  531. +                    &stale_utf8filename, TRUE);
  532. +                if (NT_SUCCESS(status)) {
  533. +                    DbgP("marshal_nfs41_fileset/stale: stale_filename='%wZ'\n",
  534. +                        &stale_filename);
  535. +#if 1
  536. +                    nfs41_mark_file_as_non_collapsible(
  537. +                        (PNET_ROOT)SrvOpen->pVNetRoot->pNetRoot,
  538. +                        &stale_filename);
  539. +#endif
  540. +                    RtlFreeUnicodeString(&stale_filename);
  541. +                    status = STATUS_SUCCESS;
  542. +                }
  543. +
  544. +                DbgP("marshal_nfs41_fileset/stale: DONE\n");
  545. +            }
  546. +        }
  547. +#endif
  548. +#if 0 /* old */
  549. +        if (RxContext->Info.FileInformationClass == FileRenameInformation) {
  550. +            DbgP("marshal_nfs41_fileset: "
  551. +                "setting SRVOPEN_FLAG_FILE_RENAMED for filename='%wZ'\n",
  552. +                entry->filename);
  553. +            SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED);
  554. +
  555. +            PFILE_RENAME_INFORMATION prinfo =
  556. +                (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
  557. +            UNICODE_STRING ren_dst = {
  558. +                .Length = (USHORT)prinfo->FileNameLength,
  559. +                .MaximumLength = (USHORT)prinfo->FileNameLength,
  560. +                .Buffer = prinfo->FileName
  561. +            };
  562. +            nfs41_mark_file_as_non_collapsible((PNET_ROOT)SrvOpen->pVNetRoot->pNetRoot, &ren_dst);
  563. +            DbgP("marshal_nfs41_fileset: "
  564. +                "DONE setting SRVOPEN_FLAG_FILE_RENAMED for filename='%wZ'\n",
  565. +                entry->filename);
  566. +        }
  567. +#endif
  568.      }
  569.  out:
  570.      if (entry) {
  571. @@ -916,7 +1076,7 @@ out:
  572.          t2.QuadPart - t1.QuadPart, setattr.tops, setattr.ticks);
  573.  #endif
  574.  #endif
  575. -    FsRtlExitFileSystem();
  576. +//    FsRtlExitFileSystem();
  577.  #ifdef DEBUG_FILE_SET
  578.      DbgEx();
  579.  #endif
  580. diff --git a/sys/nfs41sys_mount.c b/sys/nfs41sys_mount.c
  581. index ba2effa..502182a 100644
  582. --- a/sys/nfs41sys_mount.c
  583. +++ b/sys/nfs41sys_mount.c
  584. @@ -943,6 +943,8 @@ NTSTATUS nfs41_CreateVNetRoot(
  585.          goto out;
  586.      }
  587.  
  588. +    ((PNET_ROOT)pNetRoot)->FcbTable.CaseInsensitiveMatch = FALSE;
  589. +
  590.      pVNetRootContext->session = INVALID_HANDLE_VALUE;
  591.  
  592.      /*
  593. diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
  594. index eaf04f0..cddaab8 100644
  595. --- a/sys/nfs41sys_openclose.c
  596. +++ b/sys/nfs41sys_openclose.c
  597. @@ -1229,6 +1229,7 @@ retry_on_link:
  598.              DbgP("nfs41_Create: write-only handle for file '%wZ', "
  599.                  "setting SRVOPEN_FLAG_DONTUSE_WRITE_CACHING\n",
  600.                  SrvOpen->pAlreadyPrefixedName);
  601. +            nfs41_srvopen->writeonly_srvopen = TRUE;
  602.          }
  603.  
  604.          if (!(params->CreateOptions & FILE_WRITE_THROUGH) &&
  605. @@ -1321,6 +1322,14 @@ out:
  606.              nfs41_srvopen->sec_ctx.ClientToken = NULL;
  607.          }
  608.      }
  609. +    else {
  610. +        /* Success! */
  611. +        if (nfs41_srvopen->writeonly_srvopen)
  612. +            nfs41_fcb->writeonly_srvopen_count++;
  613. +
  614. +        nfs41_MungeBufferingIfWriteOnlyHandles(SrvOpen,
  615. +            nfs41_fcb->writeonly_srvopen_count);
  616. +    }
  617.  
  618.      if (fcb_locked_exclusive) {
  619.          RxReleaseFcbResourceInMRx(Fcb);
  620. @@ -1385,6 +1394,28 @@ NTSTATUS nfs41_ShouldTryToCollapseThisOpen(
  621.          goto out;
  622.      }
  623.  
  624. +    if (nfs41_fcb->Renamed) {
  625. +        DbgP("nfs41_ShouldTryToCollapseThisOpen: filename='%wZ' nfs41_fcb->Renamed set, cannot collapse\n",
  626. +            SrvOpen->pAlreadyPrefixedName);
  627. +        status = STATUS_MORE_PROCESSING_REQUIRED;
  628. +        goto out;
  629. +    }
  630. +
  631. +    if (nfs41_fcb->stale) {
  632. +        DbgP("nfs41_ShouldTryToCollapseThisOpen: filename='%wZ' nfs41_fcb->stale set, cannot collapse\n",
  633. +            SrvOpen->pAlreadyPrefixedName);
  634. +        status = STATUS_MORE_PROCESSING_REQUIRED;
  635. +        goto out;
  636. +    }
  637. +
  638. +    if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED)) {
  639. +        DbgP("nfs41_ShouldTryToCollapseThisOpen: filename='%wZ' renamed, cannot collapse\n",
  640. +            SrvOpen->pAlreadyPrefixedName);
  641. +        status = STATUS_MORE_PROCESSING_REQUIRED;
  642. +        goto out;
  643. +    }
  644. +
  645. +
  646.  #ifdef WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER
  647.      /*
  648.       * Reject srvopens if the primary group used to create
  649. @@ -1643,6 +1674,13 @@ NTSTATUS nfs41_CloseSrvOpen(
  650.      status = map_close_errors(entry->status);
  651.  
  652.  out:
  653. +    if (status == 0) {
  654. +        /* Success! */
  655. +
  656. +        if (nfs41_srvopen->writeonly_srvopen)
  657. +            nfs41_fcb->writeonly_srvopen_count--;
  658. +    }
  659. +
  660.      if (entry) {
  661.          nfs41_UpcallDestroy(entry);
  662.      }
  663. diff --git a/sys/nfs41sys_updowncall.c b/sys/nfs41sys_updowncall.c
  664. index 15f948c..3c5ea62 100644
  665. --- a/sys/nfs41sys_updowncall.c
  666. +++ b/sys/nfs41sys_updowncall.c
  667. @@ -773,13 +773,13 @@ NTSTATUS nfs41_downcall(
  668.              break;
  669.          case NFS41_SYSOP_FILE_SET:
  670.          case NFS41_SYSOP_FILE_SET_AT_CLEANUP:
  671. -            unmarshal_nfs41_setattr(cur, &cur->ChangeTime, &inbuf);
  672. +            unmarshal_nfs41_setattr(cur, &inbuf);
  673.              break;
  674.          case NFS41_SYSOP_EA_SET:
  675. -            unmarshal_nfs41_setattr(cur, &cur->ChangeTime, &inbuf);
  676. +            unmarshal_nfs41_getchangetime(cur, &cur->ChangeTime, &inbuf);
  677.              break;
  678.          case NFS41_SYSOP_ACL_SET:
  679. -            unmarshal_nfs41_setattr(cur, &cur->ChangeTime, &inbuf);
  680. +            unmarshal_nfs41_getchangetime(cur, &cur->ChangeTime, &inbuf);
  681.              break;
  682.          case NFS41_SYSOP_FSCTL_QUERYALLOCATEDRANGES:
  683.              unmarshal_nfs41_queryallocatedranges(cur, &inbuf);

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