pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Patches for moving the NFS tag into UNC server part+misc, 2025-10-16
Posted by Anonymous on Thu 16th Oct 2025 20:57
raw | new post

  1. From ac2d0ed7114f93a69310bb4125d423653f35bd7f Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Tue, 14 Oct 2025 13:08:36 +0200
  4. Subject: [PATCH 1/5] dll: Add more debug output to network provider
  5.  
  6. Add more debug output to network provider.
  7.  
  8. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  9. ---
  10. dll/nfs41_np.c | 8 ++++++--
  11.  1 file changed, 6 insertions(+), 2 deletions(-)
  12.  
  13. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  14. index 37209ea..52d6e84 100644
  15. --- a/dll/nfs41_np.c
  16. +++ b/dll/nfs41_np.c
  17. @@ -1343,7 +1343,9 @@ NPGetResourceParent(
  18.      LPVOID          lpBuffer,
  19.      LPDWORD         lpBufferSize )
  20.  {
  21. -    DbgP((L"NPGetResourceParent: WN_NOT_SUPPORTED\n"));
  22. +    DbgP((L"NPGetResourceParent(pNetResource->lpRemoteName='%ls'): "
  23. +        "WN_NOT_SUPPORTED\n",
  24. +        lpNetResource->lpRemoteName));
  25.      return WN_NOT_SUPPORTED;
  26.  }
  27.  
  28. @@ -1354,7 +1356,9 @@ NPGetResourceInformation(
  29.      __inout LPDWORD lpBufferSize,
  30.      __deref_out LPWSTR *lplpSystem )
  31.  {
  32. -    DbgP((L"NPGetResourceInformation: WN_NOT_SUPPORTED\n"));
  33. +    DbgP((L"NPGetResourceInformation(lpNetResource->lpRemoteName='%ls'): "
  34. +        "WN_NOT_SUPPORTED\n",
  35. +        lpNetResource->lpRemoteName));
  36.      return WN_NOT_SUPPORTED;
  37.  }
  38.  
  39. --
  40. 2.51.0
  41.  
  42. From ac146ca60d11ab2037b5e657942b6610bb1a0469 Mon Sep 17 00:00:00 2001
  43. From: Roland Mainz <roland.mainz@nrubsig.org>
  44. Date: Thu, 16 Oct 2025 18:17:07 +0200
  45. Subject: [PATCH 2/5]
  46.  README.md,daemon,dll,docs,mount,nfs41_build_features.h,sys,tests: Move NFS
  47.  tag into UNC path server part
  48.  
  49. Move NFS tag into UNC path server part. Previously we used
  50. /nfs4/ and /pubnfs4/ subdirs in the UNC root to mark this
  51. as NFSv4 or "public NFSv4" filesystem. But this caused
  52. issues, as Windows software was not able to deal with issues that
  53. the mount points for filesystems were not in the immediate UNC
  54. root, and there was no room to store additional transport attributes,
  55. e.g. having both TLS and non-TLS mounts to the same server.
  56.  
  57. We fix these issues by putting the "NFS"/"PUBNFS" tags into the
  58. UNC server part, like Microsoft Windows WebDAV driver does it
  59. (e.g. see
  60. https://learn.microsoft.com/en-us/windows/win32/api/davclnt/nf-davclnt-davgethttpfromuncpath)
  61.  
  62. This commits marks a "flag day" (e.g. incompatibilty for existing
  63. installations), because the layout of the UNC paths changes, e.g.
  64. '\\10.49.202.230@2049\nfs4\net_tmpfs2' becomes
  65. '\\10.49.202.230@NFS@2049\net_tmpfs2'.
  66.  
  67. Reported-by: Lionel Cons <lionelcons1972@gmail.com>
  68. Reported-by: Cedric Blancher <cedric.blancher@gmail.com>
  69. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  70. ---
  71. README.md                  |  28 +++----
  72.  daemon/mount.c             |  15 +++-
  73.  dll/nfs41_np.c             |  32 +++-----
  74.  docs/README.xml            |  28 +++----
  75.  mount/enum.c               |  94 ++++++++++------------
  76.  mount/mount.c              |  23 +++---
  77.  nfs41_build_features.h     |  11 ---
  78.  sys/nfs41sys_buildconfig.h |   2 -
  79.  sys/nfs41sys_driver.c      |   6 +-
  80.  sys/nfs41sys_driver.h      |   2 -
  81.  sys/nfs41sys_mount.c       | 161 +++++++++++++++----------------------
  82.  tests/manual_testing.txt   |  24 +++---
  83.  12 files changed, 191 insertions(+), 235 deletions(-)
  84.  
  85. diff --git a/README.md b/README.md
  86. index 01cbb9f..8d34637 100644
  87. --- a/README.md
  88. +++ b/README.md
  89. @@ -85,12 +85,12 @@ NFSv4.2/NFSv4.1 filesystem driver for Windows 10/11 & Windows Server
  90.    - `/sbin/nfs_mount` prints UNC paths in Win32+Cygwin/MSYS2 formats
  91.  
  92.    - Cygwin/MSYS2 bash+ksh93 support UNC paths, e.g.,
  93. -    `cd //derfwnb4966@2049/nfs4/bigdisk/mysqldb4/`
  94. +    `cd //derfwnb4966@NFS@2049/bigdisk/mysqldb4/`
  95.  
  96.    - Symlinks on NFS can redirect to other filesystems via UNC syntax and
  97.      work with Cygwin, MSYS2, cmd.exe, powershell etc., e.g.:
  98.  
  99. -        mklink /D symlnk1_to_h_tmp \\lab17@2049\nfs4\export\home\rsm\tmp
  100. +        mklink /D symlnk1_to_h_tmp \\lab17@NFS@2049\export\home\rsm\tmp
  101.  
  102.  - WSL support
  103.  
  104. @@ -507,7 +507,7 @@ Run the NFSv4 client daemon manually:
  105.  Mount a filesystem to drive N: and use it
  106.  
  107.      $ /sbin/nfs_mount -o rw N 10.49.202.230:/net_tmpfs2
  108. -    Successfully mounted '10.49.202.230@2049' to drive 'N:'
  109. +    Successfully mounted '10.49.202.230@NFS@2049' to drive 'N:'
  110.      $ cd /cygdrive/n/
  111.      $ ls -la
  112.      total 4
  113. @@ -527,10 +527,10 @@ Unmount filesystem:
  114.  Mount a filesystem WITHOUT a dos drive assigned and use it via UNC path
  115.  
  116.      $ /sbin/nfs_mount -o rw 10.49.202.230:/net_tmpfs2
  117. -    Successfully mounted '10.49.202.230@2049' to drive '\0.49.202.230@2049\nfs4\net_tmpfs2'
  118. -    $ cygpath -u '\0.49.202.230@2049\nfs4\net_tmpfs2'
  119. -    //10.49.202.230@2049/nfs4/net_tmpfs2
  120. -    $ cd '//10.49.202.230@2049/nfs4/net_tmpfs2'
  121. +    Successfully mounted '10.49.202.230@NFS@2049' to drive '\0.49.202.230@NFS@2049\net_tmpfs2'
  122. +    $ cygpath -u '\0.49.202.230@NFS@2049\net_tmpfs2'
  123. +    //10.49.202.230@NFS@2049/net_tmpfs2
  124. +    $ cd '//10.49.202.230@NFS@2049/net_tmpfs2'
  125.      $ ls -la
  126.      total 4
  127.      drwxrwxrwt 5 Unix_User+0      Unix_Group+0      100 Dec  7 14:17 .
  128. @@ -541,10 +541,10 @@ Mount a filesystem WITHOUT a dos drive assigned and use it via UNC path
  129.  
  130.  Unmount filesystem:
  131.  
  132. -    $ cd ~ && /sbin/nfs_umount '\0.49.202.230@2049\nfs4\net_tmpfs2'
  133. +    $ cd ~ && /sbin/nfs_umount '\0.49.202.230@NFS@2049\net_tmpfs2'
  134.      # OR
  135.      $ cd ~
  136. -    $ net use '\0.49.202.230@2049\nfs4\net_tmpfs2' /delete
  137. +    $ net use '\0.49.202.230@NFS@2049\net_tmpfs2' /delete
  138.  
  139.  List mounted NFSv4.2 filesystems:
  140.  
  141. @@ -574,7 +574,7 @@ Example 1: Mount Windows NFSv4.2 share via Windows drive letter
  142.  Mount NFSv4.2 share in Windows to drive letter 'N':
  143.  
  144.      $ /sbin/nfs_mount -o rw 'N' nfs://10.49.202.230//bigdisk
  145. -    Successfully mounted '10.49.202.230@2049' to drive 'N:'
  146. +    Successfully mounted '10.49.202.230@NFS@2049' to drive 'N:'
  147.  
  148.  Within WSL mount drive letter 'N' to `/mnt/n`
  149.  
  150. @@ -587,13 +587,13 @@ Example 2: Mount Windows NFSv4.2 share via UNC path:
  151.  Mount NFSv4.2 share in Windows
  152.  
  153.      $ /sbin/nfs_mount -o rw nfs://10.49.202.230//bigdisk
  154. -    Successfully mounted '10.49.202.230@2049' to drive '\0.49.202.230@2049\nfs4\bigdisk'
  155. +    Successfully mounted '10.49.202.230@NFS@2049' to drive '\0.49.202.230@NFS@2049\bigdisk'
  156.  
  157.  Within WSL mount UNC path returned by `/sbin/nfs_mount`
  158.  
  159.      $ sudo bash
  160.      $ mkdir /mnt/bigdisk
  161. -    $ mount -t drvfs '\0.49.202.230@2049\nfs4\bigdisk' /mnt/bigdisk
  162. +    $ mount -t drvfs '\0.49.202.230@NFS@2049\bigdisk' /mnt/bigdisk
  163.  
  164.  **Known issues with WSL:**
  165.  
  166. @@ -633,7 +633,7 @@ Within WSL mount UNC path returned by `/sbin/nfs_mount`
  167.  - Cygwin/MSYS2 symlinks are supported, but might require
  168.    `$ fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1 #`.
  169.    This includes symlinks to UNC paths, e.g., as Administrator
  170. -  `$ cmd /c 'mklink /d c:\home\rmainz \\derfwpc5131_ipv6@2049\nfs4\export\home2\rmainz' #`
  171. +  `$ cmd /c 'mklink /d c:\home\rmainz \\derfwpc5131_ipv6@NFS@2049\export\home2\rmainz' #`
  172.    and then `$ cd /cygdrive/c/home/rmainz/ #` should work
  173.  
  174.  - performance: All binaries are built without any optimisation, so the
  175. @@ -771,7 +771,7 @@ Within WSL mount UNC path returned by `/sbin/nfs_mount`
  176.    Example:
  177.  
  178.        {Fehler beim verzoegerten Schreibvorgang} Nicht alle Daten fuer die
  179. -      Datei "\\34.159.25.153@2049\nfs4\export\nfs4export\gcc\lto-dump.exe"
  180. +      Datei "\\34.159.25.153@NFS@2049\exportexport\gcc\lto-dump.exe"
  181.        konnten gespeichert werden. Daten gingen verloren.
  182.        Dieser Fehler wurde von dem Server zurueckgegeben, auf dem sich die
  183.        Datei befindet. Versuchen Sie, die Datei woanders zu speichern.
  184. diff --git a/daemon/mount.c b/daemon/mount.c
  185. index 81f1b30..1fa78ec 100644
  186. --- a/daemon/mount.c
  187. +++ b/daemon/mount.c
  188. @@ -172,14 +172,25 @@ static int handle_mount(void *daemon_context, nfs41_upcall *upcall)
  189.  
  190.      (void)strcpy_s(hostname, sizeof(hostname), args->hostport);
  191.      s = strchr(hostname, '@');
  192. +    if (s) {
  193. +        char *tmps;
  194. +        *s++ = '\0';
  195. +        tmps = strchr(s, '@');
  196. +        if (tmps)
  197. +            s = tmps;
  198. +    }
  199. +
  200.      if (s) {
  201.          *s++ = '\0';
  202.         port = atoi(s);
  203.         if ((port < 1) || (port > 65535)) {
  204.              status = ERROR_BAD_ARGUMENTS;
  205. -            eprintf("handle_mount: bad port number %d specified in "
  206. +            eprintf("handle_mount: "
  207. +                "bad port number '%s' -> %d specified in "
  208.                  "hostport '%s'\n",
  209. -                port, args->hostport);
  210. +                s,
  211. +                port,
  212. +                args->hostport);
  213.              goto out;
  214.         }
  215.  
  216. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  217. index 52d6e84..d305614 100644
  218. --- a/dll/nfs41_np.c
  219. +++ b/dll/nfs41_np.c
  220. @@ -274,7 +274,8 @@ static DWORD StoreConnectionInfo(
  221.      LUID authenticationid = { .LowPart = 0, .HighPart = 0L };
  222.  #endif /* NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE */
  223.  
  224. -    DbgP((L"--> StoreConnectionInfo\n"));
  225. +    DbgP((L"--> StoreConnectionInfo(LocalName='%ls',ConnectionName='%ls')\n",
  226. +        LocalName, ConnectionName));
  227.  
  228.  #ifdef NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE
  229.      (void)get_token_authenticationid(GetCurrentThreadEffectiveToken(),
  230. @@ -603,14 +604,18 @@ NPAddConnection3(
  231.      }
  232.      ServerName[i] = L'\0';
  233.  
  234. +    /* Check for "@NFS" or "@PUBNFS" tag in UNC path */
  235. +    if ((wcsstr(ServerName, L"@NFS") == NULL) &&
  236. +        (wcsstr(ServerName, L"@PUBNFS") == NULL)) {
  237. +        DbgP((L"ServerName name '%ls' not tagged with "
  238. +            "'@NFS' or '@PUBNFS'\n",
  239. +            ServerName));
  240. +        Status = WN_BAD_NETNAME;
  241. +        goto out;
  242. +    }
  243. +
  244.      (void)StringCchCatW(ConnectionName,
  245.          NFS41_SYS_MAX_PATH_LEN, ServerName);
  246. -#ifndef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  247. -    /* insert the "nfs4" in between the server name and the path,
  248. -     * just to make sure all calls to our driver come thru this */
  249. -    (void)StringCchCatW(ConnectionName,
  250. -        NFS41_SYS_MAX_PATH_LEN, L"\\nfs4");
  251. -#endif /* NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX */
  252.  
  253.  #ifdef CONVERT_2_UNIX_SLASHES
  254.      /* convert all windows slashes to unix slashes */
  255. @@ -645,7 +650,7 @@ NPAddConnection3(
  256.       * from looking up the path from the device letter
  257.       * (e.g. device letter does not show up in /cygdrive/).
  258.       * nfsd_daemon will still see the full path with all backslashes
  259. -     * (e.g. "msg=mount(hostport='derfwnb4966_ipv4@2049',
  260. +     * (e.g. "msg=mount(hostport='derfwnb4966_ipv4@NFS@2049',
  261.       * path='\\\\\\\\\net_tmpfs2\\test2')"
  262.       */
  263.      {
  264. @@ -661,17 +666,6 @@ NPAddConnection3(
  265.      }
  266.  #endif
  267.  
  268. -#ifdef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  269. -    if (wcsncmp(&p[i], L"\\nfs4", 5) &&
  270. -        wcsncmp(&p[i], L"\\pubnfs4", 8)) {
  271. -        DbgP((L"Connection name '%ls' not prefixed with "
  272. -            "'\\nfs41' or '\\pubnfs41'\n",
  273. -            &p[i]));
  274. -        Status = WN_BAD_NETNAME;
  275. -        goto out;
  276. -    }
  277. -#endif /* NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX */
  278. -
  279.      (void)StringCchCatW(ConnectionName,
  280.          NFS41_SYS_MAX_PATH_LEN, &p[i]);
  281.      DbgP((L"Full Connect Name: '%ls'\n", ConnectionName));
  282. diff --git a/docs/README.xml b/docs/README.xml
  283. index 5830f66..a1dbd2c 100644
  284. --- a/docs/README.xml
  285. +++ b/docs/README.xml
  286. @@ -71,11 +71,11 @@
  287.                <para><filename>/sbin/nfs_mount</filename> prints UNC paths in Win32+Cygwin/MSYS2 formats</para>
  288.              </listitem>
  289.              <listitem>
  290. -              <para>Cygwin/MSYS2 bash+ksh93 support UNC paths, e.g., <command>cd //derfwnb4966@2049/nfs4/bigdisk/mysqldb4/</command></para>
  291. +              <para>Cygwin/MSYS2 bash+ksh93 support UNC paths, e.g., <command>cd //derfwnb4966@NFS@2049/bigdisk/mysqldb4/</command></para>
  292.              </listitem>
  293.              <listitem>
  294.                <para>Symlinks on NFS can redirect to other filesystems via UNC syntax and work with Cygwin, MSYS2, cmd.exe, powershell etc., e.g.:
  295. -                <programlisting>mklink /D symlnk1_to_h_tmp \\lab17@2049\nfs4\export\home\rsm\tmp</programlisting>
  296. +                <programlisting>mklink /D symlnk1_to_h_tmp \\lab17@NFS@2049\export\home\rsm\tmp</programlisting>
  297.                </para>
  298.              </listitem>
  299.            </itemizedlist>
  300. @@ -647,7 +647,7 @@ $ /sbin/msnfs41client install
  301.          <title>Basic usage</title>
  302.          <para>Mount a filesystem to drive N: and use it</para>
  303.          <programlisting>$ /sbin/nfs_mount -o rw N 10.49.202.230:/net_tmpfs2
  304. -Successfully mounted '10.49.202.230@2049' to drive 'N:'
  305. +Successfully mounted '10.49.202.230@NFS@2049' to drive 'N:'
  306.  $ cd /cygdrive/n/
  307.  $ ls -la
  308.  total 4
  309. @@ -665,10 +665,10 @@ $ net use N: /delete</programlisting>
  310.  
  311.          <para>Mount a filesystem WITHOUT a dos drive assigned and use it via UNC path</para>
  312.          <programlisting>$ /sbin/nfs_mount -o rw 10.49.202.230:/net_tmpfs2
  313. -Successfully mounted '10.49.202.230@2049' to drive '\0.49.202.230@2049\nfs4\net_tmpfs2'
  314. -$ cygpath -u '\0.49.202.230@2049\nfs4\net_tmpfs2'
  315. -//10.49.202.230@2049/nfs4/net_tmpfs2
  316. -$ cd '//10.49.202.230@2049/nfs4/net_tmpfs2'
  317. +Successfully mounted '10.49.202.230@NFS@2049' to drive '\0.49.202.230@NFS@2049\net_tmpfs2'
  318. +$ cygpath -u '\0.49.202.230@NFS@2049\net_tmpfs2'
  319. +//10.49.202.230@NFS@2049/net_tmpfs2
  320. +$ cd '//10.49.202.230@NFS@2049/net_tmpfs2'
  321.  $ ls -la
  322.  total 4
  323.  drwxrwxrwt 5 Unix_User+0      Unix_Group+0      100 Dec  7 14:17 .
  324. @@ -677,10 +677,10 @@ drwxr-xr-x 3 Unix_User+197608 Unix_Group+197121  80 Dec 12 16:24 10492030
  325.  drwxr-xr-x 3 Unix_User+197608 Unix_Group+197121  60 Dec 13 17:58 directory_t
  326.  drwxr-xr-x 3 Unix_User+197608 Unix_Group+197121  60 Dec  7 11:01 test2</programlisting>
  327.          <para>Unmount filesystem:</para>
  328. -        <programlisting>$ cd ~ &amp;&amp; /sbin/nfs_umount '\0.49.202.230@2049\nfs4\net_tmpfs2'
  329. +        <programlisting>$ cd ~ &amp;&amp; /sbin/nfs_umount '\0.49.202.230@NFS@2049\net_tmpfs2'
  330.  # OR
  331.  $ cd ~
  332. -$ net use '\0.49.202.230@2049\nfs4\net_tmpfs2' /delete</programlisting>
  333. +$ net use '\0.49.202.230@NFS@2049\net_tmpfs2' /delete</programlisting>
  334.          <para>List mounted NFSv4.2 filesystems:</para>
  335.          <programlisting>$ /sbin/nfs_mount</programlisting>
  336.        </section>
  337. @@ -704,7 +704,7 @@ sc start ms-nfs41-client-globalmountall-service</programlisting>
  338.          <para>Example 1: Mount Windows NFSv4.2 share via Windows drive letter</para>
  339.          <para>Mount NFSv4.2 share in Windows to drive letter 'N':</para>
  340.          <programlisting>$ /sbin/nfs_mount -o rw 'N' nfs://10.49.202.230//bigdisk
  341. -Successfully mounted '10.49.202.230@2049' to drive 'N:'</programlisting>
  342. +Successfully mounted '10.49.202.230@NFS@2049' to drive 'N:'</programlisting>
  343.          <para>Within WSL mount drive letter 'N' to <filename>/mnt/n</filename></para>
  344.          <programlisting>$ sudo bash
  345.  $ mkdir /mnt/n
  346. @@ -713,11 +713,11 @@ $ mount -t drvfs N: /mnt/n</programlisting>
  347.          <para>Example 2: Mount Windows NFSv4.2 share via UNC path:</para>
  348.          <para>Mount NFSv4.2 share in Windows</para>
  349.          <programlisting>$ /sbin/nfs_mount -o rw nfs://10.49.202.230//bigdisk
  350. -Successfully mounted '10.49.202.230@2049' to drive '\0.49.202.230@2049\nfs4\bigdisk'</programlisting>
  351. +Successfully mounted '10.49.202.230@NFS@2049' to drive '\0.49.202.230@NFS@2049\bigdisk'</programlisting>
  352.          <para>Within WSL mount UNC path returned by <filename>/sbin/nfs_mount</filename></para>
  353.          <programlisting>$ sudo bash
  354.  $ mkdir /mnt/bigdisk
  355. -$ mount -t drvfs '\0.49.202.230@2049\nfs4\bigdisk' /mnt/bigdisk</programlisting>
  356. +$ mount -t drvfs '\0.49.202.230@NFS@2049\bigdisk' /mnt/bigdisk</programlisting>
  357.  
  358.          <para><emphasis role="strong">Known issues with WSL:</emphasis></para>
  359.          <itemizedlist>
  360. @@ -750,7 +750,7 @@ $ mount -t drvfs '\0.49.202.230@2049\nfs4\bigdisk' /mnt/bigdisk</programlistin
  361.          </para>
  362.        </listitem>
  363.        <listitem>
  364. -        <para>Cygwin/MSYS2 symlinks are supported, but might require <command>$ fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1 #</command>. This includes symlinks to UNC paths, e.g., as Administrator <command>$ cmd /c 'mklink /d c:\home\rmainz \\derfwpc5131_ipv6@2049\nfs4\export\home2\rmainz' #</command> and then <command>$ cd /cygdrive/c/home/rmainz/ #</command> should work</para>
  365. +        <para>Cygwin/MSYS2 symlinks are supported, but might require <command>$ fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1 #</command>. This includes symlinks to UNC paths, e.g., as Administrator <command>$ cmd /c 'mklink /d c:\home\rmainz \\derfwpc5131_ipv6@NFS@2049\export\home2\rmainz' #</command> and then <command>$ cd /cygdrive/c/home/rmainz/ #</command> should work</para>
  366.        </listitem>
  367.        <listitem>
  368.          <para>performance: All binaries are built without any optimisation, so the filesystem is much slower than it could be.</para>
  369. @@ -870,7 +870,7 @@ A::EVERYONE@:rtcy</programlisting>
  370.        <listitem>
  371.          <para>Windows event log can list errors like "MUP 0xc0000222" (<literal>|STATUS_LOST_WRITEBEHIND_DATA|</literal>) in case the disk on the NFSv4 server is full and outstanding writes from a memory-mapped file fail. Example:</para>
  372.          <programlisting>{Fehler beim verzoegerten Schreibvorgang} Nicht alle Daten fuer die
  373. -Datei "\\34.159.25.153@2049\nfs4\export\nfs4export\gcc\lto-dump.exe"
  374. +Datei "\\34.159.25.153@NFS@2049\exportexport\gcc\lto-dump.exe"
  375.  konnten gespeichert werden. Daten gingen verloren.
  376.  Dieser Fehler wurde von dem Server zurueckgegeben, auf dem sich die
  377.  Datei befindet. Versuchen Sie, die Datei woanders zu speichern.</programlisting>
  378. diff --git a/mount/enum.c b/mount/enum.c
  379. index 11f8a6d..99d1be3 100644
  380. --- a/mount/enum.c
  381. +++ b/mount/enum.c
  382. @@ -1,5 +1,6 @@
  383.  /* NFSv4.1 client for Windows
  384. - * Copyright (C) 2012 The Regents of the University of Michigan
  385. + * Copyright (C) 2012 The Regents of the University of Michigan
  386. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  387.   *
  388.   * Olga Kornievskaia <aglo@umich.edu>
  389.   * Casey Bodley <cbodley@umich.edu>
  390. @@ -57,26 +58,14 @@ void PrintMountLine(
  391.      wchar_t *b;
  392.      LPCWSTR s;
  393.      wchar_t sc;
  394. -#ifndef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  395. -    unsigned int backslash_counter;
  396. -#endif
  397.      bool is_pubfh = false;
  398. +    bool found_unc_nfs_tag = false;
  399.  
  400. -    for(b = cygwin_unc_buffer, s = remote
  401. -#ifndef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  402. -     , backslash_counter = 0
  403. -#endif
  404. -     ;
  405. +    for(b = cygwin_unc_buffer, s = remote ;
  406.          (sc = *s++) != L'\0' ; ) {
  407.          switch(sc) {
  408.              case L'\\':
  409.                  *b++ = L'/';
  410. -#ifndef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  411. -                if (backslash_counter++ == 2) {
  412. -                    (void)wcscpy_s(b, 6, L"nfs4/");
  413. -                    b+=5;
  414. -                }
  415. -#endif
  416.                  break;
  417.              default:
  418.                  *b++ = sc;
  419. @@ -128,8 +117,8 @@ void PrintMountLine(
  420.  
  421.      unsigned int slash_counter = 0;
  422.      char *utf8unc = wcs2utf8str(cygwin_unc_buffer);
  423. -    if (!utf8unc)
  424. -        return;
  425. +    if (utf8unc == NULL)
  426. +        goto out;
  427.      char *utf8unc_p = utf8unc;
  428.      char *us = cygwin_nfsurl_buffer;
  429.  
  430. @@ -153,43 +142,47 @@ void PrintMountLine(
  431.              slash_counter++;
  432.  
  433.          /*
  434. -         * Skip "nfs4", but not the last '/' to make the nfs://-URL
  435. -         * an absolute URL, not a relative nfs://-URL.
  436. -         * (This assumes that all input strings have "nfs4/"!)
  437. +         * Intercept "tags" in UNC hostnames, e.g.
  438. +         * "\hostname@TAG1@TAG2@port\path"
  439.           */
  440. -        if (slash_counter == 1) {
  441. -            *us++ = uc;
  442. -            if (strncmp(utf8unc_p, "pubnfs4/", 8) == 0) {
  443. -                /*
  444. -                 * Skip "pubnfs4/", the trailing slash is skipped
  445. -                 * because public nfs://-URLs must be relative to
  446. -                 * the pubfh
  447. -                 */
  448. -                utf8unc_p += 8;
  449. -                slash_counter++;
  450. -                is_pubfh = true;
  451. -            }
  452. -            else if (strncmp(utf8unc_p, "nfs4/", 5) == 0) {
  453. -                /* Skip "nfs4" */
  454. -                utf8unc_p += 4;
  455. -            }
  456. -            else {
  457. -                (void)fwprintf(stderr,
  458. -                    L"PrintMountLine: ## Internal error, "
  459. -                    "unknown provider prefix, utf8unc_p='%s'\n",
  460. -                    utf8unc_p);
  461. -                return;
  462. +        if (uc == '@') {
  463. +            /* |slash_counter == 0| means we are processing the UNC hostname */
  464. +            if (slash_counter == 0) {
  465. +                if (found_unc_nfs_tag) {
  466. +                    /*
  467. +                     * Replace '@' for UNC port number with ':' for
  468. +                     * URL port number
  469. +                     */
  470. +                    *us++ = ':';
  471. +                    continue;
  472. +                }
  473. +                else {
  474. +                    if (strncmp(utf8unc_p, "NFS", 3) == 0) {
  475. +                        /* Skip "NFS" */
  476. +                        utf8unc_p += 3;
  477. +                        found_unc_nfs_tag = true;
  478. +                    }
  479. +                    else if (strncmp(utf8unc_p, "PUBNFS", 6) == 0) {
  480. +                        /* Skip "PUBNFS" */
  481. +                        utf8unc_p += 6;
  482. +                        is_pubfh = true;
  483. +                        found_unc_nfs_tag = true;
  484. +                    }
  485. +                    else {
  486. +                        (void)fwprintf(stderr,
  487. +                            L"PrintMountLine: ## Internal error, "
  488. +                            "unknown UNC tag, utf8unc_p='%s'\n",
  489. +                            utf8unc_p);
  490. +                        goto out;
  491. +                    }
  492. +                    continue;
  493. +                }
  494.              }
  495. -
  496. -            continue;
  497.          }
  498.  
  499. -        if ((uc == '@') && (slash_counter == 0)) {
  500. -            *us++ = ':';
  501. -        }
  502. -        else if (printURLShellSafe?
  503. -                    (ISVALIDSHELLSAFEURLCHAR(uc)):
  504. -                    (ISVALIDURLCHAR(uc))) {
  505. +        if (printURLShellSafe?
  506. +            (ISVALIDSHELLSAFEURLCHAR(uc)):
  507. +            (ISVALIDURLCHAR(uc))) {
  508.              *us++ = uc;
  509.          }
  510.          else {
  511. @@ -220,6 +213,7 @@ void PrintMountLine(
  512.      (void)wprintf(L"%-8ls\t%-50ls\t%-50ls\t%-50s\n",
  513.          local, remote, cygwin_unc_buffer, cygwin_nfsurl_buffer);
  514.  
  515. +out:
  516.      free(utf8unc);
  517.  }
  518.  
  519. diff --git a/mount/mount.c b/mount/mount.c
  520. index a5355aa..daac874 100644
  521. --- a/mount/mount.c
  522. +++ b/mount/mount.c
  523. @@ -1136,12 +1136,21 @@ static DWORD ParseRemoteName(
  524.          *   too
  525.          */
  526.          (void)swprintf(srvname, SRVNAME_LEN,
  527. -           L"%ls.ipv6-literal.net@%d", premotename, port);
  528. +            L"%ls.ipv6-literal.net@%ls@%d",
  529. +            premotename,
  530. +            (use_nfspubfh?L"PUBNFS":L"NFS"),
  531. +            port);
  532.      }
  533.      else {
  534. -        /* ALWAYS add port number to hostname, so UNC paths use it too */
  535. -        (void)swprintf(srvname, SRVNAME_LEN, L"%ls@%d",
  536. -           premotename, port);
  537. +        /*
  538. +         * ALWAYS add @NFS/@PUBNFS tag and port number to hostname, so
  539. +         * UNC paths use them too
  540. +         */
  541. +        (void)swprintf(srvname, SRVNAME_LEN,
  542. +            L"%ls@%ls@%d",
  543. +            premotename,
  544. +            (use_nfspubfh?L"PUBNFS":L"NFS"),
  545. +            port);
  546.      }
  547.  
  548.      /*
  549. @@ -1174,12 +1183,6 @@ static DWORD ParseRemoteName(
  550.      result = StringCbCatW(pConnectionName, cchConnectionLen, srvname);
  551.      if (FAILED(result))
  552.          goto out;
  553. -#ifdef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  554. -    result = StringCbCatW(pConnectionName, cchConnectionLen,
  555. -        (use_nfspubfh?(L"\\pubnfs4"):(L"\\nfs4")));
  556. -    if (FAILED(result))
  557. -        goto out;
  558. -#endif /* NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX */
  559.      if (*pEnd)
  560.          result = StringCchCatW(pConnectionName, cchConnectionLen, pEnd);
  561.  
  562. diff --git a/nfs41_build_features.h b/nfs41_build_features.h
  563. index 27cfb07..274950b 100644
  564. --- a/nfs41_build_features.h
  565. +++ b/nfs41_build_features.h
  566. @@ -53,17 +53,6 @@
  567.   */
  568.  #define NFS41_DRIVER_SID_CACHE 1
  569.  
  570. -/*
  571. - * NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX - nfs_mount.exe and
  572. - * not nfs41_np does the \nfs4 prefix between servername and path
  573. - * in UNC paths. As side-effect both normal and Windows UNC paths
  574. - * always have \nfs4 in them (e.g. \\derfwnb4966_ipv4@2049\nfs4\bigdisk
  575. - * (Windows UNC) and //derfwnb4966_ipv4@2049/nfs4/bigdisk (Cygwin UNC)
  576. - * instead of just the the Cygwin UNC paths, which constantly confuses
  577. - * users madly.
  578. - */
  579. -#define NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX 1
  580. -
  581.  /*
  582.   * NFS41_DRIVER_STABILITY_HACKS - use horrible
  583.   * hacks to improve stabilty
  584. diff --git a/sys/nfs41sys_buildconfig.h b/sys/nfs41sys_buildconfig.h
  585. index aec9c54..760f39d 100644
  586. --- a/sys/nfs41sys_buildconfig.h
  587. +++ b/sys/nfs41sys_buildconfig.h
  588. @@ -50,8 +50,6 @@
  589.  // #define LOOKASIDELISTS_STATS 1
  590.  #endif /* (NTDDI_VERSION >= NTDDI_WIN10_VB) */
  591.  
  592. -// #define USE_ENTIRE_PATH_FOR_NETROOT 1
  593. -
  594.  /* debugging printout defines */
  595.  #if defined(_DEBUG)
  596.  /* Debug build defines follow... */
  597. diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
  598. index 38cc8e3..42c1e15 100644
  599. --- a/sys/nfs41sys_driver.c
  600. +++ b/sys/nfs41sys_driver.c
  601. @@ -72,11 +72,9 @@
  602.  
  603.  /*
  604.   * In order to cooperate with other network providers,
  605. - * we only claim paths of the format '\\server\nfs4\path' or
  606. - * '\\server\pubnfs4\path'
  607. + * we only claim paths of the format '\\server@NFS@<portnum>\path'
  608. + * or '\\server@PUBNFS@<portnum>\path'
  609.   */
  610. -DECLARE_CONST_UNICODE_STRING(NfsPrefix, L"\\nfs4");
  611. -DECLARE_CONST_UNICODE_STRING(PubNfsPrefix, L"\\pubnfs4");
  612.  DECLARE_CONST_UNICODE_STRING(AUTH_NONE_NAME, L"none");
  613.  DECLARE_CONST_UNICODE_STRING(AUTH_SYS_NAME, L"sys");
  614.  DECLARE_CONST_UNICODE_STRING(AUTHGSS_KRB5_NAME, L"krb5");
  615. diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
  616. index 8061528..b984878 100644
  617. --- a/sys/nfs41sys_driver.h
  618. +++ b/sys/nfs41sys_driver.h
  619. @@ -108,8 +108,6 @@ typedef struct __nfs41_timings {
  620.  #define NFS41_MM_POOLTAG_DOWN   ('down')
  621.  
  622.  
  623. -DECLARE_EXTERN_DECLARE_CONST_UNICODE_STRING(NfsPrefix);
  624. -DECLARE_EXTERN_DECLARE_CONST_UNICODE_STRING(PubNfsPrefix);
  625.  DECLARE_EXTERN_DECLARE_CONST_UNICODE_STRING(AUTH_NONE_NAME);
  626.  DECLARE_EXTERN_DECLARE_CONST_UNICODE_STRING(AUTH_SYS_NAME);
  627.  DECLARE_EXTERN_DECLARE_CONST_UNICODE_STRING(AUTHGSS_KRB5_NAME);
  628. diff --git a/sys/nfs41sys_mount.c b/sys/nfs41sys_mount.c
  629. index 7133e72..062b076 100644
  630. --- a/sys/nfs41sys_mount.c
  631. +++ b/sys/nfs41sys_mount.c
  632. @@ -533,7 +533,7 @@ NTSTATUS nfs41_MountConfig_ParseOptions(
  633.          else if (wcsncmp(L"public", Name, NameLen) == 0) {
  634.              /*
  635.               + We ignore this value here, and instead rely on the
  636. -             * /pubnfs4 prefix
  637. +             * "@PUBNFS" tag in the UNC path
  638.               */
  639.              BOOLEAN dummy;
  640.              status = nfs41_MountConfig_ParseBoolean(Option, &usValue,
  641. @@ -776,81 +776,65 @@ release_sec_ctx:
  642.  }
  643.  
  644.  static
  645. -NTSTATUS has_nfs_prefix(
  646. +NTSTATUS netroot_has_nfs_tag(
  647.      IN PUNICODE_STRING SrvCallName,
  648.      IN PUNICODE_STRING NetRootName,
  649. -    OUT BOOLEAN *pubfh_prefix)
  650. +    OUT bool *pubfh_tag)
  651.  {
  652.      NTSTATUS status = STATUS_BAD_NETWORK_NAME;
  653.  
  654. -#ifdef USE_ENTIRE_PATH_FOR_NETROOT
  655. -    if (NetRootName->Length >=
  656. -        (SrvCallName->Length + NfsPrefix.Length)) {
  657. -        size_t len = NetRootName->Length / 2;
  658. -        size_t i;
  659. -        int state = 0;
  660. +    DbgP("netroot_has_nfs_tag: SrvCallName='%wZ' NetRootName='%wZ'\n",
  661. +        SrvCallName, NetRootName);
  662.  
  663. -        /* Scan \hostname@port\nfs4 */
  664. -        for (i = 0 ; i < len ; i++) {
  665. -            wchar_t ch = NetRootName->Buffer[i];
  666. +    size_t len = NetRootName->Length / 2;
  667. +    size_t i;
  668. +    int state = 0;
  669. +    wchar_t *nfstag = NULL;
  670.  
  671. -            if ((ch == L'\\') && (state == 0)) {
  672. -                state = 1;
  673. -                continue;
  674. -            }
  675. -            else if ((ch == L'@') && (state == 1)) {
  676. -                state = 2;
  677. -                continue;
  678. -            }
  679. -            else if ((ch == L'\\') && (state == 2)) {
  680. -                state = 3;
  681. -                break;
  682. -            }
  683. -            else if (ch == L'\\') {
  684. -                /* Abort, '\\' with wrong state */
  685. -                break;
  686. -            }
  687. -        }
  688. +    /* Scan \hostname@NFS@port\ or \hostname@PUBNFS@port\ */
  689. +    for (i = 0 ; i < len ; i++) {
  690. +        wchar_t ch = NetRootName->Buffer[i];
  691.  
  692. -        if (state == 3) {
  693. -            if (!memcmp(&NetRootName->Buffer[i], L"\\nfs4",
  694. -                (4*sizeof(wchar_t))))) {
  695. -                *pubfh_prefix = FALSE;
  696. -                status = STATUS_SUCCESS;
  697. -            }
  698. -            if ((NetRootName->Length >=
  699. -                (SrvCallName->Length + PubNfsPrefix.Length)) &&
  700. -                (!memcmp(&NetRootName->Buffer[i], L"\\pubnfs4",
  701. -                    (4*sizeof(wchar_t))))) {
  702. -                *pubfh_prefix = TRUE;
  703. -                status = STATUS_SUCCESS;
  704. +        if ((ch == L'\\') && (state == 0)) {
  705. +            state = 1;
  706. +            continue;
  707. +        }
  708. +        else if ((ch == L'@') && ((state == 1) || (state == 2))) {
  709. +            if (state == 1) {
  710. +                nfstag = &NetRootName->Buffer[i];
  711.              }
  712. +            state = 2;
  713. +            continue;
  714. +        }
  715. +        else if ((ch == L'\\') && (state == 2)) {
  716. +            state = 3;
  717. +            continue;
  718. +        }
  719. +        else if (ch == L'\\') {
  720. +            /* Abort, '\\' with wrong state */
  721. +            break;
  722. +        }
  723. +        else {
  724. +            /* Next character */
  725.          }
  726.      }
  727. -#else
  728. -    if (NetRootName->Length ==
  729. -        (SrvCallName->Length + NfsPrefix.Length)) {
  730. -        const UNICODE_STRING NetRootPrefix = {
  731. -            NfsPrefix.Length,
  732. -            NetRootName->MaximumLength - SrvCallName->Length,
  733. -            &NetRootName->Buffer[SrvCallName->Length/2]
  734. -        };
  735. -        if (!RtlCompareUnicodeString(&NetRootPrefix, &NfsPrefix, FALSE))
  736. -            *pubfh_prefix = FALSE;
  737. +
  738. +    DbgP("netroot_has_nfs_tag: state=%d, nfstag=0x%p\n", state, nfstag);
  739. +
  740. +    if (((state == 2) || (state == 3)) && (nfstag != NULL)) {
  741. +        if (memcmp(nfstag, L"@NFS", (4*sizeof(wchar_t))) == 0) {
  742. +            *pubfh_tag = false;
  743.              status = STATUS_SUCCESS;
  744. -    }
  745. -    else if (NetRootName->Length ==
  746. -        (SrvCallName->Length + PubNfsPrefix.Length)) {
  747. -        const UNICODE_STRING PubNetRootPrefix = {
  748. -            PubNfsPrefix.Length,
  749. -            NetRootName->MaximumLength - SrvCallName->Length,
  750. -            &NetRootName->Buffer[SrvCallName->Length/2]
  751. -        };
  752. -        if (!RtlCompareUnicodeString(&PubNetRootPrefix, &PubNfsPrefix, FALSE))
  753. -            *pubfh_prefix = TRUE;
  754. +        }
  755. +        else if (memcmp(nfstag, L"@PUBNFS", (7*sizeof(wchar_t))) == 0) {
  756. +            *pubfh_tag = true;
  757.              status = STATUS_SUCCESS;
  758. +        }
  759. +        else {
  760. +            DbgP("netroot_has_nfs_tag: no match\n");
  761. +        }
  762.      }
  763. -#endif /* USE_ENTIRE_PATH_FOR_NETROOT */
  764. +
  765.      return status;
  766.  }
  767.  
  768. @@ -934,15 +918,16 @@ NTSTATUS nfs41_CreateVNetRoot(
  769.  
  770.      /*
  771.       * In order to cooperate with other network providers, we
  772. -     * must only claim paths of the form '\\server\nfs4\path'
  773. -     * or '\\server\pubnfs4\path'
  774. +     * must only claim paths of the form '\\server@NFS@<port>\path'
  775. +     * or '\\server@PUBNFS@<port>\path'
  776.       */
  777. -    BOOLEAN pubfh_prefix = FALSE;
  778. -    status = has_nfs_prefix(pSrvCall->pSrvCallName, pNetRoot->pNetRootName, &pubfh_prefix);
  779. +    bool pubfh_tag = false;
  780. +    status = netroot_has_nfs_tag(pSrvCall->pSrvCallName, pNetRoot->pNetRootName, &pubfh_tag);
  781.      if (status) {
  782. -        print_error("nfs41_CreateVNetRoot: NetRootName '%wZ' doesn't match "
  783. -            "'\\nfs4' or '\\pubnfs4'!\n", pNetRoot->pNetRootName);
  784. -        goto out;
  785. +        print_error("nfs41_CreateVNetRoot: "
  786. +            "NetRootName '%wZ' does not match '@NFS' or '@PUBNFS'!\n",
  787. +            pNetRoot->pNetRootName);
  788. +            goto out;
  789.      }
  790.      pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD;
  791.      pNetRoot->DeviceType = FILE_DEVICE_DISK;
  792. @@ -979,10 +964,10 @@ NTSTATUS nfs41_CreateVNetRoot(
  793.          pVNetRootContext->timebasedcoherency = Config->timebasedcoherency;
  794.      } else {
  795.          /*
  796. -         * Codepath for \\server@port\nfs4\path or
  797. -         * \\server@port\pubnfs4\path
  798. +         * Codepath for \\server@NFS@port\path or
  799. +         * \\server@PUBNFS@port\path
  800.           */
  801. -        DbgP("Codepath for \\\\server@port\\@(pubnfs4|nfs4)\\path\n");
  802. +        DbgP("Codepath for \\\\server@(NFS|PUBNFS)@port\\path\n");
  803.  
  804.          /*
  805.           * STATUS_NFS_SHARE_NOT_MOUNTED - status code for the case
  806. @@ -1102,7 +1087,7 @@ NTSTATUS nfs41_CreateVNetRoot(
  807.          pVNetRootContext->timebasedcoherency = Config->timebasedcoherency;
  808.      }
  809.  
  810. -    Config->use_nfspubfh = pubfh_prefix;
  811. +    Config->use_nfspubfh = pubfh_tag;
  812.  
  813.      DbgP("Config->{ "
  814.          "MntPt='%wZ', "
  815. @@ -1283,7 +1268,7 @@ NTSTATUS nfs41_CreateVNetRoot(
  816.          RtlCopyLuid(&entry->login_id, &luid);
  817.          /*
  818.           * Save mount config so we can use it for
  819. -         * \\server@port\@(pubnfs4|nfs4)\path mounts later
  820. +         * \\server@(PUBNFS|NFS)@port\path mounts later
  821.           */
  822.          copy_nfs41_mount_config(&entry->Config, Config);
  823.          nfs41_AddEntry(pNetRootContext->mounts.lock,
  824. @@ -1366,32 +1351,18 @@ VOID nfs41_ExtractNetRootName(
  825.      ULONG length = FilePathName->Length;
  826.      PWCH w = FilePathName->Buffer;
  827.      PWCH wlimit = (PWCH)(((PCHAR)w)+length);
  828. -    PWCH wlow;
  829.  
  830. -    w += (SrvCall->pSrvCallName->Length/sizeof(WCHAR));
  831. -    NetRootName->Buffer = wlow = w;
  832. -    /* parse the entire path into NetRootName */
  833. -#if USE_ENTIRE_PATH_FOR_NETROOT
  834. -    w = wlimit;
  835. -#else
  836. -    for (;;) {
  837. -        if (w >= wlimit)
  838. -            break;
  839. -        if ((*w == OBJ_NAME_PATH_SEPARATOR) && (w != wlow))
  840. -            break;
  841. -        w++;
  842. -    }
  843. -#endif
  844. -    NetRootName->Length = NetRootName->MaximumLength
  845. -                = (USHORT)((PCHAR)w - (PCHAR)wlow);
  846. +    NetRootName->Buffer = wlimit;
  847. +    NetRootName->Length = NetRootName->MaximumLength = 0;
  848. +
  849. +    /* FIXME: |RestOfName| not implemented yet, the Win10 RDR does not use it */
  850. +
  851.  #ifdef DEBUG_MOUNT
  852.      DbgP("nfs41_ExtractNetRootName: "
  853. -        "In: pSrvCall 0x%p PathName='%wZ' SrvCallName='%wZ' "
  854. +        "In: pSrvCall 0x%p FilePathName='%wZ' SrvCallName='%wZ' "
  855.          "Out: NetRootName='%wZ'\n",
  856.          SrvCall, FilePathName, SrvCall->pSrvCallName, NetRootName);
  857. -#endif
  858. -    return;
  859. -
  860. +#endif /* DEBUG_MOUNT */
  861.  }
  862.  
  863.  NTSTATUS nfs41_FinalizeSrvCall(
  864. diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
  865. index ee1cb7f..a969839 100644
  866. --- a/tests/manual_testing.txt
  867. +++ b/tests/manual_testing.txt
  868. @@ -1,5 +1,5 @@
  869.  #
  870. -# ms-nfs41-client manual testing sequence, 2025-10-02
  871. +# ms-nfs41-client manual testing sequence, 2025-10-15
  872.  #
  873.  # Draft version, needs to be turned into automated tests
  874.  # if possible
  875. @@ -264,16 +264,16 @@ ln -s /dev/zero foo && ls -l foo && rm foo
  876.  rm -f symlink1_to_m_builds ; cmd /C 'mklink /D symlink1_to_m_builds M:\builds' ; cmd /C 'cd symlink1_to_m_builds && dir && echo test_OK'
  877.  # 8. cmd.exe follow sublink dir to other filesystem
  878.  # (this assumes we have an valid UNC path
  879. -# \\derfwnb4966_ipv6linklocal@2049\nfs4\bigdisk\ with a subdir "builds")
  880. -rm -f symlink1_to_unc ; cmd /C 'mklink /D symlink1_to_unc \\derfwnb4966_ipv6linklocal@2049\nfs4\bigdisk\builds\' ; cmd /C 'cd symlink1_to_unc && dir && echo test_OK'
  881. +# \\derfwnb4966_ipv6linklocal@NFS@2049\bigdisk\ with a subdir "builds")
  882. +rm -f symlink1_to_unc ; cmd /C 'mklink /D symlink1_to_unc \\derfwnb4966_ipv6linklocal@NFS@2049\bigdisk\builds\' ; cmd /C 'cd symlink1_to_unc && dir && echo test_OK'
  883.  # 9a. powershell follow sublink dir to other filesystem
  884.  # (this assumes we have an valid UNC path
  885. -# \\derfwnb4966_ipv6linklocal@2049\nfs4\bigdisk\ with a subdir "builds")
  886. -rm -f symlink1_to_unc ; cmd /C 'mklink /D symlink1_to_unc \\derfwnb4966_ipv6linklocal@2049\nfs4\bigdisk\builds\' ; powershell -Command 'cd symlink1_to_unc ; if ($?) { dir ; if ($?) { echo "test OK" } else { echo "dir failed" } } else { echo "cd failed" }'
  887. +# \\derfwnb4966_ipv6linklocal@NFS@2049\bigdisk\ with a subdir "builds")
  888. +rm -f symlink1_to_unc ; cmd /C 'mklink /D symlink1_to_unc \\derfwnb4966_ipv6linklocal@NFS@2049\bigdisk\builds\' ; powershell -Command 'cd symlink1_to_unc ; if ($?) { dir ; if ($?) { echo "test OK" } else { echo "dir failed" } } else { echo "cd failed" }'
  889.  # 9b. powershell follow sublink dir to other filesystem
  890.  # (this assumes we have an valid UNC path
  891. -# \\derfwpc5131_ipv4@2049\nfs4\export\home2\rmainz\ with a subdir "tmp")
  892. -rm -f symlink1_to_h_tmp ; cmd /C 'mklink /D symlink1_to_h_tmp \\derfwpc5131_ipv4@2049\nfs4\export\home2\rmainz\tmp' ; powershell -Command 'cd symlink1_to_h_tmp ; if ($?) { dir ; if ($?) { echo "test OK" } else { echo "dir failed" } } else { echo "cd failed" }'
  893. +# \\derfwpc5131_ipv4@NFS@2049\export\home2\rmainz\ with a subdir "tmp")
  894. +rm -f symlink1_to_h_tmp ; cmd /C 'mklink /D symlink1_to_h_tmp \\derfwpc5131_ipv4@NFS@2049\export\home2\rmainz\tmp' ; powershell -Command 'cd symlink1_to_h_tmp ; if ($?) { dir ; if ($?) { echo "test OK" } else { echo "dir failed" } } else { echo "cd failed" }'
  895.  
  896.  #
  897.  # Tests for absolute (start from root "/") POSIX symlinks
  898. @@ -392,11 +392,11 @@ Example:
  899.  ---- snip ----
  900.  # get UNC path for driver letterr 'L':
  901.  $ powershell -Command 'Get-PSDrive -Name L | Select-Object -Property DisplayRoot,CurrentLocation | Format-List' | ksh93 -c 'compound c=(typeset -A ar) ; while IFS="" read -r l ; do dummy="${l/~(Elr)(.+?)[[:space:]]*:[[:space:]](.+)\015/x}" ; [[ "${.sh.match[1]-}" == "" ]] && continue ; c.ar["${.sh.match[1]}"]="${.sh.match[2]}" ; done ; cygpath -u "$(printf "%s\\\\%s\n" "${c.ar[DisplayRoot]}" "${c.ar[CurrentLocation]}")"'
  902. -//derfwnb4966_ipv6linklocal@2049/nfs4/bigdisk/builds/bash_build1
  903. +//derfwnb4966_ipv6linklocal@NFS@2049/bigdisk/builds/bash_build1
  904.  # tests
  905. -mkdir -p //derfwnb4966_ipv6linklocal@2049/nfs4/bigdisk/builds/bash_build1/a1/b1/c1 || echo FAIL
  906. -mkdir //derfwnb4966_ipv6linklocal@2049/nfs4/bigdisk/builds/bash_build1/a2 || echo FAIL
  907. -mkdir //derfwnb4966_ipv6linklocal@2049/nfs4/bigdisk/builds/bash_build1/a2/b2 || echo FAIL
  908. +mkdir -p //derfwnb4966_ipv6linklocal@NFS@2049/bigdisk/builds/bash_build1/a1/b1/c1 || echo FAIL
  909. +mkdir //derfwnb4966_ipv6linklocal@NFS@2049/bigdisk/builds/bash_build1/a2 || echo FAIL
  910. +mkdir //derfwnb4966_ipv6linklocal@NFS@2049/bigdisk/builds/bash_build1/a2/b2 || echo FAIL
  911.  ---- snip ----
  912.  
  913.  #
  914. @@ -655,7 +655,7 @@ $ time ksh93 -c 'rm -Rf nfstmp1 gcc.x.strace.log x.c x.exe && mkdir nfstmp1 && c
  915.  git clone -b 'v1.0.10' https://github.com/ksh93/ksh.git
  916.  cd ksh
  917.  git config --global --add safe.directory "$PWD"
  918. -# add patch so UNC path support is enabled (e.g. "cd cd //derfwnb4966_ipv6linklocal@2049/nfs4/net_tmpfs")
  919. +# add patch so UNC path support is enabled (e.g. "cd //derfwnb4966_ipv6linklocal@NFS@2049/net_tmpfs")
  920.  patch -p1 <'../cygwin/cygwin_ksh93/ksh_1_0_8_libast_Cygwin_set_PATH_LEADING_SLASHES_for_UNC_paths.patch'
  921.  sed -i -r 's/mkfifo.+?(-m [[:digit:]]+)/mkfifo /g' ./src/cmd/INIT/package.sh ./bin/package
  922.  # repeat:
  923. --
  924. 2.51.0
  925.  
  926. From b221fb1ae46b738a838bc73b41f4a392648b707d Mon Sep 17 00:00:00 2001
  927. From: Dan Shelton <dan.f.shelton@gmail.com>
  928. Date: Thu, 16 Oct 2025 18:36:39 +0200
  929. Subject: [PATCH 3/5] sys: Remove unused NTRY_OPCODE2STRING(entry) macro
  930.  
  931. Remove unused NTRY_OPCODE2STRING(entry) macro.
  932.  
  933. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  934. ---
  935. sys/nfs41sys_debug.h | 1 -
  936.  1 file changed, 1 deletion(-)
  937.  
  938. diff --git a/sys/nfs41sys_debug.h b/sys/nfs41sys_debug.h
  939. index 4570cde..47f8d61 100644
  940. --- a/sys/nfs41sys_debug.h
  941. +++ b/sys/nfs41sys_debug.h
  942. @@ -50,7 +50,6 @@ void print_ea_info(PFILE_FULL_EA_INFORMATION info);
  943.  void print_get_ea(int on, PFILE_GET_EA_INFORMATION info);
  944.  void print_caching_level(int on, ULONG flag, PUNICODE_STRING s);
  945.  const char *opcode2string(int opcode);
  946. -#define ENTRY_OPCODE2STRING(entry) ((entry)?opcode2string((entry)->opcode):"<entry==NULL>")
  947.  void print_open_error(int on, int status);
  948.  void print_wait_status(int on, const char *str, NTSTATUS status,
  949.                         const char *opcode, PVOID entry, LONGLONG xid);
  950. --
  951. 2.51.0
  952.  
  953. From 919186a7ed8a639b174d31eb1c0995c9e61f9597 Mon Sep 17 00:00:00 2001
  954. From: Cedric Blancher <cedric.blancher@gmail.com>
  955. Date: Thu, 16 Oct 2025 20:12:08 +0200
  956. Subject: [PATCH 4/5] tests: nfsbuildtest: Add bison,flex to required packages
  957.  for bash build
  958.  
  959. nfsbuildtest: Add bison,flex to required packages for bash build.
  960.  
  961. Signed-off-by: Roland Mainz <roland.mainz@nrubsig.org>
  962. ---
  963. tests/nfsbuildtest/nfsbuildtest.ksh93 | 2 ++
  964.  1 file changed, 2 insertions(+)
  965.  
  966. diff --git a/tests/nfsbuildtest/nfsbuildtest.ksh93 b/tests/nfsbuildtest/nfsbuildtest.ksh93
  967. index 2103fa3..5cd2015 100644
  968. --- a/tests/nfsbuildtest/nfsbuildtest.ksh93
  969. +++ b/tests/nfsbuildtest/nfsbuildtest.ksh93
  970. @@ -754,6 +754,8 @@ function main
  971.                         is_toolkit_pkg_installed itp 'gcc-g++' || (( errc++ ))
  972.                         is_toolkit_pkg_installed itp 'autoconf' || (( errc++ ))
  973.                         is_toolkit_pkg_installed itp 'automake' || (( errc++ ))
  974. +                       is_toolkit_pkg_installed itp 'flex' || (( errc++ ))
  975. +                       is_toolkit_pkg_installed itp 'bison' || (( errc++ ))
  976.                         if is_cygwin ; then
  977.                                 if (( (cygwin_vers.major*1000+cygwin_vers.minor) >= 3005 )) ; then
  978.                                         print '# bash_build: Using Cygwin >= 3.5 config'
  979. --
  980. 2.51.0
  981.  
  982. From bc301b70df576b9d14b095af34303e67f07708a1 Mon Sep 17 00:00:00 2001
  983. From: Roland Mainz <roland.mainz@nrubsig.org>
  984. Date: Thu, 16 Oct 2025 21:31:48 +0200
  985. Subject: [PATCH 5/5] daemon: Add some debug statistics for NFS I/O read+write
  986.  sizes
  987.  
  988. Add some debug statistics for NFS I/O read+write sizes.
  989.  
  990. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  991. ---
  992. daemon/readwrite.c | 139 +++++++++++++++++++++++++++++++++++++++++++++
  993.  1 file changed, 139 insertions(+)
  994.  
  995. diff --git a/daemon/readwrite.c b/daemon/readwrite.c
  996. index ac42a50..e86c623 100644
  997. --- a/daemon/readwrite.c
  998. +++ b/daemon/readwrite.c
  999. @@ -24,6 +24,12 @@
  1000.  #include <Windows.h>
  1001.  #include <stdio.h>
  1002.  
  1003. +// #define IOSIZE_STAT 1
  1004. +
  1005. +#ifdef IOSIZE_STAT
  1006. +#include <math.h>
  1007. +#endif /* IOSIZE_STAT */
  1008. +
  1009.  #include "nfs41_ops.h"
  1010.  #include "name_cache.h"
  1011.  #include "upcall.h"
  1012. @@ -35,6 +41,129 @@
  1013.  #define MAX_WRITE_RETRIES 6
  1014.  
  1015.  
  1016. +
  1017. +#ifdef IOSIZE_STAT
  1018. +struct
  1019. +{
  1020. +    /*
  1021. +     * Windows I/O is limited to |ULONG| (32bit) block sizes, so
  1022. +     * |log2()| below can never go beyond 2^31
  1023. +     */
  1024. +    long long readstats[32+1];
  1025. +    long read_counter;
  1026. +    long long writestats[32+1];
  1027. +    long write_counter;
  1028. +} iosizestat;
  1029. +
  1030. +static
  1031. +void ioread_stats(int status, ULONG size)
  1032. +{
  1033. +    if (status != ERROR_SUCCESS)
  1034. +        return;
  1035. +
  1036. +    /* No locking, no atomic operations, we do not need to be 100% accurate! */
  1037. +    iosizestat.readstats[(int)log2((double)size)]++;
  1038. +    iosizestat.read_counter++;
  1039. +    if ((iosizestat.read_counter % 256) == 0) {
  1040. +        DPRINTF(0, ("ioread_stats: readstats=( "
  1041. +            "[0]=%lld [1]=%lld [2]=%lld [3]=%lld "
  1042. +            "[4]=%lld [5]=%lld [6]=%lld [7]=%lld "
  1043. +            "[8]=%lld [9]=%lld [10]=%lld [11]=%lld "
  1044. +            "[12]=%lld [13]=%lld [14]=%lld [15]=%lld "
  1045. +            "[16]=%lld [17]=%lld [18]=%lld [19]=%lld "
  1046. +            "[20]=%lld [21]=%lld [22]=%lld [23]=%lld "
  1047. +            "[24]=%lld [25]=%lld [26]=%lld [27]=%lld "
  1048. +            "[28]=%lld [29]=%lld [30]=%lld [31]=%lld )\n",
  1049. +            iosizestat.readstats[0],
  1050. +            iosizestat.readstats[1],
  1051. +            iosizestat.readstats[2],
  1052. +            iosizestat.readstats[3],
  1053. +            iosizestat.readstats[4],
  1054. +            iosizestat.readstats[5],
  1055. +            iosizestat.readstats[6],
  1056. +            iosizestat.readstats[7],
  1057. +            iosizestat.readstats[8],
  1058. +            iosizestat.readstats[9],
  1059. +            iosizestat.readstats[10],
  1060. +            iosizestat.readstats[11],
  1061. +            iosizestat.readstats[12],
  1062. +            iosizestat.readstats[13],
  1063. +            iosizestat.readstats[14],
  1064. +            iosizestat.readstats[15],
  1065. +            iosizestat.readstats[16],
  1066. +            iosizestat.readstats[17],
  1067. +            iosizestat.readstats[18],
  1068. +            iosizestat.readstats[19],
  1069. +            iosizestat.readstats[20],
  1070. +            iosizestat.readstats[21],
  1071. +            iosizestat.readstats[22],
  1072. +            iosizestat.readstats[23],
  1073. +            iosizestat.readstats[24],
  1074. +            iosizestat.readstats[25],
  1075. +            iosizestat.readstats[26],
  1076. +            iosizestat.readstats[27],
  1077. +            iosizestat.readstats[28],
  1078. +            iosizestat.readstats[29],
  1079. +            iosizestat.readstats[30],
  1080. +            iosizestat.readstats[31]));
  1081. +    }
  1082. +}
  1083. +
  1084. +static
  1085. +void iowrite_stats(int status, ULONG size)
  1086. +{
  1087. +    if (status != ERROR_SUCCESS)
  1088. +        return;
  1089. +
  1090. +    /* No locking, no atomic operations, we do not need to be 100% accurate! */
  1091. +    iosizestat.writestats[(int)log2((double)size)]++;
  1092. +    iosizestat.write_counter++;
  1093. +    if ((iosizestat.write_counter % 256) == 0) {
  1094. +        DPRINTF(0, ("iowrite_stats: writestats=( "
  1095. +            "[0]=%lld [1]=%lld [2]=%lld [3]=%lld "
  1096. +            "[4]=%lld [5]=%lld [6]=%lld [7]=%lld "
  1097. +            "[8]=%lld [9]=%lld [10]=%lld [11]=%lld "
  1098. +            "[12]=%lld [13]=%lld [14]=%lld [15]=%lld "
  1099. +            "[16]=%lld [17]=%lld [18]=%lld [19]=%lld "
  1100. +            "[20]=%lld [21]=%lld [22]=%lld [23]=%lld "
  1101. +            "[24]=%lld [25]=%lld [26]=%lld [27]=%lld "
  1102. +            "[28]=%lld [29]=%lld [30]=%lld [31]=%lld )\n",
  1103. +            iosizestat.writestats[0],
  1104. +            iosizestat.writestats[1],
  1105. +            iosizestat.writestats[2],
  1106. +            iosizestat.writestats[3],
  1107. +            iosizestat.writestats[4],
  1108. +            iosizestat.writestats[5],
  1109. +            iosizestat.writestats[6],
  1110. +            iosizestat.writestats[7],
  1111. +            iosizestat.writestats[8],
  1112. +            iosizestat.writestats[9],
  1113. +            iosizestat.writestats[10],
  1114. +            iosizestat.writestats[11],
  1115. +            iosizestat.writestats[12],
  1116. +            iosizestat.writestats[13],
  1117. +            iosizestat.writestats[14],
  1118. +            iosizestat.writestats[15],
  1119. +            iosizestat.writestats[16],
  1120. +            iosizestat.writestats[17],
  1121. +            iosizestat.writestats[18],
  1122. +            iosizestat.writestats[19],
  1123. +            iosizestat.writestats[20],
  1124. +            iosizestat.writestats[21],
  1125. +            iosizestat.writestats[22],
  1126. +            iosizestat.writestats[23],
  1127. +            iosizestat.writestats[24],
  1128. +            iosizestat.writestats[25],
  1129. +            iosizestat.writestats[26],
  1130. +            iosizestat.writestats[27],
  1131. +            iosizestat.writestats[28],
  1132. +            iosizestat.writestats[29],
  1133. +            iosizestat.writestats[30],
  1134. +            iosizestat.writestats[31]));
  1135. +    }
  1136. +}
  1137. +#endif /* IOSIZE_STAT */
  1138. +
  1139.  const stateid4 special_read_stateid = {0xffffffff,
  1140.      {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
  1141.  
  1142. @@ -193,6 +322,11 @@ static int handle_read(void *daemon_context, nfs41_upcall *upcall)
  1143.  
  1144.      args->out_len += pnfs_bytes_read;
  1145.  out:
  1146. +
  1147. +#ifdef IOSIZE_STAT
  1148. +    ioread_stats(status, args->out_len);
  1149. +#endif /* IOSIZE_STAT */
  1150. +
  1151.      return status;
  1152.  }
  1153.  
  1154. @@ -396,6 +530,11 @@ static int handle_write(void *daemon_context, nfs41_upcall *upcall)
  1155.      status = write_to_mds(upcall, &stateid);
  1156.  out:
  1157.      args->out_len += pnfs_bytes_written;
  1158. +
  1159. +#ifdef IOSIZE_STAT
  1160. +    iowrite_stats(status, args->out_len);
  1161. +#endif /* IOSIZE_STAT */
  1162. +
  1163.      return status;
  1164.  }
  1165.  
  1166. --
  1167. 2.51.0

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