- From 1fb6631ecd9a75e4aeb592f250c3a9bb0f9a9687 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 3 Dec 2025 11:41:42 +0100
- Subject: [PATCH 1/8] sys: |nfs41_Create()|: Switch from
- |RxChangeBufferingState()|+|DISABLE_CACHING| to |RxFlushFcbInSystemCache(fcb,
- TRUE)|
- |nfs41_Create()|: Switch from |RxChangeBufferingState()|+|DISABLE_CACHING|
- to |RxFlushFcbInSystemCache(fcb, TRUE)| if the file is opened
- for data access.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_openclose.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 7a4d4ed..57b10d5 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -1189,21 +1189,25 @@ retry_on_link:
- print_std_info(1, &nfs41_fcb->StandardInfo);
- #endif
- - /* aglo: 05/10/2012. it seems like always have to invalid the cache if the
- + /*
- + * aglo: 05/10/2012: it seems like always have to invalid the cache if the
- * file has been opened before and being opened again for data access.
- * If the file was opened before, RDBSS might have cached (unflushed) data
- * and by opening it again, we will not have the correct representation of
- * the file size and data content. fileio tests 208, 219, 221.
- + * gisburn 2025-12-02: Switching from |RxChangeBufferingState()| with
- + * |DISABLE_CACHING| to |RxFlushFcbInSystemCache(fcb, TRUE)| incl.
- + * syncing with lazywriter (testing with parallel gcc build shows that
- + * just waiting for the lazy writer is not sufficient).
- */
- if (Fcb->OpenCount > 0 && (isDataAccess(params->DesiredAccess) ||
- nfs41_fcb->changeattr != entry->ChangeTime) &&
- !nfs41_fcb->StandardInfo.Directory) {
- - ULONG flag = DISABLE_CACHING;
- #ifdef DEBUG_OPEN
- DbgP("nfs41_Create: reopening (changed) file '%wZ'\n",
- SrvOpen->pAlreadyPrefixedName);
- #endif
- - RxChangeBufferingState((PSRV_OPEN)SrvOpen, ULongToPtr(flag), 1);
- + (void)RxFlushFcbInSystemCache((PFCB)RxContext->pFcb, TRUE);
- }
- if (!nfs41_fcb->StandardInfo.Directory &&
- --
- 2.51.0
- From 7cdf7984afb1a48386c45aac9307f3e1c52875f3 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 3 Dec 2025 12:37:37 +0100
- Subject: [PATCH 2/8] cygwin,tests: Add new /sbin/catdbgprint.exe utilty to
- print kernel |DbgPrint*()| messages to stdout
- Add new /sbin/catdbgprint.exe utilty to print kernel |DbgPrint*()|
- messages to stdout.
- This tool can also run multiple instances in parallel, allowing for
- automated tests to examine the kernel debug output.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- cygwin/Makefile | 4 +
- cygwin/Makefile.install | 2 +
- cygwin/devel/msnfs41client.bash | 31 +----
- tests/catdbgprint/Makefile | 26 ++++
- tests/catdbgprint/catdbgprint.c | 205 ++++++++++++++++++++++++++++++++
- 5 files changed, 240 insertions(+), 28 deletions(-)
- create mode 100644 tests/catdbgprint/Makefile
- create mode 100644 tests/catdbgprint/catdbgprint.c
- diff --git a/cygwin/Makefile b/cygwin/Makefile
- index cf2b036..5d058a9 100644
- --- a/cygwin/Makefile
- +++ b/cygwin/Makefile
- @@ -23,6 +23,7 @@ VS_BUILD_DIR_ARM64:=$(PROJECT_BASEDIR_DIR)/build.vc19/ARM64/Debug/
- # trigger "build_testutils" target when these binaries are needed
- $(PROJECT_BASEDIR_DIR)/tests/ea/nfs_ea.exe \
- + $(PROJECT_BASEDIR_DIR)/tests/catdbgprint/catdbgprint.exe \
- $(PROJECT_BASEDIR_DIR)/tests/lssparse/lssparse.exe \
- $(PROJECT_BASEDIR_DIR)/tests/winfsinfo1/winfsinfo.exe \
- $(PROJECT_BASEDIR_DIR)/tests/filemmaptests/qsortonmmapedfile1.exe \
- @@ -76,6 +77,7 @@ build_arm_64bit_debug:
- MSBuild.exe '$(shell cygpath -w "$(PROJECT_BASEDIR_DIR)/build.vc19/nfs41-client.sln")' -t:Build -p:Configuration=Debug -p:Platform=ARM64 /p:CERTIFICATE_THUMBPRINT=$$CERTIFICATE_THUMBPRINT
- build_testutils:
- + (cd "$(PROJECT_BASEDIR_DIR)/tests/catdbgprint" && make all)
- (cd "$(PROJECT_BASEDIR_DIR)/tests/ea" && make all)
- (cd "$(PROJECT_BASEDIR_DIR)/tests/lssparse" && make all)
- (cd "$(PROJECT_BASEDIR_DIR)/tests/winfsinfo1" && make all)
- @@ -117,6 +119,7 @@ build64: \
- #
- clean:
- rm -vRf $$(find "$(PROJECT_BASEDIR_DIR)/build.vc19" -name Debug -o -name Release)
- + (cd "$(PROJECT_BASEDIR_DIR)/tests/catdbgprint" && make clean)
- (cd "$(PROJECT_BASEDIR_DIR)/tests/ea" && make clean)
- (cd "$(PROJECT_BASEDIR_DIR)/tests/lssparse" && make clean)
- (cd "$(PROJECT_BASEDIR_DIR)/tests/winfsinfo1" && make clean)
- @@ -131,6 +134,7 @@ installdest_util: \
- $(PROJECT_BASEDIR_DIR)/nfs41rdr.inf \
- $(PROJECT_BASEDIR_DIR)/etc_netconfig \
- $(PROJECT_BASEDIR_DIR)/ms-nfs41-idmap.conf \
- + $(PROJECT_BASEDIR_DIR)/tests/catdbgprint/catdbgprint.exe \
- $(PROJECT_BASEDIR_DIR)/tests/ea/nfs_ea.exe \
- $(PROJECT_BASEDIR_DIR)/tests/lssparse/lssparse.exe \
- $(PROJECT_BASEDIR_DIR)/tests/winfsinfo1/winfsinfo.exe \
- diff --git a/cygwin/Makefile.install b/cygwin/Makefile.install
- index efb327d..1db56fc 100644
- --- a/cygwin/Makefile.install
- +++ b/cygwin/Makefile.install
- @@ -167,6 +167,8 @@ installdest:
- cp "$(PROJECT_BASEDIR_DIR)/tests/winclonefile/winclonefile.i686.exe" $(DESTDIR)/bin/winclonefile.i686.exe
- cp "$(PROJECT_BASEDIR_DIR)/tests/winoffloadcopyfile/winoffloadcopyfile.x86_64.exe" $(DESTDIR)/bin/winoffloadcopyfile.x86_64.exe
- cp "$(PROJECT_BASEDIR_DIR)/tests/winoffloadcopyfile/winoffloadcopyfile.i686.exe" $(DESTDIR)/bin/winoffloadcopyfile.i686.exe
- + cp "$(PROJECT_BASEDIR_DIR)/tests/catdbgprint/catdbgprint.x86_64.exe" $(DESTDIR)/sbin/catdbgprint.x86_64.exe
- + cp "$(PROJECT_BASEDIR_DIR)/tests/catdbgprint/catdbgprint.i686.exe" $(DESTDIR)/sbin/catdbgprint.i686.exe
- cp "$(PROJECT_BASEDIR_DIR)/tests/winrunassystem/winrunassystem.x86_64.exe" $(DESTDIR)/sbin/winrunassystem.x86_64.exe
- cp "$(PROJECT_BASEDIR_DIR)/tests/winrunassystem/winrunassystem.i686.exe" $(DESTDIR)/sbin/winrunassystem.i686.exe
- cp "$(PROJECT_BASEDIR_DIR)/tests/winrunassystem/nfs_globalmount.x86_64.exe" $(DESTDIR)/sbin/nfs_globalmount.x86_64.exe
- diff --git a/cygwin/devel/msnfs41client.bash b/cygwin/devel/msnfs41client.bash
- index 4e44571..4b769c7 100755
- --- a/cygwin/devel/msnfs41client.bash
- +++ b/cygwin/devel/msnfs41client.bash
- @@ -249,6 +249,7 @@ function nfsclient_install
- 'bin/winoffloadcopyfile'
- 'bin/winsg'
- 'bin/nfs_ea'
- + 'sbin/catdbgprint'
- 'sbin/winrunassystem'
- 'sbin/nfs_globalmount'
- 'usr/share/msnfs41client/tests/misc/qsortonmmapedfile1'
- @@ -939,29 +940,10 @@ function attach_debugger_to_daemon
- function watch_kernel_debuglog
- {
- - typeset dbgview_cmd
- -
- printf "# logging start...\n" 1>&2
- - case "$(uname -m)" in
- - 'x86_64') dbgview_cmd='dbgview64' ;;
- - 'i686') dbgview_cmd='dbgview' ;;
- - *)
- - printf $"%s: Unknown machine type\n" "$0" 1>&2
- - return 1
- - ;;
- - esac
- + catdbgprint
- - # seperate process so SIGINT works
- - # use DebugView (https://learn.microsoft.com/en-gb/sysinternals/downloads/debugview) to print kernel log
- - dbgview_cmd="${dbgview_cmd}" bash -c '
- - klogname="msnfs41client_watch_kernel_debuglog$$.log"
- - $dbgview_cmd /t /k /l "$klogname" &
- - (( dbgview_pid=$! ))
- - trap "(( dbgview_pid != 0)) && kill $dbgview_pid && wait ; (( dbgview_pid=0 ))" INT TERM EXIT
- - sleep 2
- - printf "# logging %s ...\n" "$klogname" 1>&2
- - tail -n0 -f "$klogname"'
- printf '# logging done\n' 1>&2
- return 0
- }
- @@ -1302,14 +1284,7 @@ function main
- ;;
- 'watch_kernel_debuglog')
- check_machine_arch || (( numerr++ ))
- - case "$(uname -m)" in
- - 'x86_64') require_cmd 'dbgview64' || (( numerr++ )) ;;
- - 'i686') require_cmd 'dbgview' || (( numerr++ )) ;;
- - *)
- - printf $"%s: Unknown machine type\n" "$0" 1>&2
- - (( numerr++ ))
- - ;;
- - esac
- + require_cmd 'catdbgprint' || (( numerr++ ))
- if ! is_windows_admin_account ; then
- printf $"%s: %q requires Windows Adminstator permissions.\n" "$0" "$cmd"
- (( numerr++ ))
- diff --git a/tests/catdbgprint/Makefile b/tests/catdbgprint/Makefile
- new file mode 100644
- index 0000000..ea75bd7
- --- /dev/null
- +++ b/tests/catdbgprint/Makefile
- @@ -0,0 +1,26 @@
- +#
- +# Makefile for catdbgprint
- +#
- +
- +# signtool.exe can be in either '/cygdrive/c/Program Files/' or '/cygdrive/c/Program Files (x86)/'
- +SIGNTOOL := $(shell ls -1 '/cygdrive/c/Program Files'*'/Microsoft SDKs/ClickOnce/SignTool/signtool.exe' | head -n 1)
- +
- +all: catdbgprint.i686.exe catdbgprint.x86_64.exe catdbgprint.exe
- +
- +catdbgprint.i686.exe: catdbgprint.c
- + clang -target i686-pc-windows-gnu -std=gnu17 -Wall -Wextra -DUNICODE=1 -D_UNICODE=1 -I../../include -g catdbgprint.c -lntdll -o $@
- + bash -x -c '"$(SIGNTOOL)" sign /ph /fd "sha256" /sha1 "$${CERTIFICATE_THUMBPRINT%$$(printf "\r")}" $@'
- +
- +catdbgprint.x86_64.exe: catdbgprint.c
- + clang -target x86_64-pc-windows-gnu -std=gnu17 -Wall -Wextra -DUNICODE=1 -D_UNICODE=1 -I../../include -g catdbgprint.c -lntdll -o $@
- + bash -x -c '"$(SIGNTOOL)" sign /ph /fd "sha256" /sha1 "$${CERTIFICATE_THUMBPRINT%$$(printf "\r")}" $@'
- +
- +catdbgprint.exe: catdbgprint.x86_64.exe
- + ln -s catdbgprint.x86_64.exe catdbgprint.exe
- +
- +clean:
- + rm -fv \
- + catdbgprint.i686.exe \
- + catdbgprint.x86_64.exe \
- + catdbgprint.exe
- +# EOF.
- diff --git a/tests/catdbgprint/catdbgprint.c b/tests/catdbgprint/catdbgprint.c
- new file mode 100644
- index 0000000..7f053e1
- --- /dev/null
- +++ b/tests/catdbgprint/catdbgprint.c
- @@ -0,0 +1,205 @@
- +/*
- + * MIT License
- + *
- + * Copyright (c) 2024-2025 Roland Mainz <roland.mainz@nrubsig.org>
- + *
- + * Permission is hereby granted, free of charge, to any person obtaining a copy
- + * of this software and associated documentation files (the "Software"), to deal
- + * in the Software without restriction, including without limitation the rights
- + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- + * copies of the Software, and to permit persons to whom the Software is
- + * furnished to do so, subject to the following conditions:
- + *
- + * The above copyright notice and this permission notice shall be included in
- + * all copies or substantial portions of the Software.
- + *
- + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- + * SOFTWARE.
- + */
- +
- +/*
- + * catdbgprint.c - print Windows kernel |DbgPrint()| messages
- + *
- + * Written by Roland Mainz <roland.mainz@nrubsig.org>
- + */
- +
- +/*
- + * Compile with:
- + * $ clang -target x86_64-pc-windows-gnu \
- + * -Wall -Wextra -DUNICODE=1 -D_UNICODE=1 -g catdbgprint.c -o catdbgprint.exe #
- + */
- +
- +#include <windows.h>
- +#include <evntrace.h>
- +#include <evntcons.h>
- +#include <stdio.h>
- +#include <stdlib.h>
- +#include <stddef.h>
- +#include <ctype.h>
- +
- +typedef struct _DBGPRINT_EVENT {
- + ULONG ComponentId; /* DPFLTR_xxx_ID */
- + ULONG Level; /* DPFLTR_LEVEL_xxx */
- + CHAR Message[]; /* '\0'-terminated ANSI string */
- +} DBGPRINT_EVENT;
- +
- +static
- +void int_to_octal3(int value, unsigned char *restrict out)
- +{
- + if (value < 0)
- + value = 0;
- + if (value > 0777)
- + value = 0777; /* clamp to max 0777/511 */
- +
- + out[2] = (char)('0' + (value & 7));
- + out[1] = (char)('0' + ((value >> 3) & 7));
- + out[0] = (char)('0' + ((value >> 6) & 7));
- +}
- +
- +static
- +VOID WINAPI EventCallback(PEVENT_RECORD ev)
- +{
- + unsigned char buffer[2048];
- + unsigned char *b = buffer;
- +
- + if (ev->UserDataLength >= offsetof(DBGPRINT_EVENT, Message)) {
- + size_t i;
- + unsigned char c;
- + const DBGPRINT_EVENT *dpe = (const DBGPRINT_EVENT *)ev->UserData;
- + const unsigned char *msg = (const unsigned char *)dpe->Message;
- + ssize_t msg_len = ev->UserDataLength - offsetof(DBGPRINT_EVENT, Message);
- +
- + for (i=0 ; i < msg_len ; i++) {
- + if ((msg[i] == '\0') ||
- + ((msg[i] == '\n') && (msg[i+1] == '\0')))
- + break;
- +
- + c = msg[i];
- +
- + if (c == '\n') {
- + *b++ = '\\';
- + *b++ = 'n';
- + }
- + else if (c == '\v') {
- + *b++ = '\\';
- + *b++ = 'v';
- + }
- + else if (c == '\f') {
- + *b++ = '\\';
- + *b++ = 'f';
- + }
- + else if (c == '\r') {
- + *b++ = '\\';
- + *b++ = 'r';
- + }
- + else if (c == '\t') {
- + *b++ = '\\';
- + *b++ = 't';
- + }
- + else if (c == '\b') {
- + *b++ = '\\';
- + *b++ = 'b';
- + }
- + else if (c == '\a') {
- + *b++ = '\\';
- + *b++ = 'a';
- + }
- + else if (c == '\\') {
- + /*
- + * We only print one backslash, otherwise we cause problems
- + * with the user expectation that they can copy&&paste Windows
- + * paths.
- + * FIXME: There should be a command-line argument to define
- + * how to handle non-printable+backslash characters (e.g.
- + * "human readable", "always octal escaped",
- + * "ksh93 compound variable array", ...)
- + */
- + *b++ = '\\';
- + }
- + else if ((c > 127) || isprint((int)c)) {
- + *b++ = c;
- + }
- + else {
- + *b++ = '\\';
- + int_to_octal3(c, b);
- + b+=3;
- + }
- + }
- +
- + *b++ = '\0';
- + (void)fprintf(stdout, "%s\n", buffer);
- + }
- +}
- +
- +int main(int ac, char *av[])
- +{
- + TRACEHANDLE hSession = 0;
- + TRACEHANDLE hTrace = 0;
- + ULONG status;
- + int retval = EXIT_SUCCESS;
- +
- + (void)ac;
- +
- + size_t propsSize = sizeof(EVENT_TRACE_PROPERTIES) + 1024;
- + EVENT_TRACE_PROPERTIES *props = (EVENT_TRACE_PROPERTIES*)calloc(1, propsSize);
- + if (props == NULL) {
- + (void)fprintf(stderr, "%s: Malloc failed\n", av[0]);
- + retval = EXIT_FAILURE;
- + goto done;
- + }
- +
- + props->Wnode.BufferSize = (ULONG)propsSize;
- + props->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
- + props->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
- + props->EnableFlags = EVENT_TRACE_FLAG_DBGPRINT;
- + props->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
- +#if 1
- + /* Increase buffer size to 32MB */
- + props->BufferSize = 64; /* Buffer size in KB (64KB per buffer) */
- + props->MinimumBuffers = 512; /* Minimum buffers */
- + props->MaximumBuffers = 512; /* Maximum buffers */
- +#endif
- +
- + status = StartTraceW(&hSession, KERNEL_LOGGER_NAME, props);
- + if (status == ERROR_ALREADY_EXISTS) {
- + (void)fprintf(stderr,
- + "#### Kernel Logger already running, attaching...\n");
- + hSession = 0;
- + } else if (status != ERROR_SUCCESS) {
- + (void)fprintf(stderr, "%s: StartTraceA() failed with error=%d\n",
- + av[0], (int)status);
- + retval = EXIT_FAILURE;
- + goto done;
- + } else {
- + (void)fprintf(stderr,
- + "#### Started Kernel Logger session.\n");
- + }
- +
- + EVENT_TRACE_LOGFILE log = {
- + .LoggerName = KERNEL_LOGGER_NAME,
- + .ProcessTraceMode =
- + PROCESS_TRACE_MODE_REAL_TIME |
- + PROCESS_TRACE_MODE_EVENT_RECORD,
- + .EventRecordCallback = EventCallback
- + };
- +
- + hTrace = OpenTrace(&log);
- + if (hTrace == INVALID_PROCESSTRACE_HANDLE) {
- + (void)fprintf(stderr, "%s: OpenTrace() failed with error=%d\n",
- + av[0], (int)GetLastError());
- + retval = EXIT_FAILURE;
- + goto done;
- + }
- +
- + (void)fprintf(stderr,
- + "#### Listening for |DbgPrint*()| messages...\n");
- + status = ProcessTrace(&hTrace, 1, NULL, NULL);
- +
- +done:
- + return retval;
- +}
- --
- 2.51.0
- From ad7800c72c5922105fc307073154c099069c15d1 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Aur=C3=A9lien=20Couderc?= <aurelien.couderc2002@gmail.com>
- Date: Wed, 3 Dec 2025 12:50:19 +0100
- Subject: [PATCH 3/8] README.md,docs: Improve comment about using NFS as MSYS2
- root filesystem
- Improve comment about using NFS as MSYS2 root filesystem.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- README.md | 4 ++--
- docs/README.xml | 2 +-
- 2 files changed, 3 insertions(+), 3 deletions(-)
- diff --git a/README.md b/README.md
- index df8c22b..589ab63 100644
- --- a/README.md
- +++ b/README.md
- @@ -367,8 +367,8 @@ Cygwin 32bit can be installed like this:
- pacman -S --noconfirm base-devel gcc clang sed time coreutils util-linux grep sed emacs gdb make autoconf automake gettext gettext-devel git subversion flex bison unzip pax tar libiconv-devel ncurses-devel gmp-devel mpfr-devel mpc-devel isl-devel procps-ng libiconv-devel
- > [!NOTE]
- -> NFS filesystem used the MSYS root filesystem must be mounted as global
- -> filesystem
- +> NFS filesystem used as MSYS root filesystem (`/`) must be mounted as
- +> global filesystem (e.g. use `nfs_globalmount.exe`)
- >
- > <div>
- >
- diff --git a/docs/README.xml b/docs/README.xml
- index 5c0d941..1d34228 100644
- --- a/docs/README.xml
- +++ b/docs/README.xml
- @@ -500,7 +500,7 @@ chmod a+x 'msys2-x86_64-20250830.exe'
- </orderedlist>
- <note>
- <title>Installing MSYS on NFS filesystem</title>
- - <para>NFS filesystem used the MSYS root filesystem must be mounted as global filesystem</para>
- + <para>NFS filesystem used as MSYS root filesystem (<filename>/</filename>) must be mounted as global filesystem (e.g. use <command>nfs_globalmount.exe</command>)</para>
- <orderedlist>
- <title>Known issues</title>
- <listitem><para>Edit <filename>/etc/pacman.conf</filename> and set <programlisting>SigLevel = Never</programlisting>, because due to a Cygwin/MSYS2 bug there is a mismatch between Cygwin/MSYS2 POSIX uid/gid and Win32 owner/owner_group SIDs</para></listitem>
- --
- 2.51.0
- From 17c63ca23b066574bbc21932b6815407949cdb43 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Aur=C3=A9lien=20Couderc?= <aurelien.couderc2002@gmail.com>
- Date: Wed, 3 Dec 2025 13:09:57 +0100
- Subject: [PATCH 4/8] README.md,docs: Improve Windows requirement documentation
- Improve Windows requirement documentation.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- README.md | 14 ++++++++++++--
- docs/README.xml | 17 ++++++++++++++++-
- 2 files changed, 28 insertions(+), 3 deletions(-)
- diff --git a/README.md b/README.md
- index 589ab63..aea5dcd 100644
- --- a/README.md
- +++ b/README.md
- @@ -260,8 +260,18 @@ NFSv4.2/NFSv4.1 filesystem driver for Windows 10/11 & Windows Server
- # Requirements
- -- Windows 10 (32bit or 64bit), Windows 11 or Windows Server
- - 2019+2022+2025
- +- Operarting system:
- +
- + - Windows 10 (32bit or 64bit)
- + - Windows 11 (64bit)
- + - Windows Server 2019 (64bit)
- + - Windows Server 2022 (64bit)
- + - Windows Server 2025 (64bit)
- +
- + (Requires `NTFS`, `ReFS` or
- + [`WinBTRFS`](https://github.com/maharmstone/btrfs) for System Volume
- + (`C:`); the installer requires hardlink support, which `FAT` does not
- + support)
- - Cygwin:
- diff --git a/docs/README.xml b/docs/README.xml
- index 1d34228..c264cac 100644
- --- a/docs/README.xml
- +++ b/docs/README.xml
- @@ -301,7 +301,22 @@
- <title>Requirements</title>
- <itemizedlist>
- <listitem>
- - <para>Windows 10 (32bit or 64bit), Windows 11 or Windows Server 2019+2022+2025</para>
- + <para>Operarting system:
- + <itemizedlist>
- + <listitem>Windows 10 (32bit or 64bit)</listitem>
- + <listitem>Windows 11 (64bit)</listitem>
- + <listitem>Windows Server 2019 (64bit)</listitem>
- + <listitem>Windows Server 2022 (64bit)</listitem>
- + <listitem>Windows Server 2025 (64bit)</listitem>
- + </itemizedlist>
- + </para>
- + <para>(Requires <literal>NTFS</literal>,
- + <literal>ReFS</literal> or
- + <link xl:href="https://github.com/maharmstone/btrfs"><literal>WinBTRFS</literal></link>
- + for System Volume (<filename>C:</filename>); the installer
- + requires hardlink support, which <literal>FAT</literal>
- + does not support)
- + </para>
- </listitem>
- <listitem>
- <para>Cygwin:
- --
- 2.51.0
- From 23eb1d6f076ddeaeedbaa7e1c3395990c9811d00 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Aur=C3=A9lien=20Couderc?= <aurelien.couderc2002@gmail.com>
- Date: Wed, 3 Dec 2025 14:35:51 +0100
- Subject: [PATCH 5/8] tests: Fix Win11/2022 build failure in winfsinfo.c
- Fix Win11/2022 build failure in winfsinfo.c.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/winfsinfo1/winfsinfo.c | 5 +++++
- 1 file changed, 5 insertions(+)
- diff --git a/tests/winfsinfo1/winfsinfo.c b/tests/winfsinfo1/winfsinfo.c
- index dc103e1..e81e0b4 100644
- --- a/tests/winfsinfo1/winfsinfo.c
- +++ b/tests/winfsinfo1/winfsinfo.c
- @@ -1187,8 +1187,13 @@ int get_file_remote_protocol_info(const char *progname, const char *filename)
- (void)printf("\t\t\tcompound Share=(\n");
- (void)printf("\t\t\t\tCapabilities=0x%lx\n",
- (unsigned long)frpi.ProtocolSpecific.Smb2.Share.Capabilities);
- +#if NTDDI_VERSION >= NTDDI_WIN10_NI
- (void)printf("\t\t\t\tShareFlags=0x%lx\n",
- (unsigned long)frpi.ProtocolSpecific.Smb2.Share.ShareFlags);
- +#else
- + (void)printf("\t\t\t\tCachingFlags=0x%lx\n",
- + (unsigned long)frpi.ProtocolSpecific.Smb2.Share.CachingFlags);
- +#endif /* NTDDI_VERSION >= NTDDI_WIN10_NI */
- #if 0 /* MinGW header do not have these fields yet */
- (void)printf("\t\t\t\tCachingFlags=0x%lx\n",
- (unsigned long)frpi.ProtocolSpecific.Smb2.Share.CachingFlags);
- --
- 2.51.0
- From 02c643c308023741da84d90922cc93cc1ddd8aa7 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 3 Dec 2025 15:41:17 +0100
- Subject: [PATCH 6/8] README.md,docs: Document status of create-file-with-ACL
- NFS server support
- Document status of create-file-with-ACL NFS server support.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- README.md | 22 +++++++++++++++++++---
- docs/README.xml | 12 +++++++++---
- 2 files changed, 28 insertions(+), 6 deletions(-)
- diff --git a/README.md b/README.md
- index aea5dcd..0b9c4a0 100644
- --- a/README.md
- +++ b/README.md
- @@ -807,9 +807,25 @@ Within WSL mount UNC path returned by `/sbin/nfs_mount`
- which support `FATTR4_ACL`/`FATTR4_DACL` for `OPEN`/`CREATE`
- operations.
- - So far FreeBSD 14.3 and the NFS-Ganesha NFS servers are known to
- - support this, while Linux 6.12.\*, Solaris 11.4 and Illumos NFS
- - servers ignore the ACL on `OPEN`/`CREATE` operations.
- + Status:
- +
- + - FreeBSD 14.3 nfsd: Works
- +
- + - NFS-Ganesha NFS server: Works
- +
- + - Linux kernel server: Requires patch
- +
- + ([f9a48423f6ff5198257e508c5ef1ff0ec1be4465 - "NFSD: NFSv4 file
- + creation neglects setting
- + ACL"](https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git/commit/?h=nfsd-testing&id=f9a48423f6ff5198257e508c5ef1ff0ec1be4465))
- +
- + - Solaris 11.4 nfsd: Does not work
- +
- + (ignores the ACL on `OPEN`/`CREATE` operations)
- +
- + - Illumos NFSv4.2 nfsd: Does not work
- +
- + (ignores the ACL on `OPEN`/`CREATE` operations)
- # Troubleshooting && finding bugs/debugging
- diff --git a/docs/README.xml b/docs/README.xml
- index c264cac..4821cf9 100644
- --- a/docs/README.xml
- +++ b/docs/README.xml
- @@ -907,9 +907,15 @@ Datei befindet. Versuchen Sie, die Datei woanders zu speichern.</programlisting>
- <literal>FATTR4_ACL</literal>/<literal>FATTR4_DACL</literal> for
- <literal>OPEN</literal>/<literal>CREATE</literal>
- operations.</para>
- - <para>So far FreeBSD 14.3 and the NFS-Ganesha NFS servers are known to support this,
- - while Linux 6.12.*, Solaris 11.4 and Illumos NFS servers ignore the ACL on
- - <literal>OPEN</literal>/<literal>CREATE</literal> operations.</para>
- + <para>Status:
- + <itemizedlist>
- + <listitem><para>FreeBSD 14.3 nfsd: Works</para></listitem>
- + <listitem><para>NFS-Ganesha NFS server: Works</para></listitem>
- + <listitem><para>Linux kernel server: Requires patch</para><para>(<link xl:href="https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git/commit/?h=nfsd-testing&id=f9a48423f6ff5198257e508c5ef1ff0ec1be4465">f9a48423f6ff5198257e508c5ef1ff0ec1be4465 - "NFSD: NFSv4 file creation neglects setting ACL"</link>)</para></listitem>
- + <listitem><para>Solaris 11.4 nfsd: Does not work</para><para>(ignores the ACL on <literal>OPEN</literal>/<literal>CREATE</literal> operations)</para></listitem>
- + <listitem><para>Illumos NFSv4.2 nfsd: Does not work</para><para>(ignores the ACL on <literal>OPEN</literal>/<literal>CREATE</literal> operations)</para></listitem>
- + </itemizedlist>
- + </para>
- </listitem>
- </itemizedlist>
- </section>
- --
- 2.51.0
- From 15f00908f394ed7b1f37651e4934bab0cfbc3aea Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 3 Dec 2025 19:58:39 +0100
- Subject: [PATCH 7/8] sys: Use |RxFlushFcbInSystemCache(fcb,TRUE)| to flush
- {src,dest} files for
- |FSCTL_SET_ZERO_DATA|,|FSCTL_DUPLICATE_EXTENTS_TO_FILE|,|FSCTL_OFFLOAD_WRITE|
- Use |RxFlushFcbInSystemCache(fcb,TRUE)| to flush {src,dest} files for
- |FSCTL_SET_ZERO_DATA|, |FSCTL_DUPLICATE_EXTENTS_TO_FILE| and
- |FSCTL_OFFLOAD_WRITE|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_fsctl.c | 155 +++++++++++++++++++++++++++++--------------
- 1 file changed, 105 insertions(+), 50 deletions(-)
- diff --git a/sys/nfs41sys_fsctl.c b/sys/nfs41sys_fsctl.c
- index 25c1290..696f9c8 100644
- --- a/sys/nfs41sys_fsctl.c
- +++ b/sys/nfs41sys_fsctl.c
- @@ -459,6 +459,7 @@ NTSTATUS nfs41_SetZeroData(
- __notnull const PFILE_ZERO_DATA_INFORMATION setzerodatabuffer =
- (const PFILE_ZERO_DATA_INFORMATION)FsCtl->pInputBuffer;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- + bool fcb_locked_exclusive = false;
- DbgEn();
- @@ -482,23 +483,29 @@ NTSTATUS nfs41_SetZeroData(
- goto out;
- }
- + status = RxAcquireExclusiveFcbResourceInMRx(RxContext->pFcb);
- + if (!NT_SUCCESS(status)) {
- + DbgP("nfs41_SetZeroData: "
- + "RxAcquireExclusiveFcbResourceInMRx() failed, status=0x%lx\n",
- + status);
- + goto out;
- + }
- + fcb_locked_exclusive = true;
- +
- DbgP("nfs41_SetZeroData: "
- "setzerodatabuffer=(FileOffset=%lld,BeyondFinalZero=%lld)\n",
- (long long)setzerodatabuffer->FileOffset.QuadPart,
- (long long)setzerodatabuffer->BeyondFinalZero.QuadPart);
- /*
- - * Disable caching because NFSv4.2 DEALLOCATE is basically a
- - * "write" operation. AFAIK we should flush the cache and wait
- - * for the kernel lazy writer (which |RxChangeBufferingState()|
- - * AFAIK does) before doing the DEALLOCATE, to avoid that we
- - * have outstanding writes in the kernel cache at the same
- - * location where the DEALLOCATE should do it's work
- + * NFSv4.2 DEALLOCATE is basically a "write" operation, but happens
- + * only on the NFS server side. We need to flush our NFS client
- + * cache and wait for the kernel lazy writer before doing the
- + * DEALLOCATE, to avoid that we have outstanding writes in the
- + * kernel cache at the same location where the DEALLOCATE should
- + * do it's work.
- */
- - ULONG flag = DISABLE_CACHING;
- - DbgP("nfs41_SetZeroData: disableing caching for file '%wZ'\n",
- - SrvOpen->pAlreadyPrefixedName);
- - RxChangeBufferingState((PSRV_OPEN)SrvOpen, ULongToPtr(flag), 1);
- + (void)RxFlushFcbInSystemCache((PFCB)RxContext->pFcb, TRUE);
- status = nfs41_UpcallCreate(NFS41_SYSOP_FSCTL_SET_ZERO_DATA,
- &nfs41_fobx->sec_ctx,
- @@ -534,6 +541,10 @@ NTSTATUS nfs41_SetZeroData(
- }
- out:
- + if (fcb_locked_exclusive) {
- + RxReleaseFcbResourceInMRx(RxContext->pFcb);
- + }
- +
- if (entry) {
- nfs41_UpcallDestroy(entry);
- }
- @@ -639,6 +650,10 @@ NTSTATUS nfs41_DuplicateData(
- __notnull XXCTL_LOWIO_COMPONENT *FsCtl =
- &RxContext->LowIoContext.ParamsFor.FsCtl;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- + PFCB srcfcb = NULL;
- + PFOBX srcfox = NULL;
- + bool src_fcb_locked_exclusive = false;
- + bool dest_fcb_locked_exclusive = false;
- /*
- * Temporary store |FSCTL_DUPLICATE_EXTENTS_TO_FILE| data here, which
- @@ -751,8 +766,8 @@ NTSTATUS nfs41_DuplicateData(
- goto out;
- }
- - PFCB srcfcb = srcfo->FsContext;
- - PFOBX srcfox = srcfo->FsContext2;
- + srcfcb = srcfo->FsContext;
- + srcfox = srcfo->FsContext2;
- PNFS41_FCB nfs41_src_fcb = NFS41GetFcbExtension(srcfcb);
- PNFS41_SRV_OPEN src_nfs41_srvopen = NFS41GetSrvOpenExtension(srcfox->SrvOpen);
- @@ -768,38 +783,39 @@ NTSTATUS nfs41_DuplicateData(
- goto out;
- }
- - IO_STATUS_BLOCK flushIoStatus;
- - DbgP("nfs41_DuplicateData: flushing src file buffers\n");
- - status = ZwFlushBuffersFile(dd.handle, &flushIoStatus);
- - if (status) {
- - if (status == STATUS_ACCESS_DENIED) {
- - /*
- - * |ZwFlushBuffersFile()| can fail if |dd.handle| was not opened
- - * for write access
- - */
- - DbgP("nfs41_DuplicateData: "
- - "ZwFlushBuffersFile() failed with STATUS_ACCESS_DENIED\n");
- - }
- - else {
- - DbgP("nfs41_DuplicateData: "
- - "ZwFlushBuffersFile() failed, status=0x%lx\n",
- - (long)status);
- - goto out;
- - }
- + status = RxAcquireExclusiveFcbResourceInMRx((PMRX_FCB)srcfcb);
- + if (!NT_SUCCESS(status)) {
- + DbgP("nfs41_DuplicateData: "
- + "RxAcquireExclusiveFcbResourceInMRx() failed, status=0x%lx\n",
- + status);
- + goto out;
- + }
- + src_fcb_locked_exclusive = true;
- +
- + status = RxAcquireExclusiveFcbResourceInMRx(RxContext->pFcb);
- + if (!NT_SUCCESS(status)) {
- + DbgP("nfs41_DuplicateData: "
- + "RxAcquireExclusiveFcbResourceInMRx() failed, status=0x%lx\n",
- + status);
- + goto out;
- }
- + dest_fcb_locked_exclusive = true;
- /*
- - * Disable caching because NFSv4.2 CLONE is basically a
- - * "write" operation. AFAIK we should flush the cache and wait
- - * for the kernel lazy writer (which |RxChangeBufferingState()|
- - * AFAIK does) before doing the CLONE, to avoid that we
- - * have outstanding writes in the kernel cache at the same
- - * location where the CLONE should do it's work
- + * NFSv4.2 CLONE is basically a "write" operation, but happens
- + * only on the NFS server side. We need to flush our NFS client
- + * cache (for both src and dest files!!) and wait in both cases
- + * for the kernel lazy writer before doing the CLONE, to avoid
- + * that we have outstanding writes in the kernel cache at the
- + * same location where the CLONE should do it's work.
- */
- - ULONG flag = DISABLE_CACHING;
- - DbgP("nfs41_DuplicateData: disableing caching for file '%wZ'\n",
- - SrvOpen->pAlreadyPrefixedName);
- - RxChangeBufferingState((PSRV_OPEN)SrvOpen, ULongToPtr(flag), 1);
- + DbgP("nfs41_DuplicateData: flushing src file '%wZ'\n",
- + srcfox->SrvOpen->pAlreadyPrefixedName);
- + (void)RxFlushFcbInSystemCache((PFCB)srcfcb, TRUE);
- +
- + DbgP("nfs41_DuplicateData: flushing dest file '%wZ'\n",
- + RxContext->pRelevantSrvOpen->pAlreadyPrefixedName);
- + (void)RxFlushFcbInSystemCache((PFCB)RxContext->pFcb, TRUE);
- status = nfs41_UpcallCreate(NFS41_SYSOP_FSCTL_DUPLICATE_DATA,
- &nfs41_fobx->sec_ctx,
- @@ -842,6 +858,14 @@ NTSTATUS nfs41_DuplicateData(
- }
- out:
- + if (src_fcb_locked_exclusive) {
- + RxReleaseFcbResourceInMRx((PMRX_FCB)srcfcb);
- + }
- +
- + if (dest_fcb_locked_exclusive) {
- + RxReleaseFcbResourceInMRx(RxContext->pFcb);
- + }
- +
- if (entry) {
- nfs41_UpcallDestroy(entry);
- }
- @@ -1185,6 +1209,8 @@ NTSTATUS nfs41_OffloadWrite(
- &RxContext->LowIoContext.ParamsFor.FsCtl;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- offloadcontext_entry *src_oce = NULL;
- + bool src_fcb_locked_exclusive = false;
- + bool dest_fcb_locked_exclusive = false;
- struct {
- LONGLONG srcfileoffset;
- @@ -1291,18 +1317,39 @@ NTSTATUS nfs41_OffloadWrite(
- PNFS41_SRV_OPEN src_nfs41_srvopen =
- NFS41GetSrvOpenExtension(src_oce->src_srvopen);
- + status = RxAcquireExclusiveFcbResourceInMRx(src_oce->src_srvopen->pFcb);
- + if (!NT_SUCCESS(status)) {
- + DbgP("nfs41_OffloadWrite: "
- + "RxAcquireExclusiveFcbResourceInMRx() failed, status=0x%lx\n",
- + status);
- + goto out;
- + }
- + src_fcb_locked_exclusive = true;
- +
- + status = RxAcquireExclusiveFcbResourceInMRx(RxContext->pFcb);
- + if (!NT_SUCCESS(status)) {
- + DbgP("nfs41_OffloadWrite: "
- + "RxAcquireExclusiveFcbResourceInMRx() failed, status=0x%lx\n",
- + status);
- + goto out;
- + }
- + dest_fcb_locked_exclusive = true;
- +
- /*
- - * Disable caching because NFSv4.2 COPY is basically a
- - * "write" operation. AFAIK we should flush the cache and wait
- - * for the kernel lazy writer (which |RxChangeBufferingState()|
- - * AFAIK does) before doing the COPY, to avoid that we
- - * have outstanding writes in the kernel cache at the same
- - * location where the COPY should do it's work
- + * NFSv4.2 COPY is basically a "write" operation, but happens
- + * only on the NFS server side. We need to flush our NFS client
- + * cache (for both src and dest files!!) and wait in both cases
- + * for the kernel lazy writer before doing the COPY, to avoid
- + * that we have outstanding writes in the kernel cache at the
- + * same location where the COPY should do it's work.
- */
- - ULONG flag = DISABLE_CACHING;
- - DbgP("nfs41_OffloadWrite: disableing caching for file '%wZ'\n",
- - SrvOpen->pAlreadyPrefixedName);
- - RxChangeBufferingState((PSRV_OPEN)SrvOpen, ULongToPtr(flag), 1);
- + DbgP("nfs41_OffloadWrite: flushing src file '%wZ'\n",
- + src_oce->src_srvopen->pAlreadyPrefixedName);
- + (void)RxFlushFcbInSystemCache((PFCB)src_oce->src_srvopen->pFcb, TRUE);
- +
- + DbgP("nfs41_OffloadWrite: flushing dest file '%wZ'\n",
- + RxContext->pRelevantSrvOpen->pAlreadyPrefixedName);
- + (void)RxFlushFcbInSystemCache((PFCB)RxContext->pFcb, TRUE);
- status = nfs41_UpcallCreate(NFS41_SYSOP_FSCTL_OFFLOAD_DATACOPY,
- &nfs41_fobx->sec_ctx,
- @@ -1350,6 +1397,14 @@ NTSTATUS nfs41_OffloadWrite(
- }
- out:
- + if (src_fcb_locked_exclusive) {
- + RxReleaseFcbResourceInMRx(src_oce->src_srvopen->pFcb);
- + }
- +
- + if (dest_fcb_locked_exclusive) {
- + RxReleaseFcbResourceInMRx(RxContext->pFcb);
- + }
- +
- if (src_oce) {
- /* Release resource we obtained in shared mode */
- ExReleaseResourceLite(&src_oce->resource);
- --
- 2.51.0
- From b79a9ea32708261cf292d31a957a2fad8d420803 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 3 Dec 2025 21:36:44 +0100
- Subject: [PATCH 8/8] sys: Fix |nfs41_DuplicateData()| crash on Windows/32bit
- with faulty string pointer
- Fix |nfs41_DuplicateData()| crash on Windows/32bit with faulty
- string pointer.
- Reported-by: Cedric Blancher <cedric.blancher@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_fsctl.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_fsctl.c b/sys/nfs41sys_fsctl.c
- index 696f9c8..686b139 100644
- --- a/sys/nfs41sys_fsctl.c
- +++ b/sys/nfs41sys_fsctl.c
- @@ -756,7 +756,7 @@ NTSTATUS nfs41_DuplicateData(
- DbgP("nfs41_DuplicateData: "
- "srcfo=0x%p srcfo->FileName='%wZ'\n",
- srcfo,
- - srcfo->FileName);
- + &srcfo->FileName);
- if (srcfo->DeviceObject !=
- RxContext->CurrentIrpSp->FileObject->DeviceObject) {
- --
- 2.51.0
msnfs41client: Patches for kernel file flushing, catdbgprint.exe, docs+misc, 2025-12-03
Posted by Anonymous on Wed 3rd Dec 2025 20:45
raw | new post
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.
rovema.kpaste.net RSS