pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Patch for FreeBSD15.0-file/dir-creation-EPERM-bug-workaround, lssparse update, docs, tests+misc, 2026-01-09
Posted by Anonymous on Fri 9th Jan 2026 18:27
raw | new post

  1. From 289a91ebd716c4f1296a7ed2b5430c3a6d5be31a Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Fri, 9 Jan 2026 14:30:09 +0100
  4. Subject: [PATCH 1/5] daemon: Add missing include file for
  5.  |nfs41_delegation_return()|
  6.  
  7. Add missing include file for |nfs41_delegation_return()|.
  8.  
  9. Reported-by: Cedric Blancher <cedric.blancher@gmail.com>
  10. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  11. ---
  12. daemon/fsctl.c | 3 ++-
  13.  1 file changed, 2 insertions(+), 1 deletion(-)
  14.  
  15. diff --git a/daemon/fsctl.c b/daemon/fsctl.c
  16. index 7d25a90..2044e9f 100644
  17. --- a/daemon/fsctl.c
  18. +++ b/daemon/fsctl.c
  19. @@ -1,5 +1,5 @@
  20.  /* NFSv4.1 client for Windows
  21. - * Copyright (C) 2024-2025 Roland Mainz <roland.mainz@nrubsig.org>
  22. + * Copyright (C) 2024-2026 Roland Mainz <roland.mainz@nrubsig.org>
  23.   *
  24.   * Roland Mainz <roland.mainz@nrubsig.org>
  25.   *
  26. @@ -22,6 +22,7 @@
  27.  #include <stdio.h>
  28.  
  29.  #include "nfs41_ops.h"
  30. +#include "delegation.h"
  31.  #include "name_cache.h"
  32.  #include "upcall.h"
  33.  #include "daemon_debug.h"
  34. --
  35. 2.51.0
  36.  
  37. From 56d7e76133edcd497d0ba98938b9ed0a0084dbad Mon Sep 17 00:00:00 2001
  38. From: Roland Mainz <roland.mainz@nrubsig.org>
  39. Date: Fri, 9 Jan 2026 16:40:43 +0100
  40. Subject: [PATCH 2/5] tests: lsparse should have options for start offset and
  41.  number of bytes to scan
  42.  
  43. lsparse should have options for start offset and number of bytes
  44. to scan.
  45.  
  46. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  47. ---
  48. tests/lssparse/lssparse.c | 32 ++++++++++++++++++++++++++++++--
  49.  1 file changed, 30 insertions(+), 2 deletions(-)
  50.  
  51. diff --git a/tests/lssparse/lssparse.c b/tests/lssparse/lssparse.c
  52. index 5c56a4d..81cd1f2 100644
  53. --- a/tests/lssparse/lssparse.c
  54. +++ b/tests/lssparse/lssparse.c
  55. @@ -39,6 +39,7 @@
  56.  #include <string.h>
  57.  #include <fcntl.h>
  58.  #include <unistd.h>
  59. +#include <limits.h>
  60.  #include <errno.h>
  61.  
  62.  #define EXIT_USAGE     (2) /* Traditional UNIX exit code for usage */
  63. @@ -47,8 +48,12 @@ static
  64.  void
  65.  usage(const char *progname)
  66.  {
  67. -       (void) fprintf(stderr, "Usage: %s [-h] [-xdH] <sparse_file>\n"
  68. +       (void) fprintf(stderr,
  69. +               "Usage: %s [-h] [-s startoffset] [-n len] [xdH] "
  70. +                       "<sparse_file>\n"
  71.                 "  -h: Display this help message\n"
  72. +               "  -s: Start offset in file\n"
  73. +               "  -n: Number of file bytes to scan\n"
  74.                 "  -x: Print offsets in hexadecimal (base 16)\n"
  75.                 "  -d: Print offsets in decimal (base 10)\n"
  76.                 "  -H: Print hole information\n",
  77. @@ -65,6 +70,9 @@ main(int argc, char *argv[])
  78.  {
  79.         /* Arguments */
  80.         const char *progname = argv[0];
  81. +       off_t start_offset = 0LL;
  82. +       off_t end_offset = LLONG_MIN;
  83. +       off_t max_scan_len = -1LL;
  84.         printbase pb = pb_hex;
  85.         bool print_holes = false;
  86.         const char *filename;
  87. @@ -82,12 +90,18 @@ main(int argc, char *argv[])
  88.         off_t data_len;
  89.         off_t hole_len;
  90.  
  91. -       while ((opt = getopt(argc, argv, "hxdH")) != -1) {
  92. +       while ((opt = getopt(argc, argv, "hs:n:xdH")) != -1) {
  93.                 switch (opt) {
  94.                         case '?':
  95.                         case 'h':
  96.                                 usage(progname);
  97.                                 return (EXIT_USAGE);
  98. +                       case 's':
  99. +                               start_offset = atoll(optarg);
  100. +                               break;
  101. +                       case 'n':
  102. +                               max_scan_len = atoll(optarg);
  103. +                               break;
  104.                         case 'x':
  105.                                 pb = pb_hex;
  106.                                 break;
  107. @@ -127,6 +141,15 @@ main(int argc, char *argv[])
  108.         }
  109.         (void) lseek(fd, 0, SEEK_SET);
  110.  
  111. +       if (start_offset > 0LL) {
  112. +               offset = start_offset;
  113. +               (void) printf("# ... starting at offset %lld\n",
  114. +                       (long long)offset);
  115. +       }
  116. +
  117. +       if (max_scan_len > 0LL) {
  118. +               end_offset = start_offset + max_scan_len;
  119. +       }
  120.  
  121.         /*
  122.          * Loop over hole&&data sections
  123. @@ -223,6 +246,11 @@ main(int argc, char *argv[])
  124.         }
  125.  
  126.         offset = hole_end;
  127. +
  128. +               if ((max_scan_len != -1LL) && (offset >= end_offset)) {
  129. +                       (void) printf("# ... stopping at offset %lld\n",
  130. +                               (long long)offset);
  131. +               }
  132.         }
  133.  
  134.         if ((data_start == -1) && (errno == ENXIO) && (offset == 0)) {
  135. --
  136. 2.51.0
  137.  
  138. From 61785b02157abef3c19e52b083d0ee06a26b78e2 Mon Sep 17 00:00:00 2001
  139. From: Roland Mainz <roland.mainz@nrubsig.org>
  140. Date: Fri, 9 Jan 2026 16:45:33 +0100
  141. Subject: [PATCH 3/5] tests: Fix Solaris/Illumos cstyle issues in lssparse.c
  142.  
  143. Fix Solaris/Illumos cstyle issues in lssparse.c.
  144.  
  145. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  146. ---
  147. tests/lssparse/lssparse.c | 49 +++++++++++++++++++++------------------
  148.  1 file changed, 26 insertions(+), 23 deletions(-)
  149.  
  150. diff --git a/tests/lssparse/lssparse.c b/tests/lssparse/lssparse.c
  151. index 81cd1f2..920d972 100644
  152. --- a/tests/lssparse/lssparse.c
  153. +++ b/tests/lssparse/lssparse.c
  154. @@ -42,7 +42,7 @@
  155.  #include <limits.h>
  156.  #include <errno.h>
  157.  
  158. -#define EXIT_USAGE     (2) /* Traditional UNIX exit code for usage */
  159. +#define        EXIT_USAGE      (2)     /* Traditional UNIX exit code for usage */
  160.  
  161.  static
  162.  void
  163. @@ -61,8 +61,8 @@ usage(const char *progname)
  164.  }
  165.  
  166.  typedef enum _printbase {
  167. -    pb_hex = 1,
  168. -    pb_dec = 2
  169. +       pb_hex = 1,
  170. +       pb_dec = 2
  171.  } printbase;
  172.  
  173.  int
  174. @@ -222,30 +222,33 @@ main(int argc, char *argv[])
  175.                         if (errno == ENXIO) {
  176.                         /* No more holes ? */
  177.                         hole_end = file_size;
  178. -               } else {
  179. -                       (void) fprintf(stderr,
  180. -                               "%s: "
  181. -                               "lseek(..., SEEK_DATA, ...) failed with [%s]\n",
  182. -                               progname,
  183. -                               strerror(errno));
  184. -                       retval = EXIT_FAILURE;
  185. -                       goto done;
  186. +                       } else {
  187. +                               (void) fprintf(stderr,
  188. +                                       "%s: "
  189. +                                       "lseek(..., SEEK_DATA, ...) "
  190. +                                       "failed with [%s]\n",
  191. +                                       progname,
  192. +                                       strerror(errno));
  193. +                               retval = EXIT_FAILURE;
  194. +                               goto done;
  195. +                       }
  196.                 }
  197. -       }
  198.  
  199. -       hole_len = hole_end - hole_start;
  200. +               hole_len = hole_end - hole_start;
  201.  
  202. -       if (print_holes && (hole_len > 0LL)) {
  203. -               (void) printf((pb == pb_hex)?
  204. -                       "Hole range[%ld]: offset=0x%llx,\tlength=0x%llx\n":
  205. -                       "Hole range[%ld]: offset=%lld,\tlength=%lld\n",
  206. -                       (long)i,
  207. -                       (long long)hole_start,
  208. -                       (long long)hole_len);
  209. -               i++;
  210. -       }
  211. +               if (print_holes && (hole_len > 0LL)) {
  212. +                       (void) printf((pb == pb_hex)?
  213. +                               "Hole range[%ld]: "
  214. +                               "offset=0x%llx,\tlength=0x%llx\n":
  215. +                               "Hole range[%ld]: "
  216. +                               "offset=%lld,\tlength=%lld\n",
  217. +                               (long)i,
  218. +                               (long long)hole_start,
  219. +                               (long long)hole_len);
  220. +                       i++;
  221. +               }
  222.  
  223. -       offset = hole_end;
  224. +               offset = hole_end;
  225.  
  226.                 if ((max_scan_len != -1LL) && (offset >= end_offset)) {
  227.                         (void) printf("# ... stopping at offset %lld\n",
  228. --
  229. 2.51.0
  230.  
  231. From 10e087ce4624dcde84cf00811bf51344621943c1 Mon Sep 17 00:00:00 2001
  232. From: Roland Mainz <roland.mainz@nrubsig.org>
  233. Date: Fri, 9 Jan 2026 17:27:38 +0100
  234. Subject: [PATCH 4/5] README.md,docs: Remove comment about
  235.  |FSCTL_QUERY_ALLOCATED_RANGES| bug which has long been resolved
  236.  
  237. Remove comment about |FSCTL_QUERY_ALLOCATED_RANGES| bug which has long been resolved.
  238.  
  239. Reported-by: Lionel Cons <lionelcons1972@gmail.com>
  240. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  241. ---
  242. README.md       | 4 +---
  243.  docs/README.xml | 2 +-
  244.  2 files changed, 2 insertions(+), 4 deletions(-)
  245.  
  246. diff --git a/README.md b/README.md
  247. index 5e9f717..fcbb185 100644
  248. --- a/README.md
  249. +++ b/README.md
  250. @@ -131,9 +131,7 @@ NFSv4.2/NFSv4.1 filesystem driver for Windows 10/11 & Windows Server
  251.      `$ /usr/bin/cp --sparse=auto src dest #`
  252.  
  253.    - `/cygdrive/c/Windows/system32/fsutil sparse queryrange myfile.dat`
  254. -    can be used to enumerate ranges where data are allocated (BUG:
  255. -    Win10+Win11 fsutil only support 64 data ranges, the filesystem
  256. -    itself supports an unlimited number of data ranges)
  257. +    can be used to enumerate ranges where data are allocated
  258.  
  259.    - `/cygdrive/c/Windows/system32/xcopy /sparse` can be used to copy
  260.      sparse files+sparse named streams. Requires on Win11 \>= 22H2
  261. diff --git a/docs/README.xml b/docs/README.xml
  262. index 541cef7..b21e85f 100644
  263. --- a/docs/README.xml
  264. +++ b/docs/README.xml
  265. @@ -133,7 +133,7 @@
  266.                <para>Cygwin sparse file support requires &gt;= Cygwin 3.6 to support POSIX-1.2024 <literal>|lseek(...,SEEK_HOLE/SEEK_DATA,...)|</literal>, which is needed for coreutils <filename>/usr/bin/fallocate</filename> and <command>$ /usr/bin/cp --sparse=auto src dest #</command></para>
  267.              </listitem>
  268.              <listitem>
  269. -              <para><filename>/cygdrive/c/Windows/system32/fsutil sparse queryrange myfile.dat</filename> can be used to enumerate ranges where data are allocated (BUG: Win10+Win11 fsutil only support 64 data ranges, the filesystem itself supports an unlimited number of data ranges)</para>
  270. +              <para><filename>/cygdrive/c/Windows/system32/fsutil sparse queryrange myfile.dat</filename> can be used to enumerate ranges where data are allocated</para>
  271.              </listitem>
  272.              <listitem>
  273.                <para><filename>/cygdrive/c/Windows/system32/xcopy /sparse</filename> can be used to copy sparse files+sparse named streams. Requires on Win11 &gt;= 22H2 because it relies on <literal>|CopyFile2()|</literal> flag <literal>|COPY_FILE_ENABLE_SPARSE_COPY|</literal>.</para>
  274. --
  275. 2.51.0
  276.  
  277. From ab947a04f8b03c2b9b1846fe6b1c6cddfb2b8209 Mon Sep 17 00:00:00 2001
  278. From: Roland Mainz <roland.mainz@nrubsig.org>
  279. Date: Fri, 9 Jan 2026 19:11:22 +0100
  280. Subject: [PATCH 5/5] daemon,nfs41_build_features.h: Add TEMPORARY workaround
  281.  for FreeBSD 15.0 bug which prevents file/dir creation
  282. MIME-Version: 1.0
  283. Content-Type: text/plain; charset=UTF-8
  284. Content-Transfer-Encoding: 8bit
  285.  
  286. Add a TEMPORARY workaround for the FreeBSD 15.0 bug which prevents file/dir
  287. creation when using the FreeBSD nfsd.
  288. See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=292283 ("[Bug 292283]
  289. (JAVA) NFSv4.1 client trying to set FATTR4_SYSTEM or FATTR4_HIDDEN gets
  290. EPERM for file and dir creation attemps").
  291.  
  292. This WORKAROUND is intended to be TEMPORARY and should be removed
  293. as soon as a FreeBSD 15.x release with a fix for FreeBSD bug #292283
  294. becomes available.
  295.  
  296. Reported-by: Aurélien Couderc <aurelien.couderc2002@gmail.com>
  297. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  298. ---
  299. daemon/open.c          | 47 +++++++++++++++++++++++++++++++++++++++++-
  300.  nfs41_build_features.h | 13 ++++++++++++
  301.  2 files changed, 59 insertions(+), 1 deletion(-)
  302.  
  303. diff --git a/daemon/open.c b/daemon/open.c
  304. index 585245c..17c89b6 100644
  305. --- a/daemon/open.c
  306. +++ b/daemon/open.c
  307. @@ -824,6 +824,37 @@ out:
  308.  }
  309.  #endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  310.  
  311. +#ifdef WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283
  312. +void set_hiddensystem_attrs(ULONG file_attrs, nfs41_open_state *state)
  313. +{
  314. +    int status;
  315. +    stateid_arg stateid;
  316. +
  317. +    if ((file_attrs & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) == 0)
  318. +        return;
  319. +
  320. +    nfs41_file_info createattrs = {
  321. +        .attrmask.count = 2,
  322. +        .attrmask.arr[0] = FATTR4_WORD0_HIDDEN,
  323. +        .attrmask.arr[1] = FATTR4_WORD1_SYSTEM,
  324. +        .hidden = ((file_attrs & FILE_ATTRIBUTE_HIDDEN) ? 1 : 0),
  325. +        .system = ((file_attrs & FILE_ATTRIBUTE_SYSTEM) ? 1 : 0),
  326. +    };
  327. +
  328. +    nfs41_open_stateid_arg(state, &stateid);
  329. +    status = nfs41_setattr(state->session,
  330. +        &state->file, &stateid, &createattrs);
  331. +
  332. +    if (status && (status != NFS4ERR_ATTRNOTSUPP)) {
  333. +        eprintf("set_hiddensystem_attrs(state->file.name.name='%s'): "
  334. +            "nfs41_setattr() "
  335. +            "failed with error '%s'.\n",
  336. +            state->file.name.name,
  337. +            nfs_error_string(status));
  338. +    }
  339. +}
  340. +#endif /* WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283 */
  341. +
  342.  static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  343.  {
  344.      int status = 0;
  345. @@ -1164,6 +1195,9 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  346.              upcall->currentthread_token,
  347.              state);
  348.  #endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
  349. +#ifdef WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283
  350. +        set_hiddensystem_attrs(args->file_attrs, state);
  351. +#endif /* WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283 */
  352.  
  353.          nfs_to_basic_info(state->file.name.name,
  354.              state->file.fh.superblock,
  355. @@ -1224,12 +1258,19 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  356.                  args->mode = info.mode;
  357.          }
  358.          createattrs.attrmask.count = 2;
  359. +#ifdef WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283
  360. +        createattrs.attrmask.arr[0] = FATTR4_WORD0_ARCHIVE;
  361. +        createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE;
  362. +        createattrs.mode = args->mode;
  363. +        createattrs.archive = args->file_attrs & FILE_ATTRIBUTE_ARCHIVE ? 1 : 0;
  364. +#else
  365.          createattrs.attrmask.arr[0] = FATTR4_WORD0_HIDDEN | FATTR4_WORD0_ARCHIVE;
  366.          createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE | FATTR4_WORD1_SYSTEM;
  367.          createattrs.mode = args->mode;
  368.          createattrs.hidden = args->file_attrs & FILE_ATTRIBUTE_HIDDEN ? 1 : 0;
  369.          createattrs.system = args->file_attrs & FILE_ATTRIBUTE_SYSTEM ? 1 : 0;
  370.          createattrs.archive = args->file_attrs & FILE_ATTRIBUTE_ARCHIVE ? 1 : 0;
  371. +#endif /* WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283 */
  372.  #ifdef NFS41_DRIVER_ALLOW_CREATEFILE_ACLS
  373.          if (create_nfs4_acl.aces) {
  374.              createattrs.acl = &create_nfs4_acl;
  375. @@ -1322,7 +1363,11 @@ supersede_retry:
  376.                      state);
  377.              }
  378.  #endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
  379. -
  380. +#ifdef WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283
  381. +            if (create == OPEN4_CREATE) {
  382. +                set_hiddensystem_attrs(args->file_attrs, state);
  383. +            }
  384. +#endif /* WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283 */
  385.              nfs_to_basic_info(state->file.name.name,
  386.                  state->file.fh.superblock,
  387.                  &info,
  388. diff --git a/nfs41_build_features.h b/nfs41_build_features.h
  389. index 227008f..4ebe0d2 100644
  390. --- a/nfs41_build_features.h
  391. +++ b/nfs41_build_features.h
  392. @@ -279,4 +279,17 @@
  393.   */
  394.  #define NFS41_WINSTREAMS_SUPPORT 1
  395.  
  396. +/*
  397. + * |WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283| - workaround
  398. + * for FreeBSD bug#292283 which causes file/dir creation to fail with |EPERM|
  399. + * if |FATTR4_SYSTEM| or |FATTR4_HIDDEN| attributes are provided to a FreeBSD
  400. + * 15.0 NFS server
  401. + *
  402. + * This workaround will be REMOVED as soon as FreeBSD 15.1 or a fixed kernel
  403. + * for FreeBSD 15.0 is available.
  404. + *
  405. + *
  406. + */
  407. +#define WORKAROUND_FOR_FREEBSD15_0_CREATIONFAILSWITHEPERM_BUG292283 1
  408. +
  409.  #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
  410. --
  411. 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