- From d1a302baf4bdb79db3ebd3d0e49cfeff06931c64 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Tue, 18 Nov 2025 12:28:39 +0100
- Subject: [PATCH 01/28] daemon: |FATTR4_WORD2_MODE_SET_MASKED| uses both
- |mode_mask| AND |mode|
- |FATTR4_WORD2_MODE_SET_MASKED| uses both |mode_mask| AND |mode|
- of |nfs41_file_info|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/fileinfoutil.c | 1 +
- daemon/nfs41_types.h | 1 +
- 2 files changed, 2 insertions(+)
- diff --git a/daemon/fileinfoutil.c b/daemon/fileinfoutil.c
- index 3466cfd..fe24b0a 100644
- --- a/daemon/fileinfoutil.c
- +++ b/daemon/fileinfoutil.c
- @@ -628,6 +628,7 @@ void nfs41_file_info_cpy(
- }
- if (attrmask->count > 2) {
- if (attrmask->arr[2] & FATTR4_WORD2_MODE_SET_MASKED) {
- + dest->mode = src->mode;
- dest->mode_mask = src->mode_mask;
- }
- if (attrmask->arr[2] & FATTR4_WORD2_MDSTHRESHOLD) {
- diff --git a/daemon/nfs41_types.h b/daemon/nfs41_types.h
- index bded8db..6b1cf12 100644
- --- a/daemon/nfs41_types.h
- +++ b/daemon/nfs41_types.h
- @@ -216,6 +216,7 @@ typedef struct __nfs41_file_info {
- uint32_t numlinks;
- uint32_t rdattr_error;
- uint32_t mode;
- + /* |FATTR4_WORD2_MODE_SET_MASKED| uses |mode| AND |mode_mask| */
- uint32_t mode_mask;
- char *owner;
- char *owner_group;
- --
- 2.51.0
- From 8fcc72c1155e95bd1d0d453dc94f5cc132be7e4e Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Tue, 18 Nov 2025 18:36:40 +0100
- Subject: [PATCH 02/28] daemon: Only toggle |FILE_ATTRIBUTE_READONLY| if
- |FILE_ATTRIBUTE_NORMAL| is set
- Only toggle |FILE_ATTRIBUTE_READONLY| if |FILE_ATTRIBUTE_NORMAL| is set,
- otherwise we can accidently stomp over valid mode bits.
- This is actually what Windows Explorer does: It will set
- |FILE_ATTRIBUTE_NORMAL| when it wants to change flags like
- |FILE_ATTRIBUTE_READONLY|, |FILE_ATTRIBUTE_HIDDEN|,
- |FILE_ATTRIBUTE_SYSTEM|, or |FILE_ATTRIBUTE_ARCHIVE|, and
- keeps |FILE_BASIC_INFORMATION->FileAttributes == 0x0| if it
- does not wish to change any attributes.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/setattr.c | 32 ++++++++++++++++++++++----------
- 1 file changed, 22 insertions(+), 10 deletions(-)
- diff --git a/daemon/setattr.c b/daemon/setattr.c
- index 971b973..8c281e9 100644
- --- a/daemon/setattr.c
- +++ b/daemon/setattr.c
- @@ -101,6 +101,18 @@ static int handle_nfs41_setattr_basicinfo(void *daemon_context,
- goto out;
- }
- + /*
- + * Set file attributes
- + *
- + * Notes:
- + * - MS-FSCC 2.6 File Attributes: "... There is no file attribute with the
- + * value 0x00000000 because a value of 0x00000000 in the FileAttributes
- + * field means that the file attributes for this file MUST NOT be changed
- + * when setting basic information for the file. ..."
- + * - Windows Explorer will set |FILE_ATTRIBUTE_NORMAL| when it wants
- + * to change flags like |FILE_ATTRIBUTE_READONLY|, |FILE_ATTRIBUTE_HIDDEN|,
- + * |FILE_ATTRIBUTE_SYSTEM|, |FILE_ATTRIBUTE_ARCHIVE|
- + */
- if (basic_info->FileAttributes) {
- info.hidden = basic_info->FileAttributes & FILE_ATTRIBUTE_HIDDEN ? 1 : 0;
- info.system = basic_info->FileAttributes & FILE_ATTRIBUTE_SYSTEM ? 1 : 0;
- @@ -127,20 +139,20 @@ static int handle_nfs41_setattr_basicinfo(void *daemon_context,
- ("handle_nfs41_setattr_basicinfo(args->path='%s)': "
- "Unsupported flag FILE_ATTRIBUTE_COMPRESSED ignored.\n",
- args->path));
- - }
- - /* mode */
- - if (basic_info->FileAttributes & FILE_ATTRIBUTE_READONLY) {
- - info.mode = 0444;
- - info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
- - info.attrmask.count = __max(info.attrmask.count, 2);
- - }
- - else {
- - if (old_info.mode == 0444) {
- - info.mode = 0644;
- + /* mode */
- + if (basic_info->FileAttributes & FILE_ATTRIBUTE_READONLY) {
- + info.mode = 0444;
- info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
- info.attrmask.count = __max(info.attrmask.count, 2);
- }
- + else {
- + if (old_info.mode == 0444) {
- + info.mode = 0644;
- + info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
- + info.attrmask.count = __max(info.attrmask.count, 2);
- + }
- + }
- }
- if (superblock->cansettime) {
- --
- 2.51.0
- From bebe7a51289c241e336edc151bf960b04d5416fa Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Tue, 18 Nov 2025 19:39:14 +0100
- Subject: [PATCH 03/28] daemon: Setting/getting |FILE_ATTRIBUTE_READONLY|
- should not touch "x"/setid mode bits
- Setting/getting |FILE_ATTRIBUTE_READONLY| should not touch any
- of the "x"/set@(uid|gid) mode bits.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/fileinfoutil.c | 2 +-
- daemon/setattr.c | 48 +++++++++++++++++++++++++++++++++++--------
- 2 files changed, 40 insertions(+), 10 deletions(-)
- diff --git a/daemon/fileinfoutil.c b/daemon/fileinfoutil.c
- index fe24b0a..0dca8ad 100644
- --- a/daemon/fileinfoutil.c
- +++ b/daemon/fileinfoutil.c
- @@ -74,7 +74,7 @@ ULONG nfs_file_info_to_attributes(
- EASSERT(bitmap_isset(&info->attrmask, 1, FATTR4_WORD1_MODE));
- if (bitmap_isset(&info->attrmask, 1, FATTR4_WORD1_MODE)) {
- - if (info->mode == 0444) /* XXX: 0444 for READONLY */
- + if ((info->mode & 0666) == 0444) /* XXX: 0444 for READONLY */
- attrs |= FILE_ATTRIBUTE_READONLY;
- }
- diff --git a/daemon/setattr.c b/daemon/setattr.c
- index 8c281e9..20a81e3 100644
- --- a/daemon/setattr.c
- +++ b/daemon/setattr.c
- @@ -140,19 +140,46 @@ static int handle_nfs41_setattr_basicinfo(void *daemon_context,
- "Unsupported flag FILE_ATTRIBUTE_COMPRESSED ignored.\n",
- args->path));
- - /* mode */
- + /* |FILE_ATTRIBUTE_READONLY| to POSIX mode */
- + bool modesetmasksupported = bitmap_isset(&superblock->supported_attrs,
- + 2, FATTR4_WORD2_MODE_SET_MASKED);
- +
- if (basic_info->FileAttributes & FILE_ATTRIBUTE_READONLY) {
- - info.mode = 0444;
- - info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
- - info.attrmask.count = __max(info.attrmask.count, 2);
- - }
- - else {
- - if (old_info.mode == 0444) {
- - info.mode = 0644;
- + if (modesetmasksupported) {
- + /* Make sure we preserve the "x" and setuid/setgid bits */
- + info.mode = 0444;
- + info.mode_mask = 0666;
- +
- + info.attrmask.arr[2] |= FATTR4_WORD2_MODE_SET_MASKED;
- + info.attrmask.count = __max(info.attrmask.count, 3);
- + }
- + else {
- + /* Make sure we preserve the "x" and setuid/setgid bits */
- + info.mode = (old_info.mode & ~0666) | 0444;
- +
- info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
- info.attrmask.count = __max(info.attrmask.count, 2);
- }
- }
- + else {
- + if ((old_info.mode & 0666) == 0444) {
- + if (modesetmasksupported) {
- + /* Make sure we preserve the "x" and setuid/setgid bits */
- + info.mode = 0644;
- + info.mode_mask = 0666;
- +
- + info.attrmask.arr[2] |= FATTR4_WORD2_MODE_SET_MASKED;
- + info.attrmask.count = __max(info.attrmask.count, 3);
- + }
- + else {
- + /* Make sure we preserve the "x" and setuid/setgid bits */
- + info.mode = (old_info.mode & ~0666) | 0644;
- +
- + info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
- + info.attrmask.count = __max(info.attrmask.count, 2);
- + }
- + }
- + }
- }
- if (superblock->cansettime) {
- @@ -207,11 +234,14 @@ static int handle_nfs41_setattr_basicinfo(void *daemon_context,
- */
- if ((opcode != NFS41_SYSOP_FILE_SET_AT_CLEANUP) &&
- (bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_MODE) ||
- + bitmap_isset(&info.attrmask, 2, FATTR4_WORD2_MODE_SET_MASKED) ||
- bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_TIME_CREATE))) {
- DPRINTF(0, ("handle_nfs41_setattr_basicinfo(args->path='%s'): "
- - "returning read delegation because of mode=%d, time_create=%d\n",
- + "returning read delegation because of "
- + "mode=%d/mode_set_masked=%d, time_create=%d\n",
- args->path,
- (int)bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_MODE),
- + (int)bitmap_isset(&info.attrmask, 2, FATTR4_WORD2_MODE_SET_MASKED),
- (int)bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_TIME_CREATE)));
- nfs41_delegation_return(state->session, &state->file,
- OPEN_DELEGATE_READ, FALSE);
- --
- 2.51.0
- From efbcc2bf83a784ed6969bddfd8e2ce2f6457b5b4 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 19 Nov 2025 13:18:58 +0100
- Subject: [PATCH 04/28] daemon: |read_from_mds()| should retry with op READ if
- op READ_PLUS is not supported
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- |read_from_mds()| should retry with NFSv4.1 op READ if NFSv4.2 op READ_PLUS is
- not supported.
- Reported as read error with Windows git with a FreeBSD 14.3 nfsd.
- Reported-by: Aurélien Couderc <aurelien.couderc2002@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/readwrite.c | 4 ++++
- 1 file changed, 4 insertions(+)
- diff --git a/daemon/readwrite.c b/daemon/readwrite.c
- index d4d1b33..21f1fd8 100644
- --- a/daemon/readwrite.c
- +++ b/daemon/readwrite.c
- @@ -212,6 +212,7 @@ static int read_from_mds(
- while(to_rcv > 0) {
- uint32_t bytes_read = 0, chunk = min(to_rcv, maxreadsize);
- +retry_read:
- if (session->client->root->supports_nfs42_read_plus) {
- status = nfs42_read_plus(session, file, stateid,
- args->offset + reloffset, chunk,
- @@ -227,6 +228,9 @@ static int read_from_mds(
- "disabling OP_READ_PLUS\n",
- nfs_error_string(status)));
- session->client->root->supports_nfs42_read_plus = false;
- +
- + /* Retry now with |nfs41_read()| ... */
- + goto retry_read;
- }
- }
- else {
- --
- 2.51.0
- From fab638bc106087f57a9a5a77d7c4a123bce95a73 Mon Sep 17 00:00:00 2001
- From: Dan Shelton <dan.f.shelton@gmail.com>
- Date: Wed, 19 Nov 2025 15:27:33 +0100
- Subject: [PATCH 05/28] sys: Add more FSCTL_* to debug fsctl2string()
- Add more FSCTL_* to debug fsctl2string().
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_debug.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
- diff --git a/sys/nfs41sys_debug.c b/sys/nfs41sys_debug.c
- index c1c996f..df866b3 100644
- --- a/sys/nfs41sys_debug.c
- +++ b/sys/nfs41sys_debug.c
- @@ -831,6 +831,15 @@ dprintk(
- const char *fsctl2string(ULONG fscontrolcode)
- {
- +#ifndef FSCTL_LMR_GET_HINT_SIZE
- +#define FSCTL_LMR_GET_HINT_SIZE \
- + CTL_CODE(FILE_DEVICE_NETWORK_FILE_SYSTEM, 113, METHOD_BUFFERED, FILE_ANY_ACCESS)
- +#endif /* !FSCTL_LMR_GET_HINT_SIZE */
- +#ifndef FSCTL_LMR_GET_VERSIONS
- +#define FSCTL_LMR_GET_VERSIONS \
- + CTL_CODE(FILE_DEVICE_NETWORK_FILE_SYSTEM, 106, METHOD_BUFFERED, FILE_ANY_ACCESS)
- +#endif /* !FSCTL_LMR_GET_VERSIONS */
- +
- #define CASE_SYM2STR_RET(x) case (x): return #x ; break;
- switch(fscontrolcode) {
- #ifdef FSCTL_ADD_OVERLAY
- @@ -1052,6 +1061,18 @@ const char *fsctl2string(ULONG fscontrolcode)
- #ifdef FSCTL_IS_VOLUME_OWNED_BYCSVFS
- CASE_SYM2STR_RET(FSCTL_IS_VOLUME_OWNED_BYCSVFS)
- #endif /* FSCTL_IS_VOLUME_OWNED_BYCSVFS */
- +#ifdef FSCTL_LMR_GET_HINT_SIZE
- + CASE_SYM2STR_RET(FSCTL_LMR_GET_HINT_SIZE)
- +#endif /* FSCTL_LMR_GET_HINT_SIZE */
- +#ifdef FSCTL_LMR_GET_LINK_TRACKING_INFORMATION
- + CASE_SYM2STR_RET(FSCTL_LMR_GET_LINK_TRACKING_INFORMATION)
- +#endif /* FSCTL_LMR_GET_LINK_TRACKING_INFORMATION */
- +#ifdef FSCTL_LMR_GET_VERSIONS
- + CASE_SYM2STR_RET(FSCTL_LMR_GET_VERSIONS)
- +#endif /* FSCTL_LMR_GET_VERSIONS */
- +#ifdef FSCTL_LMR_SET_LINK_TRACKING_INFORMATION
- + CASE_SYM2STR_RET(FSCTL_LMR_SET_LINK_TRACKING_INFORMATION)
- +#endif /* FSCTL_LMR_SET_LINK_TRACKING_INFORMATION */
- #ifdef FSCTL_LOCK_VOLUME
- CASE_SYM2STR_RET(FSCTL_LOCK_VOLUME)
- #endif /* FSCTL_LOCK_VOLUME */
- --
- 2.51.0
- From d632609432affe3615d087e03e4727bf04f13d6a Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Thu, 20 Nov 2025 19:00:09 +0100
- Subject: [PATCH 06/28] sys: Print ECP (Extended Create Parameters) GUIDs at
- file creation time
- Print ECP (Extended Create Parameters) GUIDs at file creation time.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_debug.c | 128 +++++++++++++++++++++++++++++++++++++++
- sys/nfs41sys_debug.h | 4 +-
- sys/nfs41sys_driver.c | 39 ++++++++++++
- sys/nfs41sys_openclose.c | 2 +
- 4 files changed, 172 insertions(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_debug.c b/sys/nfs41sys_debug.c
- index df866b3..f17fa13 100644
- --- a/sys/nfs41sys_debug.c
- +++ b/sys/nfs41sys_debug.c
- @@ -55,6 +55,8 @@
- #include <stdarg.h>
- #include <ntstrsafe.h>
- #include <winerror.h>
- +#include <stdbool.h>
- +#include <ntifs.h>
- #include "win_reparse.h"
- @@ -1579,3 +1581,129 @@ void print_debug_header(
- if (RxContext->CurrentIrp)
- print_irp_flags(0, RxContext->CurrentIrp);
- }
- +
- +/*
- + * Print Extended Create Parameters (ECP)
- + */
- +
- +/*
- + * GUIDs for Extended Create Parameters (ECP)
- + *
- + * FIXME: These are declared in nfs41sys_driver.c and should be in a header,
- + * but nfs41sys_debug.c should not depend in nfs41sys_driver.h
- + */
- +/*
- + * |GUID_ECP_OPEN_AS_BLOCK_DEVICE| - "open as a block device"
- + * From https://www.snia.org/sites/default/files/files2/files2/SDC2013/presentations/Workloads/Barreto_Kurjanowicz-Shared_VHDX-v3.pdf
- + */
- +EXTERN_C const GUID FAR GUID_ECP_OPEN_AS_BLOCK_DEVICE;
- +EXTERN_C const GUID FAR GUID_ECP_QUERY_ON_CREATE;
- +EXTERN_C const GUID FAR GUID_ECP_CLOUDFILES_ATTRIBUTION;
- +EXTERN_C const GUID FAR GUID_ECP_CREATE_USER_PROCESS;
- +EXTERN_C const GUID FAR GUID_ECP_ATOMIC_CREATE;
- +EXTERN_C const GUID FAR GUID_ECP_OPEN_PARAMETERS;
- +
- +
- +typedef struct _ECP_NAME_MAP {
- + const GUID *Guid;
- + const char *Name;
- +} ECP_NAME_MAP;
- +
- +#define ECP_ENTRY(guid) { (const GUID*)&guid, #guid }
- +
- +static
- +const ECP_NAME_MAP KnownEcps[] = {
- +// ECP_ENTRY(GUID_ECP_FLT_CREATEFILE_TARGET),
- + ECP_ENTRY(GUID_ECP_CREATE_USER_PROCESS),
- + ECP_ENTRY(GUID_ECP_OPLOCK_KEY),
- + ECP_ENTRY(GUID_ECP_DUAL_OPLOCK_KEY),
- + ECP_ENTRY(GUID_ECP_NETWORK_OPEN_CONTEXT),
- + ECP_ENTRY(GUID_ECP_NETWORK_APP_INSTANCE),
- + ECP_ENTRY(GUID_ECP_NETWORK_APP_INSTANCE_VERSION),
- + /* GUID_ECP_PREFETCH_OPEN - Prefetch Open (Superfetch) */
- + ECP_ENTRY(GUID_ECP_PREFETCH_OPEN),
- + ECP_ENTRY(GUID_ECP_NFS_OPEN),
- + /* GUID_ECP_SRV_OPEN - SMB SRV Open */
- + ECP_ENTRY(GUID_ECP_SRV_OPEN),
- + ECP_ENTRY(GUID_ECP_RKF_BYPASS),
- + ECP_ENTRY(GUID_ECP_IO_DEVICE_HINT),
- + ECP_ENTRY(GUID_ECP_CSV_DOWN_LEVEL_OPEN),
- + ECP_ENTRY(GUID_ECP_CSV_QUERY_FILE_REVISION),
- + ECP_ENTRY(GUID_ECP_CSV_QUERY_FILE_REVISION_FILE_ID_128),
- + ECP_ENTRY(GUID_ECP_CSV_SET_HANDLE_PROPERTIES),
- + ECP_ENTRY(GUID_ECP_CREATE_REDIRECTION),
- + ECP_ENTRY(GUID_ECP_ATOMIC_CREATE),
- + ECP_ENTRY(GUID_ECP_OPEN_PARAMETERS),
- + ECP_ENTRY(GUID_ECP_QUERY_ON_CREATE),
- + ECP_ENTRY(GUID_ECP_CLOUDFILES_ATTRIBUTION),
- + /*
- + * Custom ECP not in <ntifs.h>/Windows headers
- + */
- + ECP_ENTRY(GUID_ECP_OPEN_AS_BLOCK_DEVICE),
- + { NULL, NULL }
- +};
- +
- +static
- +const char *GetEcpNameFromGuid(const GUID *restrict guid)
- +{
- + for (int i = 0; KnownEcps[i].Guid != NULL; i++) {
- + if (IsEqualGUID(guid, KnownEcps[i].Guid)) {
- + return KnownEcps[i].Name;
- + }
- + }
- + return "<Unknown-ECP>";
- +}
- +
- +void debug_printirpecps(PIRP irp)
- +{
- + NTSTATUS status;
- + PECP_LIST ecpList = NULL;
- + PVOID currentContext = NULL;
- + PVOID nextContext = NULL;
- + GUID ecpGuid;
- + ULONG ecpSize = 0;
- + UNICODE_STRING guidString;
- +
- + status = FsRtlGetEcpListFromIrp(irp, &ecpList);
- +
- + if ((status == STATUS_NOT_FOUND) || (ecpList == NULL)) {
- + DbgP("debug_printirpecps: No ECP list found attached to the IRP.\n");
- + return;
- + } else if (!NT_SUCCESS(status)) {
- + DbgP("debug_printirpecps: Failed to retrieve ECP list, status=0x%lx\n",
- + (long)status);
- + return;
- + }
- +
- + while(true) {
- + status = FsRtlGetNextExtraCreateParameter(
- + ecpList,
- + currentContext,
- + &ecpGuid,
- + &nextContext,
- + &ecpSize
- + );
- +
- + if (status == STATUS_NOT_FOUND) {
- + break;
- + }
- +
- + if (!NT_SUCCESS(status)) {
- + DbgP("debug_printirpecps: "
- + "FsRtlGetNextExtraCreateParameter() returned status=0x%lx\n",
- + (long)status);
- + break;
- + }
- +
- + if (NT_SUCCESS(RtlStringFromGUID(&ecpGuid, &guidString))) {
- + const char *friendlyName = GetEcpNameFromGuid(&ecpGuid);
- +
- + DbgP("debug_printirpecps: ECP: Name='%s', GUID='%wZ', size=%lu\n",
- + friendlyName, &guidString, ecpSize);
- +
- + RtlFreeUnicodeString(&guidString);
- + }
- +
- + currentContext = nextContext;
- + }
- +}
- diff --git a/sys/nfs41sys_debug.h b/sys/nfs41sys_debug.h
- index 47f8d61..aac1c31 100644
- --- a/sys/nfs41sys_debug.h
- +++ b/sys/nfs41sys_debug.h
- @@ -1,5 +1,6 @@
- /* NFSv4.1 client for Windows
- - * Copyright (C) 2012 The Regents of the University of Michigan
- + * Copyright (C) 2012 The Regents of the University of Michigan
- + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
- *
- * Olga Kornievskaia <aglo@umich.edu>
- * Casey Bodley <cbodley@umich.edu>
- @@ -60,6 +61,7 @@ const char *reparsetag2string(ULONG tag);
- void print_lookasidelist_stat(const char *label, PNPAGED_LOOKASIDE_LIST ll);
- #endif /* USE_LOOKASIDELISTS_FOR_UPDOWNCALLENTRY_MEM */
- void print_debug_header(PRX_CONTEXT RxContext);
- +void debug_printirpecps(PIRP irp);
- #define PTR2PTRDIFF_T(p) (((char *)(p))-((char *)0))
- #define PsGetCurrentProcessShortDebugId() ((int)PTR2PTRDIFF_T(PsGetCurrentProcessId()))
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index 39689ab..1ae41e0 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -52,6 +52,11 @@
- #endif
- #endif /* _MSC_VER >= 1900 */
- +/*
- + * <initguid.h> must be included FIRST to get GUID variable declarations below
- + */
- +#include <initguid.h>
- +
- #define MINIRDR__NAME MRxNFS41
- #include <rx.h>
- #include <windef.h>
- @@ -88,6 +93,40 @@ DECLARE_CONST_ANSI_STRING(NfsV3Attributes, EA_NFSV3ATTRIBUTES);
- DECLARE_CONST_ANSI_STRING(NfsSymlinkTargetName, EA_NFSSYMLINKTARGETNAME);
- DECLARE_CONST_ANSI_STRING(NfsActOnLink, EA_NFSACTONLINK);
- +/*
- + * |GUID_ECP_OPEN_AS_BLOCK_DEVICE| - "open as a block device"
- + * From https://www.snia.org/sites/default/files/files2/files2/SDC2013/presentations/Workloads/Barreto_Kurjanowicz-Shared_VHDX-v3.pdf
- + */
- +DEFINE_GUID(GUID_ECP_OPEN_AS_BLOCK_DEVICE,
- + 0x9ecfcb9c, 0xc104, 0x43e6,
- + 0x98, 0x0e, 0x15, 0x8d, 0xa1, 0xf6, 0xec, 0x83);
- +
- +#if !(NTDDI_VERSION >= NTDDI_WIN10_RS5)
- +DEFINE_GUID(GUID_ECP_QUERY_ON_CREATE,
- + 0x1aca62e9, 0xabb4, 0x4ff2,
- + 0xbb, 0x5c, 0x1c, 0x79, 0x2, 0x5e, 0x41, 0x7f);
- +#endif /* !(NTDDI_VERSION >= NTDDI_WIN10_RS5) */
- +#if !(NTDDI_VERSION >= NTDDI_WIN10_VB)
- +DEFINE_GUID(GUID_ECP_CLOUDFILES_ATTRIBUTION,
- + 0x2932ff52, 0x8378, 0x4fc1,
- + 0x8e, 0xdb, 0x6b, 0xdc, 0x8f, 0x60, 0x27, 0x09);
- +#endif /* !(NTDDI_VERSION >= NTDDI_WIN10_VB) */
- +#if !(NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
- +DEFINE_GUID(GUID_ECP_CREATE_USER_PROCESS,
- + 0xe0e429ff, 0x6ddc, 0x4e65,
- + 0xaa, 0xb6, 0x45, 0xd0, 0x5a, 0x3, 0x8a, 0x8);
- +#endif /* !(NTDDI_VERSION >= NTDDI_WINTHRESHOLD) */
- +#if !(NTDDI_VERSION >= NTDDI_WIN10_TH2)
- +DEFINE_GUID(GUID_ECP_ATOMIC_CREATE,
- + 0x4720bd83, 0x52ac, 0x4104,
- + 0xa1, 0x30, 0xd1, 0xec, 0x6a, 0x8c, 0xc8, 0xe5);
- +#endif /* !(NTDDI_VERSION >= NTDDI_WIN10_TH2) */
- +#if !(NTDDI_VERSION >= NTDDI_WIN10_RS3)
- +DEFINE_GUID(GUID_ECP_OPEN_PARAMETERS,
- + 0xcd0a93c3, 0x3bb7, 0x463d,
- + 0xac, 0xcb, 0x96, 0x9d, 0x34, 0x35, 0xa5, 0xa5);
- +#endif /* !(NTDDI_VERSION >= NTDDI_WIN10_RS3) */
- +
- #ifdef USE_LOOKASIDELISTS_FOR_UPDOWNCALLENTRY_MEM
- NPAGED_LOOKASIDE_LIST updowncall_entry_upcall_lookasidelist;
- #ifndef USE_STACK_FOR_DOWNCALL_UPDOWNCALLENTRY_MEM
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 3247539..25ae634 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -655,6 +655,8 @@ NTSTATUS nfs41_Create(
- status = check_nfs41_create_args(RxContext);
- if (status) goto out;
- + debug_printirpecps(RxContext->CurrentIrp);
- +
- #ifdef NFS41_DRIVER_ALLOW_CREATEFILE_ACLS
- ULONG SdLength = RxContext->Create.SdLength;
- PSECURITY_DESCRIPTOR SdBuffer;
- --
- 2.51.0
- From 1b12578a04fe5a4c58fba1969b7dcf685db7e842 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Thu, 20 Nov 2025 19:08:47 +0100
- Subject: [PATCH 07/28] sys: Fix comment about SMB also using
- |IO_NETWORK_INCREMENT|
- Fix comment about SMB also using |IO_NETWORK_INCREMENT|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_driver.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 1c327ab..47e58eb 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -92,7 +92,7 @@ typedef struct __nfs41_timings {
- } nfs41_timings;
- #endif /* ENABLE_TIMINGS */
- -/* Windows SMB driver also uses |IO_NFS41FS_INCREMENT| */
- +/* Windows SMB driver also uses |IO_NETWORK_INCREMENT| */
- #define IO_NFS41FS_INCREMENT IO_NETWORK_INCREMENT
- #define DISABLE_CACHING 0
- --
- 2.51.0
- From 4625971d4748376e1b75178f1643627d397f4143 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Thu, 20 Nov 2025 20:31:38 +0100
- Subject: [PATCH 08/28] sys: Print
- |QUERY_ON_CREATE_ECP_CONTEXT.RequestedClasses| to debug log
- Print |QUERY_ON_CREATE_ECP_CONTEXT.RequestedClasses| to debug log
- if we got a |GUID_ECP_QUERY_ON_CREATE| at file/dir creation time.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_openclose.c | 6 ++++++
- sys/nfs41sys_util.c | 29 ++++++++++++++++++++++++++++-
- sys/nfs41sys_util.h | 5 ++++-
- 3 files changed, 38 insertions(+), 2 deletions(-)
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 25ae634..53bb879 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -657,6 +657,12 @@ NTSTATUS nfs41_Create(
- debug_printirpecps(RxContext->CurrentIrp);
- + PQUERY_ON_CREATE_ECP_CONTEXT qocec =
- + get_queryoncreateecpcontext(RxContext->CurrentIrp);
- + if (qocec) {
- + DbgP("nfs41_Create: RequestedClasses=0x%lx\n", qocec->RequestedClasses);
- + }
- +
- #ifdef NFS41_DRIVER_ALLOW_CREATEFILE_ACLS
- ULONG SdLength = RxContext->Create.SdLength;
- PSECURITY_DESCRIPTOR SdBuffer;
- diff --git a/sys/nfs41sys_util.c b/sys/nfs41sys_util.c
- index 6cceee8..27691fd 100644
- --- a/sys/nfs41sys_util.c
- +++ b/sys/nfs41sys_util.c
- @@ -1,6 +1,6 @@
- /* NFSv4.1 client for Windows
- * Copyright (C) 2012 The Regents of the University of Michigan
- - * Copyright (C) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
- + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
- *
- * Olga Kornievskaia <aglo@umich.edu>
- * Casey Bodley <cbodley@umich.edu>
- @@ -194,3 +194,30 @@ NTSTATUS nfs41_UnmapLockedKernelPagesInNfsDaemonAddressSpace(
- return status;
- }
- +
- +PQUERY_ON_CREATE_ECP_CONTEXT get_queryoncreateecpcontext(
- + __in PIRP Irp)
- +{
- + NTSTATUS status;
- + PECP_LIST ecpList = NULL;
- + PVOID ecpContext = NULL;
- +
- + status = FsRtlGetEcpListFromIrp(Irp, &ecpList);
- +
- + if ((!NT_SUCCESS(status)) || (ecpList == NULL)) {
- + return NULL;
- + }
- +
- + status = FsRtlFindExtraCreateParameter(
- + ecpList,
- + &GUID_ECP_QUERY_ON_CREATE,
- + &ecpContext,
- + NULL
- + );
- +
- + if (!NT_SUCCESS(status)) {
- + return NULL;
- + }
- +
- + return (PQUERY_ON_CREATE_ECP_CONTEXT)ecpContext;
- +}
- diff --git a/sys/nfs41sys_util.h b/sys/nfs41sys_util.h
- index 6157195..793f440 100644
- --- a/sys/nfs41sys_util.h
- +++ b/sys/nfs41sys_util.h
- @@ -1,6 +1,6 @@
- /* NFSv4.1 client for Windows
- * Copyright (C) 2012 The Regents of the University of Michigan
- - * Copyright (C) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
- + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
- *
- * Olga Kornievskaia <aglo@umich.edu>
- * Casey Bodley <cbodley@umich.edu>
- @@ -65,4 +65,7 @@ NTSTATUS nfs41_MapLockedPagesInNfsDaemonAddressSpace(
- NTSTATUS nfs41_UnmapLockedKernelPagesInNfsDaemonAddressSpace(
- __in PVOID BaseAddress,
- __in PMDL MemoryDescriptorList);
- +PQUERY_ON_CREATE_ECP_CONTEXT get_queryoncreateecpcontext(
- + __in PIRP Irp);
- +
- #endif /* !_NFS41SYS_UTIL_H_ */
- --
- 2.51.0
- From d8def0564972e647f12804a1910aba3cb3dce084 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Thu, 20 Nov 2025 21:29:58 +0100
- Subject: [PATCH 09/28] sys: Invalidate kernel ACL cache if it does not contain
- the info we requested
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- Invalidate kernel ACL cache if it does not contain the info we requested
- (e.g. we have cached info for owner+primary group, but DACL info
- are requested).
- Reported-by: Aurélien Couderc <aurelien.couderc2002@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 45 ++++++++++++++++++++++++++++---------------
- sys/nfs41sys_driver.h | 1 +
- 2 files changed, 30 insertions(+), 16 deletions(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index d8e4aa8..aef18d0 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -275,27 +275,37 @@ NTSTATUS nfs41_QuerySecurityInformation(
- goto out;
- }
- - PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
- - RxContext->CurrentIrp->UserBuffer;
- - RtlCopyMemory(sec_desc, nfs41_fobx->acl, nfs41_fobx->acl_len);
- - RxContext->IoStatusBlock.Information =
- - RxContext->InformationToReturn = nfs41_fobx->acl_len;
- - RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
- + /* Check whether the cached info have all the info we need */
- + if ((nfs41_fobx->acl_secinfo & info_class) == info_class) {
- + PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
- + RxContext->CurrentIrp->UserBuffer;
- + RtlCopyMemory(sec_desc, nfs41_fobx->acl, nfs41_fobx->acl_len);
- + RxContext->IoStatusBlock.Information =
- + RxContext->InformationToReturn = nfs41_fobx->acl_len;
- + RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
- #ifdef ENABLE_TIMINGS
- - InterlockedIncrement(&getacl.sops);
- - InterlockedAdd64(&getacl.size, nfs41_fobx->acl_len);
- + InterlockedIncrement(&getacl.sops);
- + InterlockedAdd64(&getacl.size, nfs41_fobx->acl_len);
- #endif
- - DbgP("nfs41_QuerySecurityInformation: using cached ACL info\n");
- - goto out;
- - } else {
- - if (nfs41_fobx->acl) {
- - RxFreePool(nfs41_fobx->acl);
- - nfs41_fobx->acl = NULL;
- - nfs41_fobx->acl_len = 0;
- + DbgP("nfs41_QuerySecurityInformation: using cached ACL info\n");
- + goto out;
- }
- - DbgP("nfs41_QuerySecurityInformation: cached ACL info invalidated\n");
- + else {
- + DbgP("nfs41_QuerySecurityInformation: "
- + "cache misses requested info, acl_secinfo=0x%lx, info_class=0x%lx\n",
- + (unsigned long)nfs41_fobx->acl_secinfo,
- + (unsigned long)info_class);
- + }
- + }
- +
- + if (nfs41_fobx->acl) {
- + RxFreePool(nfs41_fobx->acl);
- + nfs41_fobx->acl = NULL;
- + nfs41_fobx->acl_len = 0;
- + nfs41_fobx->acl_secinfo = 0;
- }
- + DbgP("nfs41_QuerySecurityInformation: cached ACL info invalidated\n");
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_ACL_QUERY, &nfs41_fobx->sec_ctx,
- @@ -338,10 +348,12 @@ NTSTATUS nfs41_QuerySecurityInformation(
- RxFreePool(nfs41_fobx->acl);
- nfs41_fobx->acl = NULL;
- nfs41_fobx->acl_len = 0;
- + nfs41_fobx->acl_secinfo = 0;
- }
- nfs41_fobx->acl = entry->u.Acl.buf;
- nfs41_fobx->acl_len = entry->u.Acl.buf_len;
- + nfs41_fobx->acl_secinfo = entry->u.Acl.query;
- entry->u.Acl.buf = NULL;
- KeQuerySystemTime(&nfs41_fobx->time);
- @@ -479,6 +491,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- RxFreePool(nfs41_fobx->acl);
- nfs41_fobx->acl = NULL;
- nfs41_fobx->acl_len = 0;
- + nfs41_fobx->acl_secinfo = 0;
- }
- status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 47e58eb..ad1b2f4 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -496,6 +496,7 @@ typedef struct _NFS41_FOBX {
- SECURITY_CLIENT_CONTEXT sec_ctx;
- PVOID acl;
- DWORD acl_len;
- + SECURITY_INFORMATION acl_secinfo;
- LARGE_INTEGER time;
- DWORD deleg_type;
- BOOLEAN write_thru;
- --
- 2.51.0
- From 49a907fb0b098af469032c6fb55f654ae25e7e7e Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Thu, 20 Nov 2025 21:45:03 +0100
- Subject: [PATCH 10/28] daemon,sys: Rename all instances in ACL code which
- refer to |SECURITY_INFORMATION| to |*secinfo|
- Rename all instances in ACL code which refer to |SECURITY_INFORMATION|
- to |*secinfo|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/acl.c | 41 +++++++++++++++++++++------------------
- daemon/upcall.h | 4 ++--
- sys/nfs41sys_acl.c | 45 +++++++++++++++++++++++--------------------
- sys/nfs41sys_driver.h | 2 +-
- 4 files changed, 49 insertions(+), 43 deletions(-)
- diff --git a/daemon/acl.c b/daemon/acl.c
- index bd02f56..2d7546b 100644
- --- a/daemon/acl.c
- +++ b/daemon/acl.c
- @@ -45,12 +45,14 @@ static int parse_getacl(
- int status;
- getacl_upcall_args *args = &upcall->args.getacl;
- - status = safe_read(&buffer, &length, &args->query, sizeof(args->query));
- + status = safe_read(&buffer, &length, &args->query_secinfo,
- + sizeof(args->query_secinfo));
- if (status) goto out;
- EASSERT(length == 0);
- - DPRINTF(1, ("parsing NFS41_SYSOP_ACL_QUERY: info_class=%d\n", args->query));
- + DPRINTF(1, ("parsing NFS41_SYSOP_ACL_QUERY: secinfo=0xlx\n",
- + (long)args->query_secinfo));
- out:
- return status;
- }
- @@ -79,7 +81,7 @@ static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
- DPRINTF(ACLLVL1, ("--> handle_getacl(state->path.path='%s')\n",
- state->path.path));
- - if (args->query & DACL_SECURITY_INFORMATION) {
- + if (args->query_secinfo & DACL_SECURITY_INFORMATION) {
- owner_group_acl_bitmap.arr[0] |= FATTR4_WORD0_ACL;
- }
- @@ -102,13 +104,13 @@ static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
- }
- EASSERT(info.attrmask.count > 1);
- - if (args->query & DACL_SECURITY_INFORMATION) {
- + if (args->query_secinfo & DACL_SECURITY_INFORMATION) {
- EASSERT(bitmap_isset(&info.attrmask, 0, FATTR4_WORD0_ACL) == true);
- }
- - if (args->query & OWNER_SECURITY_INFORMATION) {
- + if (args->query_secinfo & OWNER_SECURITY_INFORMATION) {
- EASSERT(bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_OWNER) == true);
- }
- - if (args->query & GROUP_SECURITY_INFORMATION) {
- + if (args->query_secinfo & GROUP_SECURITY_INFORMATION) {
- EASSERT(bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_OWNER_GROUP) == true);
- }
- @@ -125,7 +127,7 @@ static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
- * stores pointers to the sids. thus each owner and group needs its own
- * memory. free them after creating self-relative security descriptor.
- */
- - if (args->query & OWNER_SECURITY_INFORMATION) {
- + if (args->query_secinfo & OWNER_SECURITY_INFORMATION) {
- // parse user@domain. currently ignoring domain part XX
- convert_nfs4name_2_user_domain(info.owner, &domain);
- DPRINTF(ACLLVL2, ("handle_getacl: OWNER_SECURITY_INFORMATION: for user='%s' "
- @@ -144,7 +146,7 @@ static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
- }
- }
- - if (args->query & GROUP_SECURITY_INFORMATION) {
- + if (args->query_secinfo & GROUP_SECURITY_INFORMATION) {
- convert_nfs4name_2_user_domain(info.owner_group, &domain);
- DPRINTF(ACLLVL2, ("handle_getacl: GROUP_SECURITY_INFORMATION: for '%s' "
- "domain='%s'\n", info.owner_group, domain?domain:"<null>"));
- @@ -162,7 +164,7 @@ static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
- }
- }
- - if (args->query & DACL_SECURITY_INFORMATION) {
- + if (args->query_secinfo & DACL_SECURITY_INFORMATION) {
- DPRINTF(ACLLVL2, ("handle_getacl: DACL_SECURITY_INFORMATION\n"));
- status = convert_nfs4acl_2_dacl(nfs41dg,
- info.acl, state->type, &dacl, &sids,
- @@ -204,13 +206,13 @@ static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
- } else status = ERROR_SUCCESS;
- out:
- - if (args->query & OWNER_SECURITY_INFORMATION) {
- + if (args->query_secinfo & OWNER_SECURITY_INFORMATION) {
- if (osid) free(osid);
- }
- - if (args->query & GROUP_SECURITY_INFORMATION) {
- + if (args->query_secinfo & GROUP_SECURITY_INFORMATION) {
- if (gsid) free(gsid);
- }
- - if (args->query & DACL_SECURITY_INFORMATION) {
- + if (args->query_secinfo & DACL_SECURITY_INFORMATION) {
- if (sids) free_sids(sids, info.acl->count);
- free(dacl);
- nfsacl41_free(info.acl);
- @@ -257,7 +259,8 @@ static int parse_setacl(
- const void *sec_desc_ptr;
- ULONG sec_desc_len;
- - status = safe_read(&buffer, &length, &args->query, sizeof(args->query));
- + status = safe_read(&buffer, &length, &args->query_secinfo,
- + sizeof(args->query_secinfo));
- if (status) goto out;
- status = safe_read(&buffer, &length, &sec_desc_len, sizeof(ULONG));
- if (status) goto out;
- @@ -268,8 +271,8 @@ static int parse_setacl(
- EASSERT(length == 0);
- - DPRINTF(1, ("parsing NFS41_SYSOP_ACL_SET: info_class=%d sec_desc_len=%d\n",
- - args->query, sec_desc_len));
- + DPRINTF(1, ("parsing NFS41_SYSOP_ACL_SET: secinfo=0x%lx sec_desc_len=%d\n",
- + (long)args->query_secinfo, sec_desc_len));
- out:
- return status;
- }
- @@ -297,7 +300,7 @@ static int handle_setacl(void *daemon_context, nfs41_upcall *upcall)
- goto out;
- }
- - if (args->query & OWNER_SECURITY_INFORMATION) {
- + if (args->query_secinfo & OWNER_SECURITY_INFORMATION) {
- DPRINTF(ACLLVL2, ("handle_setacl: OWNER_SECURITY_INFORMATION\n"));
- status = GetSecurityDescriptorOwner(args->sec_desc, &sid, &sid_default);
- if (!status) {
- @@ -319,7 +322,7 @@ static int handle_setacl(void *daemon_context, nfs41_upcall *upcall)
- ("info.owner='%s'\n", info.owner));
- }
- - if (args->query & GROUP_SECURITY_INFORMATION) {
- + if (args->query_secinfo & GROUP_SECURITY_INFORMATION) {
- DPRINTF(ACLLVL2, ("handle_setacl: GROUP_SECURITY_INFORMATION\n"));
- status = GetSecurityDescriptorGroup(args->sec_desc, &sid, &sid_default);
- if (!status) {
- @@ -341,7 +344,7 @@ static int handle_setacl(void *daemon_context, nfs41_upcall *upcall)
- ("info.owner_group='%s'\n", info.owner_group));
- }
- - if (args->query & DACL_SECURITY_INFORMATION) {
- + if (args->query_secinfo & DACL_SECURITY_INFORMATION) {
- BOOL dacl_present, dacl_default;
- PACL acl;
- DPRINTF(ACLLVL2, ("handle_setacl: DACL_SECURITY_INFORMATION\n"));
- @@ -400,7 +403,7 @@ static int handle_setacl(void *daemon_context, nfs41_upcall *upcall)
- }
- }
- - if (args->query & DACL_SECURITY_INFORMATION)
- + if (args->query_secinfo & DACL_SECURITY_INFORMATION)
- free(nfs4_acl.aces);
- out:
- DPRINTF(ACLLVL1, ("<-- handle_setacl() returning %d\n", status));
- diff --git a/daemon/upcall.h b/daemon/upcall.h
- index 5e78f54..1563c25 100644
- --- a/daemon/upcall.h
- +++ b/daemon/upcall.h
- @@ -198,13 +198,13 @@ typedef struct __volume_upcall_args {
- } volume_upcall_args;
- typedef struct __getacl_upcall_args {
- - SECURITY_INFORMATION query;
- + SECURITY_INFORMATION query_secinfo;
- PSECURITY_DESCRIPTOR sec_desc;
- DWORD sec_desc_len;
- } getacl_upcall_args;
- typedef struct __setacl_upcall_args {
- - SECURITY_INFORMATION query;
- + SECURITY_INFORMATION query_secinfo;
- PSECURITY_DESCRIPTOR sec_desc;
- ULONGLONG ctime;
- } setacl_upcall_args;
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index aef18d0..da293ec 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -90,7 +90,8 @@ NTSTATUS marshal_nfs41_getacl(
- goto out;
- }
- - RtlCopyMemory(tmp, &entry->u.Acl.query, sizeof(SECURITY_INFORMATION));
- + RtlCopyMemory(tmp,
- + &entry->u.Acl.query_secinfo, sizeof(SECURITY_INFORMATION));
- tmp += sizeof(SECURITY_INFORMATION);
- *len = (ULONG)(tmp - buf);
- @@ -102,7 +103,8 @@ NTSTATUS marshal_nfs41_getacl(
- }
- #ifdef DEBUG_MARSHAL_DETAIL
- - DbgP("marshal_nfs41_getacl: class=0x%x\n", (int)entry->u.Acl.query);
- + DbgP("marshal_nfs41_getacl: class=0x%x\n",
- + (int)entry->u.Acl.query_secinfo);
- #endif
- out:
- return status;
- @@ -130,7 +132,8 @@ NTSTATUS marshal_nfs41_setacl(
- goto out;
- }
- - RtlCopyMemory(tmp, &entry->u.Acl.query, sizeof(SECURITY_INFORMATION));
- + RtlCopyMemory(tmp,
- + &entry->u.Acl.query_secinfo, sizeof(SECURITY_INFORMATION));
- tmp += sizeof(SECURITY_INFORMATION);
- RtlCopyMemory(tmp, &entry->u.Acl.buf_len, sizeof(ULONG));
- tmp += sizeof(ULONG);
- @@ -147,7 +150,7 @@ NTSTATUS marshal_nfs41_setacl(
- #ifdef DEBUG_MARSHAL_DETAIL
- DbgP("marshal_nfs41_setacl: class=0x%x sec_desc_len=%lu\n",
- - (int)entry->u.Acl.query, (long)entry->u.Acl.buf_len);
- + (int)entry->u.Acl.query_secinfo, (long)entry->u.Acl.buf_len);
- #endif
- out:
- return status;
- @@ -204,12 +207,12 @@ NTSTATUS check_nfs41_getacl_args(
- PRX_CONTEXT RxContext)
- {
- NTSTATUS status = STATUS_SUCCESS;
- - SECURITY_INFORMATION info_class =
- + SECURITY_INFORMATION secinfo =
- RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
- /* we don't support sacls (yet) */
- - if (info_class == SACL_SECURITY_INFORMATION ||
- - info_class == LABEL_SECURITY_INFORMATION) {
- + if (secinfo == SACL_SECURITY_INFORMATION ||
- + secinfo == LABEL_SECURITY_INFORMATION) {
- DbgP("check_nfs41_getacl_args: SACLs not supported (yet)\n");
- status = STATUS_NOT_SUPPORTED;
- goto out;
- @@ -235,7 +238,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
- - SECURITY_INFORMATION info_class =
- + SECURITY_INFORMATION secinfo =
- RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
- ULONG querysecuritylength =
- RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length;
- @@ -247,7 +250,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- #ifdef DEBUG_ACL_QUERY
- DbgEn();
- print_debug_header(RxContext);
- - print_acl_args(info_class);
- + print_acl_args(secinfo);
- #endif
- FsRtlEnterFileSystem();
- @@ -276,7 +279,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- }
- /* Check whether the cached info have all the info we need */
- - if ((nfs41_fobx->acl_secinfo & info_class) == info_class) {
- + if ((nfs41_fobx->acl_secinfo & secinfo) == secinfo) {
- PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
- RxContext->CurrentIrp->UserBuffer;
- RtlCopyMemory(sec_desc, nfs41_fobx->acl, nfs41_fobx->acl_len);
- @@ -293,9 +296,9 @@ NTSTATUS nfs41_QuerySecurityInformation(
- }
- else {
- DbgP("nfs41_QuerySecurityInformation: "
- - "cache misses requested info, acl_secinfo=0x%lx, info_class=0x%lx\n",
- + "cache misses requested info, acl_secinfo=0x%lx, secinfo=0x%lx\n",
- (unsigned long)nfs41_fobx->acl_secinfo,
- - (unsigned long)info_class);
- + (unsigned long)secinfo);
- }
- }
- @@ -313,7 +316,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- - entry->u.Acl.query = info_class;
- + entry->u.Acl.query_secinfo = secinfo;
- /* we can't provide RxContext->CurrentIrp->UserBuffer to the upcall thread
- * because it becomes an invalid pointer with that execution context
- */
- @@ -353,7 +356,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- nfs41_fobx->acl = entry->u.Acl.buf;
- nfs41_fobx->acl_len = entry->u.Acl.buf_len;
- - nfs41_fobx->acl_secinfo = entry->u.Acl.query;
- + nfs41_fobx->acl_secinfo = entry->u.Acl.query_secinfo;
- entry->u.Acl.buf = NULL;
- KeQuerySystemTime(&nfs41_fobx->time);
- @@ -406,7 +409,7 @@ NTSTATUS check_nfs41_setacl_args(
- NTSTATUS status = STATUS_SUCCESS;
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
- - SECURITY_INFORMATION info_class =
- + SECURITY_INFORMATION secinfo =
- RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
- if (pVNetRootContext->read_only) {
- @@ -415,8 +418,8 @@ NTSTATUS check_nfs41_setacl_args(
- goto out;
- }
- /* we don't support sacls (yet) */
- - if (info_class == SACL_SECURITY_INFORMATION ||
- - info_class == LABEL_SECURITY_INFORMATION) {
- + if (secinfo == SACL_SECURITY_INFORMATION ||
- + secinfo == LABEL_SECURITY_INFORMATION) {
- DbgP("check_nfs41_setacl_args: SACLs not supported (yet)\n");
- status = STATUS_NOT_SUPPORTED;
- goto out;
- @@ -439,7 +442,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- __notnull PSECURITY_DESCRIPTOR sec_desc =
- RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityDescriptor;
- __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
- - SECURITY_INFORMATION info_class =
- + SECURITY_INFORMATION secinfo =
- RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
- #ifdef ENABLE_TIMINGS
- LARGE_INTEGER t1, t2;
- @@ -449,7 +452,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- #ifdef DEBUG_ACL_SET
- DbgEn();
- print_debug_header(RxContext);
- - print_acl_args(info_class);
- + print_acl_args(secinfo);
- #endif
- FsRtlEnterFileSystem();
- @@ -457,7 +460,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- if (status) goto out;
- /* check that ACL is present */
- - if (info_class & DACL_SECURITY_INFORMATION) {
- + if (secinfo & DACL_SECURITY_INFORMATION) {
- PACL acl;
- BOOLEAN present, dacl_default;
- status = RtlGetDaclSecurityDescriptor(sec_desc, &present, &acl,
- @@ -478,7 +481,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- - entry->u.Acl.query = info_class;
- + entry->u.Acl.query_secinfo = secinfo;
- entry->u.Acl.buf = sec_desc;
- entry->u.Acl.buf_len = RtlLengthSecurityDescriptor(sec_desc);
- #ifdef ENABLE_TIMINGS
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index ad1b2f4..bc7537c 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -298,7 +298,7 @@ typedef struct _updowncall_entry {
- ULONG buf_len;
- } Volume;
- struct {
- - SECURITY_INFORMATION query;
- + SECURITY_INFORMATION query_secinfo;
- PVOID buf;
- ULONG buf_len;
- } Acl;
- --
- 2.51.0
- From c559e5a22ca8aa4fe395e0e71b9f865ba0833be8 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Thu, 20 Nov 2025 21:57:16 +0100
- Subject: [PATCH 11/28] sys: Fix tests for unsupported
- |SACL_SECURITY_INFORMATION|+|LABEL_SECURITY_INFORMATION|
- Fix tests for unsupported |SACL_SECURITY_INFORMATION|+
- |LABEL_SECURITY_INFORMATION|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index da293ec..80060cb 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -211,8 +211,8 @@ NTSTATUS check_nfs41_getacl_args(
- RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
- /* we don't support sacls (yet) */
- - if (secinfo == SACL_SECURITY_INFORMATION ||
- - secinfo == LABEL_SECURITY_INFORMATION) {
- + if ((secinfo & SACL_SECURITY_INFORMATION) ||
- + (secinfo & LABEL_SECURITY_INFORMATION)) {
- DbgP("check_nfs41_getacl_args: SACLs not supported (yet)\n");
- status = STATUS_NOT_SUPPORTED;
- goto out;
- @@ -418,8 +418,8 @@ NTSTATUS check_nfs41_setacl_args(
- goto out;
- }
- /* we don't support sacls (yet) */
- - if (secinfo == SACL_SECURITY_INFORMATION ||
- - secinfo == LABEL_SECURITY_INFORMATION) {
- + if ((secinfo & SACL_SECURITY_INFORMATION) ||
- + (secinfo & LABEL_SECURITY_INFORMATION)) {
- DbgP("check_nfs41_setacl_args: SACLs not supported (yet)\n");
- status = STATUS_NOT_SUPPORTED;
- goto out;
- --
- 2.51.0
- From 7ea5f19ac2bef56db9ec7e54947f75086913d8d7 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 21 Nov 2025 12:30:43 +0100
- Subject: [PATCH 12/28] sys: Move acl cache variables int it's own sub-struct
- Move acl cache variables int it's own sub-struct.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 71 +++++++++++++++++++++++--------------------
- sys/nfs41sys_driver.c | 6 ++--
- sys/nfs41sys_driver.h | 10 +++---
- 3 files changed, 47 insertions(+), 40 deletions(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index 80060cb..a927f09 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -257,38 +257,41 @@ NTSTATUS nfs41_QuerySecurityInformation(
- status = check_nfs41_getacl_args(RxContext);
- if (status) goto out;
- - if (nfs41_fobx->acl && nfs41_fobx->acl_len) {
- + if (nfs41_fobx->aclcache.data && nfs41_fobx->aclcache.data_len) {
- LARGE_INTEGER current_time;
- KeQuerySystemTime(¤t_time);
- #ifdef DEBUG_ACL_QUERY
- DbgP("CurrentTime 0x%llx Saved Acl time 0x%llx\n",
- (long long)current_time.QuadPart,
- - (long long)nfs41_fobx->time.QuadPart);
- + (long long)nfs41_fobx->aclcache.time.QuadPart);
- #endif
- - if ((current_time.QuadPart - nfs41_fobx->time.QuadPart) <= (10*1000)) {
- - if (querysecuritylength < nfs41_fobx->acl_len) {
- + if ((current_time.QuadPart - nfs41_fobx->aclcache.time.QuadPart)
- + <= (10*1000)) {
- + if (querysecuritylength < nfs41_fobx->aclcache.data_len) {
- status = STATUS_BUFFER_OVERFLOW;
- - RxContext->InformationToReturn = nfs41_fobx->acl_len;
- + RxContext->InformationToReturn = nfs41_fobx->aclcache.data_len;
- DbgP("nfs41_QuerySecurityInformation: "
- "STATUS_BUFFER_OVERFLOW for cached entry, "
- "got %lu, need %lu\n",
- (unsigned long)querysecuritylength,
- - (unsigned long)nfs41_fobx->acl_len);
- + (unsigned long)nfs41_fobx->aclcache.data_len);
- goto out;
- }
- /* Check whether the cached info have all the info we need */
- - if ((nfs41_fobx->acl_secinfo & secinfo) == secinfo) {
- + if ((nfs41_fobx->aclcache.secinfo & secinfo) == secinfo) {
- PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
- RxContext->CurrentIrp->UserBuffer;
- - RtlCopyMemory(sec_desc, nfs41_fobx->acl, nfs41_fobx->acl_len);
- + RtlCopyMemory(sec_desc, nfs41_fobx->aclcache.data,
- + nfs41_fobx->aclcache.data_len);
- RxContext->IoStatusBlock.Information =
- - RxContext->InformationToReturn = nfs41_fobx->acl_len;
- + RxContext->InformationToReturn =
- + nfs41_fobx->aclcache.data_len;
- RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
- #ifdef ENABLE_TIMINGS
- InterlockedIncrement(&getacl.sops);
- - InterlockedAdd64(&getacl.size, nfs41_fobx->acl_len);
- + InterlockedAdd64(&getacl.size, nfs41_fobx->aclcache.data_len);
- #endif
- DbgP("nfs41_QuerySecurityInformation: using cached ACL info\n");
- @@ -296,17 +299,18 @@ NTSTATUS nfs41_QuerySecurityInformation(
- }
- else {
- DbgP("nfs41_QuerySecurityInformation: "
- - "cache misses requested info, acl_secinfo=0x%lx, secinfo=0x%lx\n",
- - (unsigned long)nfs41_fobx->acl_secinfo,
- + "cache misses requested info, "
- + "acl_secinfo=0x%lx, secinfo=0x%lx\n",
- + (unsigned long)nfs41_fobx->aclcache.secinfo,
- (unsigned long)secinfo);
- }
- }
- - if (nfs41_fobx->acl) {
- - RxFreePool(nfs41_fobx->acl);
- - nfs41_fobx->acl = NULL;
- - nfs41_fobx->acl_len = 0;
- - nfs41_fobx->acl_secinfo = 0;
- + if (nfs41_fobx->aclcache.data) {
- + RxFreePool(nfs41_fobx->aclcache.data);
- + nfs41_fobx->aclcache.data = NULL;
- + nfs41_fobx->aclcache.data_len = 0;
- + nfs41_fobx->aclcache.secinfo = 0;
- }
- DbgP("nfs41_QuerySecurityInformation: cached ACL info invalidated\n");
- }
- @@ -347,24 +351,25 @@ NTSTATUS nfs41_QuerySecurityInformation(
- * Free previous ACL data. This can happen if two concurrent
- * requests are executed for the same file
- */
- - if (nfs41_fobx->acl) {
- - RxFreePool(nfs41_fobx->acl);
- - nfs41_fobx->acl = NULL;
- - nfs41_fobx->acl_len = 0;
- - nfs41_fobx->acl_secinfo = 0;
- + if (nfs41_fobx->aclcache.data) {
- + RxFreePool(nfs41_fobx->aclcache.data);
- + nfs41_fobx->aclcache.data = NULL;
- + nfs41_fobx->aclcache.data_len = 0;
- + nfs41_fobx->aclcache.secinfo = 0;
- }
- - nfs41_fobx->acl = entry->u.Acl.buf;
- - nfs41_fobx->acl_len = entry->u.Acl.buf_len;
- - nfs41_fobx->acl_secinfo = entry->u.Acl.query_secinfo;
- + nfs41_fobx->aclcache.data = entry->u.Acl.buf;
- + nfs41_fobx->aclcache.data_len = entry->u.Acl.buf_len;
- + nfs41_fobx->aclcache.secinfo = entry->u.Acl.query_secinfo;
- entry->u.Acl.buf = NULL;
- - KeQuerySystemTime(&nfs41_fobx->time);
- + KeQuerySystemTime(&nfs41_fobx->aclcache.time);
- PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
- RxContext->CurrentIrp->UserBuffer;
- - RtlCopyMemory(sec_desc, nfs41_fobx->acl, nfs41_fobx->acl_len);
- + RtlCopyMemory(sec_desc, nfs41_fobx->aclcache.data,
- + nfs41_fobx->aclcache.data_len);
- RxContext->IoStatusBlock.Information =
- - RxContext->InformationToReturn = nfs41_fobx->acl_len;
- + RxContext->InformationToReturn = nfs41_fobx->aclcache.data_len;
- RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
- #ifdef ENABLE_TIMINGS
- @@ -490,11 +495,11 @@ NTSTATUS nfs41_SetSecurityInformation(
- #endif
- /* Invalidate cached ACL info */
- - if (nfs41_fobx->acl) {
- - RxFreePool(nfs41_fobx->acl);
- - nfs41_fobx->acl = NULL;
- - nfs41_fobx->acl_len = 0;
- - nfs41_fobx->acl_secinfo = 0;
- + if (nfs41_fobx->aclcache.data) {
- + RxFreePool(nfs41_fobx->aclcache.data);
- + nfs41_fobx->aclcache.data = NULL;
- + nfs41_fobx->aclcache.data_len = 0;
- + nfs41_fobx->aclcache.secinfo = 0;
- }
- status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index 1ae41e0..df76d8a 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -918,9 +918,9 @@ NTSTATUS nfs41_DeallocateForFobx(
- nfs41_invalidate_fobx_entry(pFobx);
- nfs41_remove_offloadcontext_for_fobx(pFobx);
- - if (nfs41_fobx->acl) {
- - RxFreePool(nfs41_fobx->acl);
- - nfs41_fobx->acl = NULL;
- + if (nfs41_fobx->aclcache.data) {
- + RxFreePool(nfs41_fobx->aclcache.data);
- + nfs41_fobx->aclcache.data = NULL;
- }
- if (nfs41_fobx->sec_ctx.ClientToken) {
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index bc7537c..e559109 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -494,10 +494,12 @@ typedef struct _NFS41_FOBX {
- HANDLE nfs41_open_state;
- SECURITY_CLIENT_CONTEXT sec_ctx;
- - PVOID acl;
- - DWORD acl_len;
- - SECURITY_INFORMATION acl_secinfo;
- - LARGE_INTEGER time;
- + struct {
- + PVOID data;
- + DWORD data_len;
- + SECURITY_INFORMATION secinfo;
- + LARGE_INTEGER time;
- + } aclcache;
- DWORD deleg_type;
- BOOLEAN write_thru;
- BOOLEAN nocache;
- --
- 2.51.0
- From 396803642a9bc4263ee4706fc57093d33fdfb32a Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 21 Nov 2025 15:08:02 +0100
- Subject: [PATCH 13/28] sys: Move ACL cache to FCB so multiple FILE_OBJECTs can
- share it
- Move ACL cache to FCB so multiple FILE_OBJECTs can share it.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 78 ++++++++++++++++++++++++-------------------
- sys/nfs41sys_driver.c | 13 +++++---
- sys/nfs41sys_driver.h | 12 +++----
- 3 files changed, 58 insertions(+), 45 deletions(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index a927f09..a9f4200 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -234,6 +234,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- nfs41_updowncall_entry *entry = NULL;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -257,41 +258,41 @@ NTSTATUS nfs41_QuerySecurityInformation(
- status = check_nfs41_getacl_args(RxContext);
- if (status) goto out;
- - if (nfs41_fobx->aclcache.data && nfs41_fobx->aclcache.data_len) {
- + if (nfs41_fcb->aclcache.data && nfs41_fcb->aclcache.data_len) {
- LARGE_INTEGER current_time;
- KeQuerySystemTime(¤t_time);
- #ifdef DEBUG_ACL_QUERY
- DbgP("CurrentTime 0x%llx Saved Acl time 0x%llx\n",
- (long long)current_time.QuadPart,
- - (long long)nfs41_fobx->aclcache.time.QuadPart);
- + (long long)nfs41_fcb->aclcache.time.QuadPart);
- #endif
- - if ((current_time.QuadPart - nfs41_fobx->aclcache.time.QuadPart)
- + if ((current_time.QuadPart - nfs41_fcb->aclcache.time.QuadPart)
- <= (10*1000)) {
- - if (querysecuritylength < nfs41_fobx->aclcache.data_len) {
- + if (querysecuritylength < nfs41_fcb->aclcache.data_len) {
- status = STATUS_BUFFER_OVERFLOW;
- - RxContext->InformationToReturn = nfs41_fobx->aclcache.data_len;
- + RxContext->InformationToReturn = nfs41_fcb->aclcache.data_len;
- DbgP("nfs41_QuerySecurityInformation: "
- "STATUS_BUFFER_OVERFLOW for cached entry, "
- "got %lu, need %lu\n",
- (unsigned long)querysecuritylength,
- - (unsigned long)nfs41_fobx->aclcache.data_len);
- + (unsigned long)nfs41_fcb->aclcache.data_len);
- goto out;
- }
- /* Check whether the cached info have all the info we need */
- - if ((nfs41_fobx->aclcache.secinfo & secinfo) == secinfo) {
- + if ((nfs41_fcb->aclcache.secinfo & secinfo) == secinfo) {
- PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
- RxContext->CurrentIrp->UserBuffer;
- - RtlCopyMemory(sec_desc, nfs41_fobx->aclcache.data,
- - nfs41_fobx->aclcache.data_len);
- + RtlCopyMemory(sec_desc, nfs41_fcb->aclcache.data,
- + nfs41_fcb->aclcache.data_len);
- RxContext->IoStatusBlock.Information =
- RxContext->InformationToReturn =
- - nfs41_fobx->aclcache.data_len;
- + nfs41_fcb->aclcache.data_len;
- RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
- #ifdef ENABLE_TIMINGS
- InterlockedIncrement(&getacl.sops);
- - InterlockedAdd64(&getacl.size, nfs41_fobx->aclcache.data_len);
- + InterlockedAdd64(&getacl.size, nfs41_fcb->aclcache.data_len);
- #endif
- DbgP("nfs41_QuerySecurityInformation: using cached ACL info\n");
- @@ -301,16 +302,22 @@ NTSTATUS nfs41_QuerySecurityInformation(
- DbgP("nfs41_QuerySecurityInformation: "
- "cache misses requested info, "
- "acl_secinfo=0x%lx, secinfo=0x%lx\n",
- - (unsigned long)nfs41_fobx->aclcache.secinfo,
- + (unsigned long)nfs41_fcb->aclcache.secinfo,
- (unsigned long)secinfo);
- }
- }
- + else {
- + DbgP("nfs41_QuerySecurityInformation: acl cache expired, "
- + "current_time=%llu, nfs41_fcb->aclcache.time=%llu\n",
- + current_time.QuadPart, nfs41_fcb->aclcache.time.QuadPart);
- + }
- - if (nfs41_fobx->aclcache.data) {
- - RxFreePool(nfs41_fobx->aclcache.data);
- - nfs41_fobx->aclcache.data = NULL;
- - nfs41_fobx->aclcache.data_len = 0;
- - nfs41_fobx->aclcache.secinfo = 0;
- + if (nfs41_fcb->aclcache.data) {
- + RxFreePool(nfs41_fcb->aclcache.data);
- + nfs41_fcb->aclcache.data = NULL;
- + nfs41_fcb->aclcache.data_len = 0;
- + nfs41_fcb->aclcache.secinfo = 0;
- + nfs41_fcb->aclcache.time.QuadPart = 0LL;
- }
- DbgP("nfs41_QuerySecurityInformation: cached ACL info invalidated\n");
- }
- @@ -351,25 +358,26 @@ NTSTATUS nfs41_QuerySecurityInformation(
- * Free previous ACL data. This can happen if two concurrent
- * requests are executed for the same file
- */
- - if (nfs41_fobx->aclcache.data) {
- - RxFreePool(nfs41_fobx->aclcache.data);
- - nfs41_fobx->aclcache.data = NULL;
- - nfs41_fobx->aclcache.data_len = 0;
- - nfs41_fobx->aclcache.secinfo = 0;
- + if (nfs41_fcb->aclcache.data) {
- + RxFreePool(nfs41_fcb->aclcache.data);
- + nfs41_fcb->aclcache.data = NULL;
- + nfs41_fcb->aclcache.data_len = 0;
- + nfs41_fcb->aclcache.secinfo = 0;
- + nfs41_fcb->aclcache.time.QuadPart = 0LL;
- }
- - nfs41_fobx->aclcache.data = entry->u.Acl.buf;
- - nfs41_fobx->aclcache.data_len = entry->u.Acl.buf_len;
- - nfs41_fobx->aclcache.secinfo = entry->u.Acl.query_secinfo;
- + nfs41_fcb->aclcache.data = entry->u.Acl.buf;
- + nfs41_fcb->aclcache.data_len = entry->u.Acl.buf_len;
- + nfs41_fcb->aclcache.secinfo = entry->u.Acl.query_secinfo;
- entry->u.Acl.buf = NULL;
- - KeQuerySystemTime(&nfs41_fobx->aclcache.time);
- + KeQuerySystemTime(&nfs41_fcb->aclcache.time);
- PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
- RxContext->CurrentIrp->UserBuffer;
- - RtlCopyMemory(sec_desc, nfs41_fobx->aclcache.data,
- - nfs41_fobx->aclcache.data_len);
- + RtlCopyMemory(sec_desc, nfs41_fcb->aclcache.data,
- + nfs41_fcb->aclcache.data_len);
- RxContext->IoStatusBlock.Information =
- - RxContext->InformationToReturn = nfs41_fobx->aclcache.data_len;
- + RxContext->InformationToReturn = nfs41_fcb->aclcache.data_len;
- RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
- #ifdef ENABLE_TIMINGS
- @@ -414,6 +422,7 @@ NTSTATUS check_nfs41_setacl_args(
- NTSTATUS status = STATUS_SUCCESS;
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
- +
- SECURITY_INFORMATION secinfo =
- RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
- @@ -495,11 +504,12 @@ NTSTATUS nfs41_SetSecurityInformation(
- #endif
- /* Invalidate cached ACL info */
- - if (nfs41_fobx->aclcache.data) {
- - RxFreePool(nfs41_fobx->aclcache.data);
- - nfs41_fobx->aclcache.data = NULL;
- - nfs41_fobx->aclcache.data_len = 0;
- - nfs41_fobx->aclcache.secinfo = 0;
- + if (nfs41_fcb->aclcache.data) {
- + RxFreePool(nfs41_fcb->aclcache.data);
- + nfs41_fcb->aclcache.data = NULL;
- + nfs41_fcb->aclcache.data_len = 0;
- + nfs41_fcb->aclcache.secinfo = 0;
- + nfs41_fcb->aclcache.time.QuadPart = 0LL;
- }
- status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index df76d8a..4ea927a 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -906,7 +906,15 @@ NTSTATUS nfs41_Flush(
- NTSTATUS nfs41_DeallocateForFcb(
- IN OUT PMRX_FCB pFcb)
- {
- + __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(pFcb);
- +
- nfs41_remove_fcb_entry(pFcb);
- +
- + if (nfs41_fcb->aclcache.data) {
- + RxFreePool(nfs41_fcb->aclcache.data);
- + nfs41_fcb->aclcache.data = NULL;
- + }
- +
- return STATUS_SUCCESS;
- }
- @@ -918,11 +926,6 @@ NTSTATUS nfs41_DeallocateForFobx(
- nfs41_invalidate_fobx_entry(pFobx);
- nfs41_remove_offloadcontext_for_fobx(pFobx);
- - if (nfs41_fobx->aclcache.data) {
- - RxFreePool(nfs41_fobx->aclcache.data);
- - nfs41_fobx->aclcache.data = NULL;
- - }
- -
- if (nfs41_fobx->sec_ctx.ClientToken) {
- SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
- nfs41_fobx->sec_ctx.ClientToken = NULL;
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index e559109..4ef084a 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -483,6 +483,12 @@ typedef struct _NFS41_FCB {
- DWORD owner_local_uid; /* owner mapped into local uid */
- DWORD owner_group_local_gid; /* owner group mapped into local gid */
- #endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
- + struct {
- + PVOID data;
- + DWORD data_len;
- + SECURITY_INFORMATION secinfo;
- + LARGE_INTEGER time;
- + } aclcache;
- ULONGLONG changeattr;
- } NFS41_FCB, *PNFS41_FCB;
- #define NFS41GetFcbExtension(pFcb) \
- @@ -494,12 +500,6 @@ typedef struct _NFS41_FOBX {
- HANDLE nfs41_open_state;
- SECURITY_CLIENT_CONTEXT sec_ctx;
- - struct {
- - PVOID data;
- - DWORD data_len;
- - SECURITY_INFORMATION secinfo;
- - LARGE_INTEGER time;
- - } aclcache;
- DWORD deleg_type;
- BOOLEAN write_thru;
- BOOLEAN nocache;
- --
- 2.51.0
- From 3aca058e0b313786e6bd14313ccba2da2fa1ecd7 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 21 Nov 2025 15:08:52 +0100
- Subject: [PATCH 14/28] sys: Set ACL cache timeout to 10 seconds
- Set ACL cache timeout to 10 seconds.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index a9f4200..9ad1036 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -267,7 +267,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- (long long)nfs41_fcb->aclcache.time.QuadPart);
- #endif
- if ((current_time.QuadPart - nfs41_fcb->aclcache.time.QuadPart)
- - <= (10*1000)) {
- + <= (10*10000000)) {
- if (querysecuritylength < nfs41_fcb->aclcache.data_len) {
- status = STATUS_BUFFER_OVERFLOW;
- RxContext->InformationToReturn = nfs41_fcb->aclcache.data_len;
- --
- 2.51.0
- From bac22964088557658d5436442245e5fa2bbc4dc2 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 21 Nov 2025 15:58:59 +0100
- Subject: [PATCH 15/28] sys: Remove checks for
- |SACL_SECURITY_INFORMATION|+|LABEL_SECURITY_INFORMATION|
- Remove checks for |SACL_SECURITY_INFORMATION|+|LABEL_SECURITY_INFORMATION|,
- they are not really needed.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 20 --------------------
- 1 file changed, 20 deletions(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index 9ad1036..d9a67e7 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -207,23 +207,13 @@ NTSTATUS check_nfs41_getacl_args(
- PRX_CONTEXT RxContext)
- {
- NTSTATUS status = STATUS_SUCCESS;
- - SECURITY_INFORMATION secinfo =
- - RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
- - /* we don't support sacls (yet) */
- - if ((secinfo & SACL_SECURITY_INFORMATION) ||
- - (secinfo & LABEL_SECURITY_INFORMATION)) {
- - DbgP("check_nfs41_getacl_args: SACLs not supported (yet)\n");
- - status = STATUS_NOT_SUPPORTED;
- - goto out;
- - }
- if (RxContext->CurrentIrp->UserBuffer == NULL &&
- RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length) {
- DbgP("check_nfs41_getacl_args: "
- "RxContext->CurrentIrp->UserBuffer == NULL\n");
- status = STATUS_INVALID_USER_BUFFER;
- }
- -out:
- return status;
- }
- @@ -423,21 +413,11 @@ NTSTATUS check_nfs41_setacl_args(
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
- - SECURITY_INFORMATION secinfo =
- - RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
- -
- if (pVNetRootContext->read_only) {
- print_error("check_nfs41_setacl_args: Read-only mount\n");
- status = STATUS_MEDIA_WRITE_PROTECTED;
- goto out;
- }
- - /* we don't support sacls (yet) */
- - if ((secinfo & SACL_SECURITY_INFORMATION) ||
- - (secinfo & LABEL_SECURITY_INFORMATION)) {
- - DbgP("check_nfs41_setacl_args: SACLs not supported (yet)\n");
- - status = STATUS_NOT_SUPPORTED;
- - goto out;
- - }
- out:
- return status;
- }
- --
- 2.51.0
- From 8927f158e6cee9f8f07085170b856c7b7ad58b22 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 22 Nov 2025 12:50:48 +0100
- Subject: [PATCH 16/28] sys: Add |FAST_MUTEX| for ACL cache
- Add |FAST_MUTEX| for ACL cache.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 20 +++++++++++++++++++-
- sys/nfs41sys_driver.h | 2 ++
- sys/nfs41sys_openclose.c | 5 +++++
- 3 files changed, 26 insertions(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index d9a67e7..2c94021 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -58,6 +58,7 @@
- #include <winerror.h>
- #include <Ntstrsafe.h>
- +#include <stdbool.h>
- #include "nfs41sys_buildconfig.h"
- @@ -233,6 +234,8 @@ NTSTATUS nfs41_QuerySecurityInformation(
- RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
- ULONG querysecuritylength =
- RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length;
- + bool aclcache_locked = false;
- +
- #ifdef ENABLE_TIMINGS
- LARGE_INTEGER t1, t2;
- t1 = KeQueryPerformanceCounter(NULL);
- @@ -248,6 +251,9 @@ NTSTATUS nfs41_QuerySecurityInformation(
- status = check_nfs41_getacl_args(RxContext);
- if (status) goto out;
- + ExAcquireFastMutexUnsafe(&nfs41_fcb->aclcache.lock);
- + aclcache_locked = true;
- +
- if (nfs41_fcb->aclcache.data && nfs41_fcb->aclcache.data_len) {
- LARGE_INTEGER current_time;
- KeQuerySystemTime(¤t_time);
- @@ -382,7 +388,12 @@ NTSTATUS nfs41_QuerySecurityInformation(
- entry->u.Acl.buf = NULL;
- }
- }
- +
- out:
- + if (aclcache_locked) {
- + ExReleaseFastMutexUnsafe(&nfs41_fcb->aclcache.lock);
- + }
- +
- if (entry) {
- nfs41_UpcallDestroy(entry);
- }
- @@ -438,6 +449,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
- SECURITY_INFORMATION secinfo =
- RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
- +
- #ifdef ENABLE_TIMINGS
- LARGE_INTEGER t1, t2;
- t1 = KeQueryPerformanceCounter(NULL);
- @@ -483,7 +495,12 @@ NTSTATUS nfs41_SetSecurityInformation(
- InterlockedAdd64(&setacl.size, entry->u.Acl.buf_len);
- #endif
- - /* Invalidate cached ACL info */
- + /*
- + * Invalidate cached ACL info
- + * (we do not try to fill the cache afte a |NFS41_SYSOP_ACL_SET|
- + * because it is typically not read after that)
- + */
- + ExAcquireFastMutexUnsafe(&nfs41_fcb->aclcache.lock);
- if (nfs41_fcb->aclcache.data) {
- RxFreePool(nfs41_fcb->aclcache.data);
- nfs41_fcb->aclcache.data = NULL;
- @@ -491,6 +508,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- nfs41_fcb->aclcache.secinfo = 0;
- nfs41_fcb->aclcache.time.QuadPart = 0LL;
- }
- + ExReleaseFastMutexUnsafe(&nfs41_fcb->aclcache.lock);
- status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
- if (status) {
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 4ef084a..0296a91 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -472,6 +472,7 @@ typedef struct _NFS41_V_NET_ROOT_EXTENSION {
- typedef struct _NFS41_FCB {
- NODE_TYPE_CODE NodeTypeCode;
- NODE_BYTE_SIZE NodeByteSize;
- + BOOLEAN initialised;
- FILE_BASIC_INFORMATION BasicInfo;
- FILE_STANDARD_INFORMATION StandardInfo;
- ULONGLONG fileid;
- @@ -484,6 +485,7 @@ typedef struct _NFS41_FCB {
- DWORD owner_group_local_gid; /* owner group mapped into local gid */
- #endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
- struct {
- + FAST_MUTEX lock;
- PVOID data;
- DWORD data_len;
- SECURITY_INFORMATION secinfo;
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 53bb879..7a09cd8 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -655,6 +655,11 @@ NTSTATUS nfs41_Create(
- status = check_nfs41_create_args(RxContext);
- if (status) goto out;
- + if (nfs41_fcb->initialised == FALSE) {
- + nfs41_fcb->initialised = TRUE;
- + ExInitializeFastMutex(&nfs41_fcb->aclcache.lock);
- + }
- +
- debug_printirpecps(RxContext->CurrentIrp);
- PQUERY_ON_CREATE_ECP_CONTEXT qocec =
- --
- 2.51.0
- From 5257bf034e6dfaa883d1523a39f80d19bc8c5ddc Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 22 Nov 2025 22:37:24 +0100
- Subject: [PATCH 17/28] tests: Update NTP&co instructions for NFS test server
- setups
- Update NTP&co instructions for NFS test server setups.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/nfs_server_setup.txt | 29 ++++++++++++++++++++++++-----
- 1 file changed, 24 insertions(+), 5 deletions(-)
- diff --git a/tests/nfs_server_setup.txt b/tests/nfs_server_setup.txt
- index d945ec7..cafdaeb 100644
- --- a/tests/nfs_server_setup.txt
- +++ b/tests/nfs_server_setup.txt
- @@ -85,6 +85,13 @@ service nfs-server restart
- # Adminstrator PowerShell
- Install-WindowsFeature -name Telnet-Client
- +# make sure the time sync service is running and uses a valid ntp server:
- +sc config w32time start=auto
- +sc start w32time
- +w32tm /config /update /manualpeerlist:10.49.0.6
- +# wait 30sec and then verify the status:
- +w32tm /query /status
- +
- Import-Module ServerManager
- Add-WindowsFeature FS-NFS-Service
- Import-Module NFS
- @@ -114,8 +121,8 @@ C:\cygwin64\sbin\nfs_mount -o rw N nfs://192.168.209.129//
- #
- ##### 1. Server setup
- -# enable ntp server "10.49.0.5"
- -printf "server 10.49.0.5\n" >/etc/inet/ntp.conf
- +# enable ntp server "10.49.0.6"
- +printf "server 10.49.0.6\n" >'/etc/inet/ntp.conf'
- svcadm enable ntp
- # configure&start NFS server
- @@ -156,8 +163,8 @@ See https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/man
- #
- ##### 1. Server setup
- -# enable ntp server "10.49.0.5"
- -printf "server 10.49.0.5\n" >/etc/inet/ntp.conf
- +# enable ntp server "10.49.0.6"
- +printf "server 10.49.0.6\n" >'/etc/inet/ntp.conf'
- svcadm enable ntp
- svcadm restart ntp
- @@ -205,6 +212,17 @@ See https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/man
- # Install FreeBSD (14.3) with NTP enabled
- +# enable time server
- +-- snip --
- +printf 'server 10.49.0.6 prefer minpoll 5 maxpoll 8\nlogfile /var/log/ntp.log\nleapfile "/var/db/ntpd.leap-seconds.list"\n' >'/etc/ntp.conf'
- +sysrc ntpd_enable="YES"
- +sysrc ntpd_flags=""
- +sysrc ntpd_sync_on_start="YES"
- +-- snip --
- +
- +# Verify NTP config with
- +ntpq -np
- +
- # configure NFSv4.2 server with idmapping enabled
- sysrc rpcbind_enable="YES"
- sysrc mountd_enable="YES"
- @@ -217,6 +235,7 @@ printf 'vfs.nfs.enable_uidtostring=0\n' >>'/etc/sysctl.conf'
- printf 'vfs.nfsd.enable_stringtouid=0\n' >>'/etc/sysctl.conf'
- printf 'vfs.nfsd.issue_delegations=1\n' >>'/etc/sysctl.conf'
- +# configure an export
- mkdir /nfsdata
- chmod a+rwxt /nfsdata
- @@ -226,7 +245,7 @@ printf 'V4: /\n' >'/etc/exports'
- printf '/nfsdata -network=10.49.202.0 -mask=255.255.255.0 -sec=sys\n' >>'/etc/exports'
- service nfsd start
- -##### 2. ms-nfs41-client setup:
- +##### 2. FreeBSD-specific ms-nfs41-client setup:
- - Normal setup
- - Add groups entry for group "wheel" if neccesary:
- $ printf 'wheel:S-1-0-0:0:\n' >>'/etc/group'
- --
- 2.51.0
- From dedd2ca7bdb09e3f35313f7e1d59157a0a93850f Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 22 Nov 2025 22:57:10 +0100
- Subject: [PATCH 18/28] cygwin: Install nfs_server_setup.txt as
- /usr/share/msnfs41client/tests/nfs_server_setup.txt
- Install nfs_server_setup.txt as /usr/share/msnfs41client/tests/nfs_server_setup.txt
- for admins as reference.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- cygwin/Makefile.install | 1 +
- 1 file changed, 1 insertion(+)
- diff --git a/cygwin/Makefile.install b/cygwin/Makefile.install
- index 129366f..087fb34 100644
- --- a/cygwin/Makefile.install
- +++ b/cygwin/Makefile.install
- @@ -144,6 +144,7 @@ installdest:
- /usr/bin/ksh93 $(CYGWIN_MAKEFILE_DIR)/utils/nfsurlconv/nfsurlconv.ksh --nroff 2>"$(DESTDIR)/usr/share/man/man1/nfsurlconv.1" || true
- @ printf "# Package tests\n"
- cp "$(PROJECT_BASEDIR_DIR)/tests/manual_testing.txt" $(DESTDIR)/usr/share/msnfs41client/tests/manual_testing.txt
- + cp "$(PROJECT_BASEDIR_DIR)/tests/nfs_server_setup.txt" $(DESTDIR)/usr/share/msnfs41client/tests/nfs_server_setup.txt
- cp "$(PROJECT_BASEDIR_DIR)/tests/winfsinfo1/winfsinfo.x86_64.exe" $(DESTDIR)/bin/winfsinfo.x86_64.exe
- cp "$(PROJECT_BASEDIR_DIR)/tests/winfsinfo1/winfsinfo.i686.exe" $(DESTDIR)/bin/winfsinfo.i686.exe
- cp "$(PROJECT_BASEDIR_DIR)/tests/winclonefile/winclonefile.x86_64.exe" $(DESTDIR)/bin/winclonefile.x86_64.exe
- --
- 2.51.0
- From 1fe3257946fb74eb615ce7f34b3f223cb86e01be Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 29 Nov 2025 15:31:18 +0100
- Subject: [PATCH 19/28] sys: Move NFSv4.1 open state into |SRV_OPEN| extension
- Move NFSv4.1 openstate handle into |SRV_OPEN| extension.
- The Win32 RDR spec expects that a filesystem handle is stored in a
- |SRV_OPEN| extension (and not in a FOBX extension) so multiple
- FILE_OBJECT/FOBX can use one |SRV_OPEN| (the RDR calls this
- "collapsing").
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_acl.c | 8 +++--
- sys/nfs41sys_dir.c | 3 +-
- sys/nfs41sys_driver.c | 12 +++++--
- sys/nfs41sys_driver.h | 17 ++++++++--
- sys/nfs41sys_ea.c | 11 ++++---
- sys/nfs41sys_fileinfo.c | 8 +++--
- sys/nfs41sys_fsctl.c | 28 +++++++++-------
- sys/nfs41sys_lock.c | 6 ++--
- sys/nfs41sys_openclose.c | 69 ++++++++++++++++++++++++++--------------
- sys/nfs41sys_readwrite.c | 8 +++--
- sys/nfs41sys_symlink.c | 6 ++--
- sys/nfs41sys_volinfo.c | 3 +-
- 12 files changed, 119 insertions(+), 60 deletions(-)
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index 2c94021..16caa63 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -225,6 +225,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- nfs41_updowncall_entry *entry = NULL;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- @@ -319,7 +320,7 @@ NTSTATUS nfs41_QuerySecurityInformation(
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_ACL_QUERY, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -440,6 +441,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- nfs41_updowncall_entry *entry = NULL;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -483,7 +485,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_ACL_SET, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -519,7 +521,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- status = map_query_acl_error(entry->status);
- if (!status) {
- - if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
- + if ((nfs41_srvopen->deleg_type == 0) && entry->ChangeTime &&
- (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- diff --git a/sys/nfs41sys_dir.c b/sys/nfs41sys_dir.c
- index e80aa1e..60e5b50 100644
- --- a/sys/nfs41sys_dir.c
- +++ b/sys/nfs41sys_dir.c
- @@ -231,6 +231,7 @@ NTSTATUS nfs41_QueryDirectory(
- FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
- PUNICODE_STRING Filter = &RxContext->pFobx->UnicodeQueryTemplate;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -269,7 +270,7 @@ NTSTATUS nfs41_QueryDirectory(
- goto out;
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_DIR_QUERY, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index 4ea927a..0b7a1f6 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -1030,6 +1030,7 @@ void enable_caching(
- ULONGLONG ChangeTime,
- HANDLE session)
- {
- + PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- ULONG flag = 0;
- PLIST_ENTRY pEntry;
- nfs41_fcb_list_entry *cur;
- @@ -1078,7 +1079,7 @@ void enable_caching(
- }
- pEntry = pEntry->Flink;
- }
- - if (!found && nfs41_fobx->deleg_type) {
- + if (!found && (nfs41_srvopen->deleg_type != 0)) {
- nfs41_fcb_list_entry *oentry;
- #ifdef DEBUG_TIME_BASED_COHERENCY
- DbgP("enable_caching: delegation recalled: srv_open=0x%p\n", SrvOpen);
- @@ -1092,7 +1093,7 @@ void enable_caching(
- oentry->ChangeTime = ChangeTime;
- oentry->skip = FALSE;
- InsertTailList(&openlist.head, &oentry->next);
- - nfs41_fobx->deleg_type = 0;
- + nfs41_srvopen->deleg_type = 0;
- }
- out_release_fcblistlock:
- ExReleaseFastMutexUnsafe(&openlist.lock);
- @@ -1227,12 +1228,14 @@ NTSTATUS nfs41_init_ops(void)
- nfs41_ops.MRxFlags = (RDBSS_MANAGE_NET_ROOT_EXTENSION |
- RDBSS_MANAGE_V_NET_ROOT_EXTENSION |
- RDBSS_MANAGE_FCB_EXTENSION |
- + RDBSS_MANAGE_SRV_OPEN_EXTENSION |
- RDBSS_MANAGE_FOBX_EXTENSION);
- nfs41_ops.MRxSrvCallSize = 0; // srvcall extension is not handled in rdbss
- nfs41_ops.MRxNetRootSize = sizeof(NFS41_NETROOT_EXTENSION);
- nfs41_ops.MRxVNetRootSize = sizeof(NFS41_V_NET_ROOT_EXTENSION);
- nfs41_ops.MRxFcbSize = sizeof(NFS41_FCB);
- + nfs41_ops.MRxSrvOpenSize = sizeof(NFS41_SRV_OPEN);
- nfs41_ops.MRxFobxSize = sizeof(NFS41_FOBX);
- // Mini redirector cancel routine
- @@ -1417,11 +1420,14 @@ VOID fcbopen_main(PVOID ctx)
- pNetRootContext =
- NFS41GetNetRootExtension(cur->fcb->pNetRoot);
- + PNFS41_SRV_OPEN nfs41_srvopen =
- + NFS41GetSrvOpenExtension(cur->srvopen);
- +
- /* place an upcall for this srv_open */
- status = nfs41_UpcallCreate(
- NFS41_SYSOP_FILE_QUERY_TIME_BASED_COHERENCY,
- &cur->nfs41_fobx->sec_ctx, cur->session,
- - cur->nfs41_fobx->nfs41_open_state,
- + nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, NULL, &entry);
- if (status) goto out;
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 0296a91..9c979f7 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -95,6 +95,9 @@ typedef struct __nfs41_timings {
- /* Windows SMB driver also uses |IO_NETWORK_INCREMENT| */
- #define IO_NFS41FS_INCREMENT IO_NETWORK_INCREMENT
- +/* Number of bytes needed to store an SID */
- +#define SID_BUF_SIZE (SECURITY_MAX_SID_SIZE)
- +
- #define DISABLE_CACHING 0
- #define ENABLE_READ_CACHING 1
- #define ENABLE_WRITE_CACHING 2
- @@ -496,13 +499,22 @@ typedef struct _NFS41_FCB {
- #define NFS41GetFcbExtension(pFcb) \
- (((pFcb) == NULL) ? NULL : (PNFS41_FCB)((pFcb)->Context))
- +typedef struct _NFS41_SRV_OPEN {
- + HANDLE nfs41_open_state;
- + DWORD deleg_type;
- +} NFS41_SRV_OPEN, *PNFS41_SRV_OPEN;
- +#define NFS41GetSrvOpenExtension(pSrvOpen) \
- + (((pSrvOpen) == NULL) ? NULL : (PNFS41_SRV_OPEN)((pSrvOpen)->Context))
- +
- typedef struct _NFS41_FOBX {
- NODE_TYPE_CODE NodeTypeCode;
- NODE_BYTE_SIZE NodeByteSize;
- - HANDLE nfs41_open_state;
- + /*
- + * |sec_ctx| must be per |FILE_OBJECT| to handle newgrp()1/|setgid()|
- + * support
- + */
- SECURITY_CLIENT_CONTEXT sec_ctx;
- - DWORD deleg_type;
- BOOLEAN write_thru;
- BOOLEAN nocache;
- BOOLEAN timebasedcoherency;
- @@ -533,6 +545,7 @@ typedef struct _NFS41_DEVICE_EXTENSION {
- typedef struct _nfs41_fcb_list_entry {
- LIST_ENTRY next;
- PMRX_FCB fcb;
- + PMRX_SRV_OPEN srvopen;
- HANDLE session;
- PNFS41_FOBX nfs41_fobx;
- ULONGLONG ChangeTime;
- diff --git a/sys/nfs41sys_ea.c b/sys/nfs41sys_ea.c
- index 1d415da..0f2a9dd 100644
- --- a/sys/nfs41sys_ea.c
- +++ b/sys/nfs41sys_ea.c
- @@ -349,6 +349,7 @@ NTSTATUS nfs41_SetEaInformation(
- nfs3_attrs *attrs = NULL;
- ULONG buflen = RxContext->CurrentIrpSp->Parameters.SetEa.Length, error_offset;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -371,7 +372,7 @@ NTSTATUS nfs41_SetEaInformation(
- if (status) goto out;
- status = nfs41_UpcallCreate(NFS41_SYSOP_EA_SET, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -411,7 +412,7 @@ NTSTATUS nfs41_SetEaInformation(
- #endif
- status = map_setea_error(entry->status);
- if (!status) {
- - if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
- + if ((nfs41_srvopen->deleg_type == 0) && entry->ChangeTime &&
- (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- @@ -479,6 +480,7 @@ NTSTATUS QueryCygwinSymlink(
- OUT PFILE_FULL_EA_INFORMATION info)
- {
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION NetRootContext =
- @@ -501,7 +503,7 @@ NTSTATUS QueryCygwinSymlink(
- HeaderLen, 0xFFFF);
- status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_GET, &Fobx->sec_ctx,
- - VNetRootContext->session, Fobx->nfs41_open_state,
- + VNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- NetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -630,6 +632,7 @@ NTSTATUS nfs41_QueryEaInformation(
- RxContext->CurrentIrpSp->Parameters.QueryEa.EaList;
- ULONG buflen = RxContext->CurrentIrpSp->Parameters.QueryEa.Length;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -657,7 +660,7 @@ NTSTATUS nfs41_QueryEaInformation(
- goto out;
- status = nfs41_UpcallCreate(NFS41_SYSOP_EA_GET, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- diff --git a/sys/nfs41sys_fileinfo.c b/sys/nfs41sys_fileinfo.c
- index 991646b..1bf736f 100644
- --- a/sys/nfs41sys_fileinfo.c
- +++ b/sys/nfs41sys_fileinfo.c
- @@ -205,6 +205,7 @@ NTSTATUS nfs41_QueryFileInformation(
- FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
- nfs41_updowncall_entry *entry = NULL;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -407,7 +408,7 @@ NTSTATUS nfs41_QueryFileInformation(
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_FILE_QUERY, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) {
- print_error("nfs41_QueryFileInformation: "
- @@ -676,6 +677,7 @@ NTSTATUS nfs41_SetFileInformationImpl(
- FILE_RENAME_INFORMATION rinfo;
- #endif /* FORCE_POSIX_SEMANTICS_DELETE */
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -788,7 +790,7 @@ NTSTATUS nfs41_SetFileInformationImpl(
- }
- status = nfs41_UpcallCreate(opcode, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -822,7 +824,7 @@ NTSTATUS nfs41_SetFileInformationImpl(
- status = map_setfile_error(entry->status);
- if (!status) {
- - if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
- + if ((nfs41_srvopen->deleg_type != 0) && entry->ChangeTime &&
- (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- diff --git a/sys/nfs41sys_fsctl.c b/sys/nfs41sys_fsctl.c
- index 864ad78..f31b976 100644
- --- a/sys/nfs41sys_fsctl.c
- +++ b/sys/nfs41sys_fsctl.c
- @@ -128,6 +128,7 @@ NTSTATUS nfs41_QueryAllocatedRanges(
- NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
- nfs41_updowncall_entry *entry = NULL;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -161,7 +162,7 @@ NTSTATUS nfs41_QueryAllocatedRanges(
- status = nfs41_UpcallCreate(NFS41_SYSOP_FSCTL_QUERYALLOCATEDRANGES,
- &nfs41_fobx->sec_ctx,
- pVNetRootContext->session,
- - nfs41_fobx->nfs41_open_state,
- + nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version,
- SrvOpen->pAlreadyPrefixedName,
- &entry);
- @@ -448,6 +449,7 @@ NTSTATUS nfs41_SetZeroData(
- NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
- nfs41_updowncall_entry *entry = NULL;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -501,7 +503,7 @@ NTSTATUS nfs41_SetZeroData(
- status = nfs41_UpcallCreate(NFS41_SYSOP_FSCTL_SET_ZERO_DATA,
- &nfs41_fobx->sec_ctx,
- pVNetRootContext->session,
- - nfs41_fobx->nfs41_open_state,
- + nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version,
- SrvOpen->pAlreadyPrefixedName,
- &entry);
- @@ -629,6 +631,7 @@ NTSTATUS nfs41_DuplicateData(
- NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
- nfs41_updowncall_entry *entry = NULL;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -751,6 +754,7 @@ NTSTATUS nfs41_DuplicateData(
- PFCB srcfcb = srcfo->FsContext;
- PFOBX srcfox = srcfo->FsContext2;
- PNFS41_FCB nfs41_src_fcb = NFS41GetFcbExtension(srcfcb);
- + PNFS41_SRV_OPEN src_nfs41_srvopen = NFS41GetSrvOpenExtension(srcfox->SrvOpen);
- PNFS41_FOBX nfs41_src_fobx = NFS41GetFobxExtension(srcfox);
- if (!nfs41_src_fcb) {
- @@ -807,7 +811,7 @@ NTSTATUS nfs41_DuplicateData(
- status = nfs41_UpcallCreate(NFS41_SYSOP_FSCTL_DUPLICATE_DATA,
- &nfs41_fobx->sec_ctx,
- pVNetRootContext->session,
- - nfs41_fobx->nfs41_open_state,
- + nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version,
- SrvOpen->pAlreadyPrefixedName,
- &entry);
- @@ -815,7 +819,7 @@ NTSTATUS nfs41_DuplicateData(
- if (status)
- goto out;
- - entry->u.DuplicateData.src_state = nfs41_src_fobx->nfs41_open_state;
- + entry->u.DuplicateData.src_state = src_nfs41_srvopen->nfs41_open_state;
- entry->u.DuplicateData.srcfileoffset = dd.srcfileoffset;
- entry->u.DuplicateData.destfileoffset = dd.destfileoffset;
- entry->u.DuplicateData.bytecount = dd.bytecount;
- @@ -949,7 +953,7 @@ typedef struct _offloadcontext_entry
- */
- ERESOURCE resource;
- STORAGE_OFFLOAD_TOKEN token;
- - PNFS41_FOBX src_fobx;
- + PMRX_FOBX src_fobx;
- ULONGLONG src_fileoffset;
- ULONGLONG src_length;
- } offloadcontext_entry;
- @@ -960,7 +964,6 @@ void nfs41_remove_offloadcontext_for_fobx(
- {
- PLIST_ENTRY pEntry;
- offloadcontext_entry *cur, *found = NULL;
- - __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
- ExAcquireFastMutexUnsafe(&offloadcontextlist.lock);
- @@ -968,7 +971,7 @@ void nfs41_remove_offloadcontext_for_fobx(
- while (!IsListEmpty(&offloadcontextlist.head)) {
- cur = (offloadcontext_entry *)CONTAINING_RECORD(pEntry,
- offloadcontext_entry, next);
- - if (cur->src_fobx == nfs41_fobx) {
- + if (cur->src_fobx == pFobx) {
- found = cur;
- break;
- }
- @@ -1054,7 +1057,6 @@ NTSTATUS nfs41_OffloadRead(
- __notnull const XXCTL_LOWIO_COMPONENT *FsCtl =
- &RxContext->LowIoContext.ParamsFor.FsCtl;
- __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
- - __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- DbgEn();
- @@ -1124,7 +1126,7 @@ NTSTATUS nfs41_OffloadRead(
- *((USHORT *)(&oce->token.TokenIdLength[0])) =
- STORAGE_OFFLOAD_TOKEN_ID_LENGTH;
- *((void **)(&oce->token.Token[0])) = oce;
- - oce->src_fobx = nfs41_fobx;
- + oce->src_fobx = RxContext->pFobx;
- oce->src_fileoffset = ori->FileOffset;
- oce->src_length = ori->CopyLength;
- @@ -1180,6 +1182,7 @@ NTSTATUS nfs41_OffloadWrite(
- NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
- nfs41_updowncall_entry *entry = NULL;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -1291,12 +1294,13 @@ NTSTATUS nfs41_OffloadWrite(
- goto out;
- }
- - PNFS41_FOBX nfs41_src_fobx = src_oce->src_fobx;
- + PNFS41_FOBX nfs41_src_fobx = NFS41GetFobxExtension(src_oce->src_fobx);
- if (!nfs41_src_fobx) {
- DbgP("nfs41_OffloadWrite: No nfs41_src_fobx\n");
- status = STATUS_INVALID_PARAMETER;
- goto out;
- }
- + PNFS41_SRV_OPEN src_nfs41_srvopen = NFS41GetSrvOpenExtension(((PFOBX)src_oce->src_fobx)->SrvOpen);
- /*
- * Disable caching because NFSv4.2 COPY is basically a
- @@ -1314,7 +1318,7 @@ NTSTATUS nfs41_OffloadWrite(
- status = nfs41_UpcallCreate(NFS41_SYSOP_FSCTL_OFFLOAD_DATACOPY,
- &nfs41_fobx->sec_ctx,
- pVNetRootContext->session,
- - nfs41_fobx->nfs41_open_state,
- + nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version,
- SrvOpen->pAlreadyPrefixedName,
- &entry);
- @@ -1322,7 +1326,7 @@ NTSTATUS nfs41_OffloadWrite(
- if (status)
- goto out;
- - entry->u.DuplicateData.src_state = nfs41_src_fobx->nfs41_open_state;
- + entry->u.DuplicateData.src_state = src_nfs41_srvopen->nfs41_open_state;
- entry->u.DuplicateData.srcfileoffset = dd.srcfileoffset;
- entry->u.DuplicateData.destfileoffset = dd.destfileoffset;
- entry->u.DuplicateData.bytecount = dd.bytecount;
- diff --git a/sys/nfs41sys_lock.c b/sys/nfs41sys_lock.c
- index 7b52ad6..71a7dec 100644
- --- a/sys/nfs41sys_lock.c
- +++ b/sys/nfs41sys_lock.c
- @@ -268,6 +268,7 @@ NTSTATUS nfs41_Lock(
- PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -301,7 +302,7 @@ NTSTATUS nfs41_Lock(
- #endif /* NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING */
- status = nfs41_UpcallCreate(NFS41_SYSOP_LOCK, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -379,6 +380,7 @@ NTSTATUS nfs41_Unlock(
- PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
- __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -415,7 +417,7 @@ NTSTATUS nfs41_Unlock(
- #endif /* NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING */
- status = nfs41_UpcallCreate(NFS41_SYSOP_UNLOCK, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 7a09cd8..41cc89a 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -619,6 +619,27 @@ out:
- return status;
- }
- +NTSTATUS nfs41_createnetfobx(
- + PRX_CONTEXT RxContext,
- + PMRX_SRV_OPEN SrvOpen)
- +{
- + NTSTATUS status;
- + PNFS41_FOBX nfs41_fobx;
- +
- + RxContext->pFobx = RxCreateNetFobx(RxContext, SrvOpen);
- + if (RxContext->pFobx == NULL) {
- + status = STATUS_INSUFFICIENT_RESOURCES;
- + goto out;
- + }
- +
- + nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- + status = nfs41_get_sec_ctx(SecurityImpersonation, &nfs41_fobx->sec_ctx);
- +
- +out:
- + return status;
- +}
- +
- +
- NTSTATUS nfs41_Create(
- IN OUT PRX_CONTEXT RxContext)
- {
- @@ -628,6 +649,7 @@ NTSTATUS nfs41_Create(
- PFILE_FULL_EA_INFORMATION ea = (PFILE_FULL_EA_INFORMATION)
- RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -943,21 +965,16 @@ retry_on_link:
- fcb_locked_exclusive = true;
- }
- - RxContext->pFobx = RxCreateNetFobx(RxContext, SrvOpen);
- - if (RxContext->pFobx == NULL) {
- - status = STATUS_INSUFFICIENT_RESOURCES;
- + nfs41_srvopen->nfs41_open_state = entry->open_state;
- +
- + status = nfs41_createnetfobx(RxContext, SrvOpen);
- + if (status)
- goto out;
- - }
- +
- #ifdef DEBUG_OPEN
- DbgP("nfs41_Create: created FOBX 0x%p\n", RxContext->pFobx);
- #endif
- nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
- - nfs41_fobx->nfs41_open_state = entry->open_state;
- - if (nfs41_fobx->sec_ctx.ClientToken == NULL) {
- - status = nfs41_get_sec_ctx(SecurityImpersonation, &nfs41_fobx->sec_ctx);
- - if (status)
- - goto out;
- - }
- // we get attributes only for data access and file (not directories)
- if (Fcb->OpenCount == 0 ||
- @@ -1104,7 +1121,7 @@ retry_on_link:
- if (!nfs41_fcb->StandardInfo.Directory &&
- isDataAccess(params->DesiredAccess)) {
- - nfs41_fobx->deleg_type = entry->u.Open.deleg_type;
- + nfs41_srvopen->deleg_type = entry->u.Open.deleg_type;
- #ifdef DEBUG_OPEN
- DbgP("nfs41_Create: received delegation %d\n", entry->u.Open.deleg_type);
- #endif
- @@ -1168,6 +1185,7 @@ retry_on_link:
- goto out;
- }
- oentry->fcb = RxContext->pFcb;
- + oentry->srvopen = SrvOpen;
- oentry->nfs41_fobx = nfs41_fobx;
- oentry->session = pVNetRootContext->session;
- oentry->ChangeTime = entry->ChangeTime;
- @@ -1225,23 +1243,25 @@ out:
- return status;
- }
- -NTSTATUS nfs41_CollapseOpen(
- +NTSTATUS nfs41_ShouldTryToCollapseThisOpen(
- IN OUT PRX_CONTEXT RxContext)
- {
- - NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
- - DbgEn();
- - FsRtlEnterFileSystem();
- - FsRtlExitFileSystem();
- - DbgEx();
- - return status;
- + if (RxContext->pRelevantSrvOpen == NULL)
- + return STATUS_SUCCESS;
- + return STATUS_MORE_PROCESSING_REQUIRED;
- }
- -NTSTATUS nfs41_ShouldTryToCollapseThisOpen(
- +/*
- + * |nfs41_CollapseOpen()| - like |nfs41_Create()|, but use an existing
- + * |MRX_SRV_OPEN|.
- + * This means one |MRX_SRV_OPEN| can have multiple |NFS41_FOBX|/|FILE_OBJECTS|
- + * if the access parameters match.
- + */
- +NTSTATUS nfs41_CollapseOpen(
- IN OUT PRX_CONTEXT RxContext)
- {
- - if (RxContext->pRelevantSrvOpen == NULL)
- - return STATUS_SUCCESS;
- - else return STATUS_MORE_PROCESSING_REQUIRED;
- + NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
- + return status;
- }
- NTSTATUS map_close_errors(
- @@ -1271,6 +1291,7 @@ NTSTATUS nfs41_CloseSrvOpen(
- NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
- nfs41_updowncall_entry *entry = NULL;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -1288,13 +1309,13 @@ NTSTATUS nfs41_CloseSrvOpen(
- #endif
- FsRtlEnterFileSystem();
- - if (!nfs41_fobx->deleg_type && !nfs41_fcb->StandardInfo.Directory &&
- + if ((nfs41_srvopen->deleg_type == 0) && !nfs41_fcb->StandardInfo.Directory &&
- !RxContext->pFcb->OpenCount) {
- nfs41_remove_fcb_entry(RxContext->pFcb);
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_CLOSE, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- diff --git a/sys/nfs41sys_readwrite.c b/sys/nfs41sys_readwrite.c
- index f82549c..8f313d9 100644
- --- a/sys/nfs41sys_readwrite.c
- +++ b/sys/nfs41sys_readwrite.c
- @@ -236,6 +236,7 @@ NTSTATUS nfs41_Read(
- BOOLEAN async = FALSE;
- PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -258,7 +259,7 @@ NTSTATUS nfs41_Read(
- if (status) goto out;
- status = nfs41_UpcallCreate(NFS41_SYSOP_READ, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -364,6 +365,7 @@ NTSTATUS nfs41_Write(
- BOOLEAN async = FALSE;
- PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -386,7 +388,7 @@ NTSTATUS nfs41_Write(
- if (status) goto out;
- status = nfs41_UpcallCreate(NFS41_SYSOP_WRITE, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -441,7 +443,7 @@ NTSTATUS nfs41_Write(
- FCB_STATE_WRITECACHING_ENABLED))) {
- enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
- pVNetRootContext->session);
- - } else if (!nfs41_fobx->deleg_type)
- + } else if (nfs41_srvopen->deleg_type == 0)
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- } else {
- diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
- index 2c81f9a..c157164 100644
- --- a/sys/nfs41sys_symlink.c
- +++ b/sys/nfs41sys_symlink.c
- @@ -259,6 +259,7 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
- (const PREPARSE_DATA_BUFFER)FsCtl->pInputBuffer;
- __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -416,7 +417,7 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_SET, &Fobx->sec_ctx,
- - VNetRootContext->session, Fobx->nfs41_open_state,
- + VNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- @@ -569,6 +570,7 @@ NTSTATUS nfs41_GetSymlinkReparsePoint(
- XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
- __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -602,7 +604,7 @@ NTSTATUS nfs41_GetSymlinkReparsePoint(
- TargetName.MaximumLength = (USHORT)targetname_buffer_len;
- status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_GET, &Fobx->sec_ctx,
- - VNetRootContext->session, Fobx->nfs41_open_state,
- + VNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- diff --git a/sys/nfs41sys_volinfo.c b/sys/nfs41sys_volinfo.c
- index 017dcb6..10b9c61 100644
- --- a/sys/nfs41sys_volinfo.c
- +++ b/sys/nfs41sys_volinfo.c
- @@ -153,6 +153,7 @@ NTSTATUS nfs41_QueryVolumeInformation(
- ULONG RemainingLength = RxContext->Info.LengthRemaining, SizeUsed;
- FS_INFORMATION_CLASS InfoClass = RxContext->Info.FsInformationClass;
- __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + __notnull PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- @@ -206,7 +207,7 @@ NTSTATUS nfs41_QueryVolumeInformation(
- goto out;
- }
- status = nfs41_UpcallCreate(NFS41_SYSOP_VOLUME_QUERY, &nfs41_fobx->sec_ctx,
- - pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
- + pVNetRootContext->session, nfs41_srvopen->nfs41_open_state,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- if (status) goto out;
- --
- 2.51.0
- From 51ffe18a79710ea0b53e2f152a687078ed322607 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 29 Nov 2025 16:11:35 +0100
- Subject: [PATCH 20/28] sys: Implement SRV_OPEN collapsing
- Implement SRV_OPEN collapsing.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_buildconfig.h | 46 ++++++++++++
- sys/nfs41sys_driver.c | 11 +++
- sys/nfs41sys_driver.h | 15 ++++
- sys/nfs41sys_openclose.c | 149 +++++++++++++++++++++++++++++++++++++
- sys/nfs41sys_updowncall.c | 32 ++++++++
- sys/nfs41sys_util.c | 59 +++++++++++++++
- sys/nfs41sys_util.h | 3 +
- 7 files changed, 315 insertions(+)
- diff --git a/sys/nfs41sys_buildconfig.h b/sys/nfs41sys_buildconfig.h
- index 760f39d..dea5e1d 100644
- --- a/sys/nfs41sys_buildconfig.h
- +++ b/sys/nfs41sys_buildconfig.h
- @@ -50,6 +50,52 @@
- // #define LOOKASIDELISTS_STATS 1
- #endif /* (NTDDI_VERSION >= NTDDI_WIN10_VB) */
- +/*
- + * |ENABLE_COLLAPSEOPEN| - SRV_OPEN collapse support
- + *
- + * This will re-use an existing SRV_OPEN
- + * when opening a file with matching parameters/flags, avoiding an
- + * upcall to the NFS server.
- + *
- + * This is currently experimental (and shoud be a mount option),
- + * requires more testing.
- + *
- + * Note this only has limited benefits (because it only short-cuts
- + * duplicate file opening requests to the NFS server) except in a
- + * benchmark which measures pure file |open()| performance:
- + * ---- snip ----
- + * $ cat "open_x_c_100000times.c"
- + * #include <windows.h>
- + * int main() {
- + * CreateFileA("x.c", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
- + * for(int i=0;i<100000;i++) {
- + * HANDLE h;
- + * h = CreateFileA("x.c", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
- + * CloseHandle(h);
- + * }
- + * return 0;
- + * }
- + *
- + * # with collapsing enabled:
- + * $ time ./open_x_c_100000times.c
- + *
- + * real 3m20.027s
- + * user 0m0.562s
- + * sys 0m34.296s
- + * # collapsing disabled:
- + * $ time ./open_x_c_100000times.c
- + *
- + * real 6m59.528s
- + * user 0m1.155s
- + * sys 0m48.936s
- + * ---- snip ----
- + */
- +#define ENABLE_COLLAPSEOPEN 1
- +#ifdef ENABLE_COLLAPSEOPEN
- +#define WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER 1
- +#define WINBUG_WORKAROUND_CLOSESRVOPEN_CALLED_AFTER_FOXB_CLEANUP 1
- +#endif /* ENABLE_COLLAPSEOPEN */
- +
- /* debugging printout defines */
- #if defined(_DEBUG)
- /* Debug build defines follow... */
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index 0b7a1f6..a8a2810 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -787,6 +787,17 @@ NTSTATUS nfs41_CreateSrvCall(
- ASSERT( pSrvCall );
- ASSERT( NodeType(pSrvCall) == RDBSS_NTC_SRVCALL );
- +#ifdef ENABLE_COLLAPSEOPEN
- + /*
- + * FIXME: This should be a tuneable
- + *
- + * Notes:
- + * - Windows 10 limit is 1023 per
- + * $ powershell -Command 'Get-SmbClientConfiguration | Select DormantFileLimit'
- + */
- + pSrvCall->MaximumNumberOfCloseDelayedFiles = 8192;
- +#endif /* ENABLE_COLLAPSEOPEN */
- +
- if (IoGetCurrentProcess() == RxGetRDBSSProcess()) {
- DbgP("executing with RDBSS context\n");
- status = _nfs41_CreateSrvCall(pCallbackContext);
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 9c979f7..32b3629 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -500,8 +500,23 @@ typedef struct _NFS41_FCB {
- (((pFcb) == NULL) ? NULL : (PNFS41_FCB)((pFcb)->Context))
- typedef struct _NFS41_SRV_OPEN {
- + BOOLEAN initialised;
- HANDLE nfs41_open_state;
- DWORD deleg_type;
- +#ifdef WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER
- + /*
- + * |open_pg_sidbuff| - Note that buffers with SID values must be 16byte
- + * aligned on Windows 10/32bit
- + */
- +#ifdef _MSC_BUILD
- + __declspec(align(16)) char open_pg_sidbuff[SID_BUF_SIZE];
- +#else
- + char open_pg_sidbuff[SID_BUF_SIZE] __attribute__((aligned(16)));
- +#endif /* _MSC_BUILD */
- +
- + /* |open_pg_sid| - PrimaryGroup SID used for opening this NFS handle */
- + PSID open_pg_sid;
- +#endif /* WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER */
- } NFS41_SRV_OPEN, *PNFS41_SRV_OPEN;
- #define NFS41GetSrvOpenExtension(pSrvOpen) \
- (((pSrvOpen) == NULL) ? NULL : (PNFS41_SRV_OPEN)((pSrvOpen)->Context))
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 41cc89a..c88d27f 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -682,6 +682,28 @@ NTSTATUS nfs41_Create(
- ExInitializeFastMutex(&nfs41_fcb->aclcache.lock);
- }
- + if (nfs41_srvopen->initialised == FALSE) {
- + nfs41_srvopen->initialised = TRUE;
- +#ifdef WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER
- + /* PrimaryGroup SID used for opening this NFS handle */
- + nfs41_srvopen->open_pg_sid = (PSID)nfs41_srvopen->open_pg_sidbuff;
- +
- + /*
- + * Store PrimaryGroup SID used to create the |SRV_OPEN|
- + *
- + * This is used to test whether the PrimaryGroup of a
- + * collapsing request is the same as this SID, and reject
- + * the collapsing request if the groups do not match,
- + * to avoid that a |SRV_OPEN| with the wrong group is reused.
- + */
- + if (!get_primarygroup_id(nfs41_srvopen->open_pg_sid)) {
- + DbgP("nfs41_Create: get_primarygroup_id() failed\n");
- + status = STATUS_INSUFFICIENT_RESOURCES;
- + goto out;
- + }
- +#endif /* WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER */
- + }
- +
- debug_printirpecps(RxContext->CurrentIrp);
- PQUERY_ON_CREATE_ECP_CONTEXT qocec =
- @@ -1246,9 +1268,100 @@ out:
- NTSTATUS nfs41_ShouldTryToCollapseThisOpen(
- IN OUT PRX_CONTEXT RxContext)
- {
- +#ifdef ENABLE_COLLAPSEOPEN
- + NTSTATUS status = STATUS_SUCCESS;
- + PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
- + PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- + PNFS41_SRV_OPEN nfs41_srvopen = NFS41GetSrvOpenExtension(SrvOpen);
- +
- + if (SrvOpen == NULL) {
- + DbgP("nfs41_ShouldTryToCollapseThisOpen: "
- + "SrvOpen==NULL, status=STATUS_SUCCESS\n");
- + return STATUS_SUCCESS;
- + }
- +
- + if (nfs41_fcb->StandardInfo.Directory) {
- + status = STATUS_MORE_PROCESSING_REQUIRED;
- + goto out;
- + }
- +
- +#ifdef WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER
- + /*
- + * Reject srvopens if the primary group used to create
- + * |RxContext->pRelevantSrvOpen| does not match the current primary group
- + *
- + * Example:
- + * $ bash -c $'command exec {n}<x.c ; newgrp cygwingrp2 bash -c \'id -a ; \
- + * for ((i=0 ; i < 5 ; i++)) ; do (command exec {nn}<x.c) done\''
- + *
- + * What happens here is that we start with primarygroup="None",
- + * start bash.exe, obtain a read file handle for file "x.c".
- + * Then we call newgrp to run a new bash.exe with a different primarygroup
- + * ("cygwingrp2", but same user), and request read file handles for "x.c"
- + * again.
- + * |MRxCollapseOpen()| is called to collapse the open request for "x.c"
- + * with primarygroup="cygwingrp2" into the SRV_OPEN which was created for
- + * primarygroup="Kein" - which leads to a privilege escalation if group
- + * "Kein" has access to the file but group "cygwingrp2" does not.
- + */
- +
- + /*
- + * |pg_sidbuff| - Note that buffers with SID values must be 16byte
- + * aligned on Windows 10/32bit
- + */
- +#ifdef _MSC_BUILD
- + __declspec(align(16)) char pg_sidbuff[SID_BUF_SIZE];
- +#else
- + char pg_sidbuff[SID_BUF_SIZE] __attribute__((aligned(16)));
- +#endif /* _MSC_BUILD */
- + PSID pg_sid = (PSID)pg_sidbuff;
- +
- + (void)get_primarygroup_id(pg_sid);
- +
- + if (RtlEqualSid(pg_sid, nfs41_srvopen->open_pg_sid)) {
- + status = STATUS_SUCCESS;
- + }
- + else {
- + wchar_t pg_sid_string_buf[200];
- + UNICODE_STRING pg_sid_string = {
- + .Buffer = pg_sid_string_buf,
- + .Length = 0,
- + .MaximumLength = sizeof(pg_sid_string_buf)
- + };
- +
- + wchar_t srvopen_pg_sid_string_buf[200];
- + UNICODE_STRING srvopen_pg_sid_string = {
- + .Buffer = srvopen_pg_sid_string_buf,
- + .Length = 0,
- + .MaximumLength = sizeof(srvopen_pg_sid_string_buf)
- + };
- +
- + (void)RtlConvertSidToUnicodeString(&pg_sid_string, pg_sid, FALSE);
- + (void)RtlConvertSidToUnicodeString(&srvopen_pg_sid_string,
- + nfs41_srvopen->open_pg_sid, FALSE);
- + DbgP("nfs41_ShouldTryToCollapseThisOpen: "
- + "Threads pg SID('%wZ') != nfs41_srvopen->open_pg_sid('%wZ')\n",
- + &pg_sid_string,
- + &srvopen_pg_sid_string);
- +
- + status = STATUS_MORE_PROCESSING_REQUIRED;
- + goto out;
- + }
- +#else
- + status = STATUS_SUCCESS;
- +#endif /* WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER */
- +
- +out:
- + DbgP("nfs41_ShouldTryToCollapseThisOpen: filename='%wZ', status=0x%lx\n",
- + SrvOpen->pAlreadyPrefixedName,
- + (long)status);
- +
- + return status;
- +#else
- if (RxContext->pRelevantSrvOpen == NULL)
- return STATUS_SUCCESS;
- return STATUS_MORE_PROCESSING_REQUIRED;
- +#endif /* ENABLE_COLLAPSEOPEN */
- }
- /*
- @@ -1260,7 +1373,43 @@ NTSTATUS nfs41_ShouldTryToCollapseThisOpen(
- NTSTATUS nfs41_CollapseOpen(
- IN OUT PRX_CONTEXT RxContext)
- {
- +#ifdef ENABLE_COLLAPSEOPEN
- + NTSTATUS status;
- + PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
- +
- + FsRtlEnterFileSystem();
- +
- + /*
- + * FIXME/ToDo:
- + * - Check whether ECP (Extended Create Parameters) must be handled
- + * - Check whether Cygwin/SFU EA must be handled
- + */
- +
- + debug_printirpecps(RxContext->CurrentIrp);
- +
- + PQUERY_ON_CREATE_ECP_CONTEXT qocec =
- + get_queryoncreateecpcontext(RxContext->CurrentIrp);
- + if (qocec) {
- + DbgP("nfs41_CollapseOpen: RequestedClasses=0x%lx\n",
- + qocec->RequestedClasses);
- + }
- +
- + status = nfs41_createnetfobx(RxContext, SrvOpen);
- + if (status)
- + goto out;
- +
- + RxContext->pFobx->OffsetOfNextEaToReturn = 1; /* FIXME: Why ? */
- + status = STATUS_SUCCESS;
- +
- +out:
- + DbgP("nfs41_CollapseOpen: collapsingopen for '%wZ', status=0x%lx\n",
- + SrvOpen->pAlreadyPrefixedName,
- + (long)status);
- +
- + FsRtlExitFileSystem();
- +#else
- NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
- +#endif /* ENABLE_COLLAPSEOPEN */
- return status;
- }
- diff --git a/sys/nfs41sys_updowncall.c b/sys/nfs41sys_updowncall.c
- index cd1c1c2..84417e7 100644
- --- a/sys/nfs41sys_updowncall.c
- +++ b/sys/nfs41sys_updowncall.c
- @@ -383,6 +383,38 @@ NTSTATUS nfs41_UpcallCreate(
- KeInitializeEvent(&entry->cond, SynchronizationEvent, FALSE);
- ExInitializeFastMutex(&entry->lock);
- +#ifdef WINBUG_WORKAROUND_CLOSESRVOPEN_CALLED_AFTER_FOXB_CLEANUP
- + /*
- + * HACK: Workaround the RDBSS bug where |RxPurgeRelatedFobxs()| first
- + * destroyes a FOBX via |RxFinalizeNetFobx()|,and then calls
- + * |nfs41_CloseSrvOpen()| to close the SRV_OPEN with the same FOBX,
- + * which results in |clnt_sec_ctx->ClientToken == NULL|.
- + *
- + * Without the workaround we crash like this, because
- + * |clnt_sec_ctx->ClientToken == NULL|:
- + * ---- snip ----
- + * nt!ObfReferenceObject
- + * nfs41_driver!nfs41_UpcallCreate
- + * nfs41_driver!nfs41_CloseSrvOpen
- + * nfs41_driver!RxCloseAssociatedSrvOpen
- + * nfs41_driver!RxFinalizeNetFobx
- + * nfs41_driver!RxDereference
- + * nfs41_driver!RxPurgeRelatedFobxs
- + * nfs41_driver!RxCommonSetInformation
- + * nfs41_driver!RxFsdCommonDispatch
- + * nfs41_driver!RxFsdDispatch
- + * nfs41_driver!nfs41_FsdDispatch
- + * ---- snip ----
- + */
- + if (opcode == NFS41_SYSOP_CLOSE) {
- + if (clnt_sec_ctx) {
- + if (clnt_sec_ctx->ClientToken == NULL) {
- + clnt_sec_ctx = NULL;
- + }
- + }
- + }
- +#endif /* WINBUG_WORKAROUND_CLOSESRVOPEN_CALLED_AFTER_FOXB_CLEANUP */
- +
- if (clnt_sec_ctx == NULL) {
- SeCaptureSubjectContext(&sec_ctx);
- sec_qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
- diff --git a/sys/nfs41sys_util.c b/sys/nfs41sys_util.c
- index 27691fd..f116aa5 100644
- --- a/sys/nfs41sys_util.c
- +++ b/sys/nfs41sys_util.c
- @@ -221,3 +221,62 @@ PQUERY_ON_CREATE_ECP_CONTEXT get_queryoncreateecpcontext(
- return (PQUERY_ON_CREATE_ECP_CONTEXT)ecpContext;
- }
- +
- +bool get_primarygroup_id(__out SID *restrict ret_sid)
- +{
- + PACCESS_TOKEN token = NULL;
- + PVOID infoBuffer = NULL;
- + NTSTATUS status;
- + bool retval = false;
- +
- + BOOLEAN copyOnOpen = FALSE;
- + BOOLEAN effectiveOnly = FALSE;
- + SECURITY_IMPERSONATION_LEVEL impLevel;
- + token = PsReferenceImpersonationToken(PsGetCurrentThread(),
- + ©OnOpen, &effectiveOnly, &impLevel);
- + if (token == NULL) {
- + token = PsReferencePrimaryToken(PsGetCurrentProcess());
- + if (token == NULL) {
- + DbgP("get_primarygroup_id: Failed to get token\n");
- + return false;
- + }
- + }
- +
- + status = SeQueryInformationToken(token,
- + TokenPrimaryGroup, &infoBuffer);
- + if (!NT_SUCCESS(status) || (infoBuffer == NULL)) {
- + DbgPrint("get_primarygroup_id: "
- + "SeQueryInformationToken(TokenPrimaryGroup) failed: 0x%lx\n",
- + (long)status);
- + goto out_cleanup_sequeryinfotok;
- + }
- +
- + TOKEN_PRIMARY_GROUP *primaryGroup = (TOKEN_PRIMARY_GROUP *)infoBuffer;
- + if ((primaryGroup == NULL) || (primaryGroup->PrimaryGroup == NULL)) {
- + DbgP("get_primarygroup_id: "
- + "primaryGroup or PrimaryGroup SID is NULL\n");
- + goto out_cleanup_sequeryinfotok;
- + }
- +
- + ULONG sidLength = RtlLengthSid(primaryGroup->PrimaryGroup);
- + if ((sidLength == 0UL) || (sidLength > SID_BUF_SIZE)) {
- + DbgP("get_primarygroup_id: "
- + "SID length (%lu) invalid or too large for buffer (%u)\n",
- + sidLength, (unsigned)SID_BUF_SIZE);
- + goto out_cleanup_sequeryinfotok;
- + }
- +
- + (void)memcpy(ret_sid, primaryGroup->PrimaryGroup, sidLength);
- + retval = true;
- +
- +out_cleanup_sequeryinfotok:
- + if (infoBuffer) {
- + ExFreePool(infoBuffer);
- + }
- +
- + if (token) {
- + ObDereferenceObject(token);
- + }
- +
- + return retval;
- +}
- diff --git a/sys/nfs41sys_util.h b/sys/nfs41sys_util.h
- index 793f440..f3a1aec 100644
- --- a/sys/nfs41sys_util.h
- +++ b/sys/nfs41sys_util.h
- @@ -24,6 +24,8 @@
- #ifndef _NFS41SYS_UTIL_H_
- #define _NFS41SYS_UTIL_H_ 1
- +#include <stdbool.h>
- +
- static INLINE BOOL AnsiStrEq(
- IN const ANSI_STRING *lhs,
- IN const CHAR *rhs,
- @@ -67,5 +69,6 @@ NTSTATUS nfs41_UnmapLockedKernelPagesInNfsDaemonAddressSpace(
- __in PMDL MemoryDescriptorList);
- PQUERY_ON_CREATE_ECP_CONTEXT get_queryoncreateecpcontext(
- __in PIRP Irp);
- +bool get_primarygroup_id(__out SID *restrict ret_sid);
- #endif /* !_NFS41SYS_UTIL_H_ */
- --
- 2.51.0
- From e3b62e6418a2605ed6ac7ecf82e26863b2466322 Mon Sep 17 00:00:00 2001
- From: Dan Shelton <dan.f.shelton@gmail.com>
- Date: Sat, 29 Nov 2025 16:26:28 +0100
- Subject: [PATCH 21/28] sys: nfs41_UpcallCreate()+opcode2string() should use
- nfs41_opcodes enum
- nfs41_UpcallCreate()+opcode2string() should use nfs41_opcodes enum.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_debug.c | 2 +-
- sys/nfs41sys_debug.h | 4 +++-
- sys/nfs41sys_driver.h | 4 +++-
- sys/nfs41sys_updowncall.c | 2 +-
- 4 files changed, 8 insertions(+), 4 deletions(-)
- diff --git a/sys/nfs41sys_debug.c b/sys/nfs41sys_debug.c
- index f17fa13..a8513e9 100644
- --- a/sys/nfs41sys_debug.c
- +++ b/sys/nfs41sys_debug.c
- @@ -671,7 +671,7 @@ void print_caching_level(int on, ULONG flag, PUNICODE_STRING name)
- }
- }
- -const char *opcode2string(int opcode)
- +const char *opcode2string(nfs41_opcodes opcode)
- {
- switch(opcode) {
- case NFS41_SYSOP_SHUTDOWN: return "NFS41_SYSOP_SHUTDOWN";
- diff --git a/sys/nfs41sys_debug.h b/sys/nfs41sys_debug.h
- index aac1c31..d9dd4d0 100644
- --- a/sys/nfs41sys_debug.h
- +++ b/sys/nfs41sys_debug.h
- @@ -24,6 +24,8 @@
- #ifndef NFS41SYS_DEBUG_H
- #define NFS41SYS_DEBUG_H 1
- +typedef enum _nfs41_opcodes nfs41_opcodes;
- +
- #define _DRIVER_NAME_ "NFS4.1 Driver"
- ULONG __cdecl DbgP(IN PCCH fmt, ...);
- @@ -50,7 +52,7 @@ void print_std_info(int on, PFILE_STANDARD_INFORMATION info);
- void print_ea_info(PFILE_FULL_EA_INFORMATION info);
- void print_get_ea(int on, PFILE_GET_EA_INFORMATION info);
- void print_caching_level(int on, ULONG flag, PUNICODE_STRING s);
- -const char *opcode2string(int opcode);
- +const char *opcode2string(nfs41_opcodes opcode);
- void print_open_error(int on, int status);
- void print_wait_status(int on, const char *str, NTSTATUS status,
- const char *opcode, PVOID entry, LONGLONG xid);
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 32b3629..40eb7ea 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -34,6 +34,8 @@
- #include "nfs_ea.h"
- +typedef enum _nfs41_opcodes nfs41_opcodes;
- +
- #if (NTDDI_VERSION >= NTDDI_WIN10_VB)
- #define EXALLOCATEPOOLWITHTAG_DEPRECATED 1
- #endif /* (NTDDI_VERSION >= NTDDI_WIN10_VB) */
- @@ -928,7 +930,7 @@ void unmarshal_nfs41_attrget(
- const unsigned char *restrict *restrict buf,
- BOOL copy_partial);
- NTSTATUS nfs41_UpcallCreate(
- - IN DWORD opcode,
- + IN nfs41_opcodes opcode,
- IN PSECURITY_CLIENT_CONTEXT clnt_sec_ctx,
- IN HANDLE session,
- IN HANDLE open_state,
- diff --git a/sys/nfs41sys_updowncall.c b/sys/nfs41sys_updowncall.c
- index 84417e7..4a44f2b 100644
- --- a/sys/nfs41sys_updowncall.c
- +++ b/sys/nfs41sys_updowncall.c
- @@ -349,7 +349,7 @@ out:
- }
- NTSTATUS nfs41_UpcallCreate(
- - IN DWORD opcode,
- + IN nfs41_opcodes opcode,
- IN PSECURITY_CLIENT_CONTEXT clnt_sec_ctx,
- IN HANDLE session,
- IN HANDLE open_state,
- --
- 2.51.0
- From 858d1a030423743d9c1c396e7e7650bc83e63f00 Mon Sep 17 00:00:00 2001
- From: Cedric Blancher <cedric.blancher@gmail.com>
- Date: Sat, 29 Nov 2025 16:44:00 +0100
- Subject: [PATCH 22/28] daemon: get_superblock_attrs() should print fsid when
- warning that "forcecaseinsensitive=1" mount override is active
- get_superblock_attrs() should print fsid when warning that
- "forcecaseinsensitive=1" mount override is active.
- Signed-off-by: Roland Mainz <roland.mainz@nrubsig.org>
- ---
- daemon/nfs41_superblock.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
- diff --git a/daemon/nfs41_superblock.c b/daemon/nfs41_superblock.c
- index 3e64444..5ffb171 100644
- --- a/daemon/nfs41_superblock.c
- +++ b/daemon/nfs41_superblock.c
- @@ -134,7 +134,9 @@ static int get_superblock_attrs(
- else {
- superblock->case_preserving = BOOL2BIT(root->force_case_preserving);
- DPRINTF(0,
- - ("get_superblock_attrs: OVERRIDING case_preserving to %d\n",
- + ("get_superblock_attrs(fsid=(%llu,%llu)): "
- + "OVERRIDING case_preserving to %d\n",
- + superblock->fsid.major, superblock->fsid.minor,
- (int)superblock->case_preserving));
- }
- if (root->force_case_insensitive == TRISTATE_BOOL_NOT_SET) {
- @@ -143,7 +145,9 @@ static int get_superblock_attrs(
- else {
- superblock->case_insensitive = BOOL2BIT(root->force_case_insensitive);
- DPRINTF(0,
- - ("get_superblock_attrs: OVERRIDING case_insensitive to %d\n",
- + ("get_superblock_attrs(fsid=(%llu,%llu)): "
- + "OVERRIDING case_insensitive to %d\n",
- + superblock->fsid.major, superblock->fsid.minor,
- (int)superblock->case_insensitive));
- }
- #else
- --
- 2.51.0
- From 543202a540ed0c412984f8700eb81e8849a85558 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 29 Nov 2025 17:40:53 +0100
- Subject: [PATCH 23/28] daemon,include,sys: Kernel should use enum for
- |deleg_type|
- Kernel should use an enum for |deleg_type|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/nfs41_ops.h | 1 +
- include/nfs41_driver.h | 8 ++++++++
- sys/nfs41sys_acl.c | 5 +++--
- sys/nfs41sys_driver.c | 4 ++--
- sys/nfs41sys_driver.h | 2 +-
- sys/nfs41sys_ea.c | 2 +-
- sys/nfs41sys_fileinfo.c | 2 +-
- sys/nfs41sys_openclose.c | 14 ++++++++------
- sys/nfs41sys_readwrite.c | 4 ++--
- 9 files changed, 27 insertions(+), 15 deletions(-)
- diff --git a/daemon/nfs41_ops.h b/daemon/nfs41_ops.h
- index f1bf145..c7d45a8 100644
- --- a/daemon/nfs41_ops.h
- +++ b/daemon/nfs41_ops.h
- @@ -621,6 +621,7 @@ enum {
- OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED = 0x20000
- };
- +/* Same as "include/nfs41_driver.h" |nfs41_open_delegation_type| */
- enum open_delegation_type4 {
- OPEN_DELEGATE_NONE = 0,
- OPEN_DELEGATE_READ = 1,
- diff --git a/include/nfs41_driver.h b/include/nfs41_driver.h
- index ce4fb54..dbb17ba 100644
- --- a/include/nfs41_driver.h
- +++ b/include/nfs41_driver.h
- @@ -97,6 +97,14 @@ typedef enum _nfs41_opcodes {
- NFS41_SYSOP_INVALID_OPCODE1
- } nfs41_opcodes;
- +/* Same as "daemon/nfs41_ops.h" |open_delegation_type4| */
- +typedef enum _nfs41_open_delegation_type {
- + NFS41_OPEN_DELEGATE_NONE = 0,
- + NFS41_OPEN_DELEGATE_READ = 1,
- + NFS41_OPEN_DELEGATE_WRITE = 2,
- + NFS41_OPEN_DELEGATE_NONE_EXT = 3
- +} nfs41_open_delegation_type;
- +
- /*
- * Same as |FILE_FS_ATTRIBUTE_INFORMATION| but with inline buffer
- * for 32 characters
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index 16caa63..1ef55ca 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -521,8 +521,9 @@ NTSTATUS nfs41_SetSecurityInformation(
- status = map_query_acl_error(entry->status);
- if (!status) {
- - if ((nfs41_srvopen->deleg_type == 0) && entry->ChangeTime &&
- - (SrvOpen->DesiredAccess &
- + if ((nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) &&
- + entry->ChangeTime &&
- + (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- nfs41_fcb->changeattr = entry->ChangeTime;
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index a8a2810..b906e64 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -1090,7 +1090,7 @@ void enable_caching(
- }
- pEntry = pEntry->Flink;
- }
- - if (!found && (nfs41_srvopen->deleg_type != 0)) {
- + if (!found && (nfs41_srvopen->deleg_type != NFS41_OPEN_DELEGATE_NONE)) {
- nfs41_fcb_list_entry *oentry;
- #ifdef DEBUG_TIME_BASED_COHERENCY
- DbgP("enable_caching: delegation recalled: srv_open=0x%p\n", SrvOpen);
- @@ -1104,7 +1104,7 @@ void enable_caching(
- oentry->ChangeTime = ChangeTime;
- oentry->skip = FALSE;
- InsertTailList(&openlist.head, &oentry->next);
- - nfs41_srvopen->deleg_type = 0;
- + nfs41_srvopen->deleg_type = NFS41_OPEN_DELEGATE_NONE;
- }
- out_release_fcblistlock:
- ExReleaseFastMutexUnsafe(&openlist.lock);
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 40eb7ea..a3a74c7 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -504,7 +504,7 @@ typedef struct _NFS41_FCB {
- typedef struct _NFS41_SRV_OPEN {
- BOOLEAN initialised;
- HANDLE nfs41_open_state;
- - DWORD deleg_type;
- + nfs41_open_delegation_type deleg_type;
- #ifdef WINBUG_NO_COLLAPSE_IF_PRIMARYGROUPS_DIFFER
- /*
- * |open_pg_sidbuff| - Note that buffers with SID values must be 16byte
- diff --git a/sys/nfs41sys_ea.c b/sys/nfs41sys_ea.c
- index 0f2a9dd..6e690f6 100644
- --- a/sys/nfs41sys_ea.c
- +++ b/sys/nfs41sys_ea.c
- @@ -412,7 +412,7 @@ NTSTATUS nfs41_SetEaInformation(
- #endif
- status = map_setea_error(entry->status);
- if (!status) {
- - if ((nfs41_srvopen->deleg_type == 0) && entry->ChangeTime &&
- + if ((nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) && entry->ChangeTime &&
- (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- diff --git a/sys/nfs41sys_fileinfo.c b/sys/nfs41sys_fileinfo.c
- index 1bf736f..be92f0a 100644
- --- a/sys/nfs41sys_fileinfo.c
- +++ b/sys/nfs41sys_fileinfo.c
- @@ -824,7 +824,7 @@ NTSTATUS nfs41_SetFileInformationImpl(
- status = map_setfile_error(entry->status);
- if (!status) {
- - if ((nfs41_srvopen->deleg_type != 0) && entry->ChangeTime &&
- + if ((nfs41_srvopen->deleg_type != NFS41_OPEN_DELEGATE_NONE) && entry->ChangeTime &&
- (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index c88d27f..1d2378c 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -1167,7 +1167,7 @@ retry_on_link:
- if (!(params->CreateOptions & FILE_WRITE_THROUGH) &&
- !pVNetRootContext->write_thru &&
- - (entry->u.Open.deleg_type == 2 ||
- + (entry->u.Open.deleg_type == NFS41_OPEN_DELEGATE_WRITE ||
- (params->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))) {
- #ifdef DEBUG_OPEN
- DbgP("nfs41_Create: enabling write buffering\n");
- @@ -1178,8 +1178,9 @@ retry_on_link:
- } else if (params->CreateOptions & FILE_WRITE_THROUGH ||
- pVNetRootContext->write_thru)
- nfs41_fobx->write_thru = TRUE;
- - if (entry->u.Open.deleg_type >= 1 ||
- - params->DesiredAccess & FILE_READ_DATA) {
- + if ((entry->u.Open.deleg_type == NFS41_OPEN_DELEGATE_READ) ||
- + (entry->u.Open.deleg_type == NFS41_OPEN_DELEGATE_WRITE) ||
- + (params->DesiredAccess & FILE_READ_DATA)) {
- #ifdef DEBUG_OPEN
- DbgP("nfs41_Create: enabling read buffering\n");
- #endif
- @@ -1195,7 +1196,7 @@ retry_on_link:
- #endif
- SrvOpen->BufferingFlags = FCB_STATE_DISABLE_LOCAL_BUFFERING;
- nfs41_fobx->nocache = TRUE;
- - } else if (!entry->u.Open.deleg_type && !Fcb->OpenCount) {
- + } else if ((entry->u.Open.deleg_type == NFS41_OPEN_DELEGATE_NONE) && !Fcb->OpenCount) {
- nfs41_fcb_list_entry *oentry;
- #ifdef DEBUG_OPEN
- DbgP("nfs41_Create: received no delegations: srv_open=0x%p "
- @@ -1458,8 +1459,9 @@ NTSTATUS nfs41_CloseSrvOpen(
- #endif
- FsRtlEnterFileSystem();
- - if ((nfs41_srvopen->deleg_type == 0) && !nfs41_fcb->StandardInfo.Directory &&
- - !RxContext->pFcb->OpenCount) {
- + if ((nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) &&
- + !nfs41_fcb->StandardInfo.Directory &&
- + RxContext->pFcb->OpenCount == 0) {
- nfs41_remove_fcb_entry(RxContext->pFcb);
- }
- diff --git a/sys/nfs41sys_readwrite.c b/sys/nfs41sys_readwrite.c
- index 8f313d9..c9f95db 100644
- --- a/sys/nfs41sys_readwrite.c
- +++ b/sys/nfs41sys_readwrite.c
- @@ -443,9 +443,9 @@ NTSTATUS nfs41_Write(
- FCB_STATE_WRITECACHING_ENABLED))) {
- enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
- pVNetRootContext->session);
- - } else if (nfs41_srvopen->deleg_type == 0)
- + } else if (nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) {
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- -
- + }
- } else {
- status = map_readwrite_errors(entry->status);
- RxContext->CurrentIrp->IoStatus.Status = status;
- --
- 2.51.0
- From a85eb27895fa48c85de32131e6f1aabd2c09dc8f Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 29 Nov 2025 18:12:27 +0100
- Subject: [PATCH 24/28] include,sys: Kernel should handle
- |NFS41_OPEN_DELEGATE_NONE_EXT| the same as |NFS41_OPEN_DELEGATE_NONE|
- Kernel should handle |NFS41_OPEN_DELEGATE_NONE_EXT| the same as
- |NFS41_OPEN_DELEGATE_NONE|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- include/nfs41_driver.h | 4 ++++
- sys/nfs41sys_acl.c | 2 +-
- sys/nfs41sys_driver.c | 2 +-
- sys/nfs41sys_ea.c | 5 +++--
- sys/nfs41sys_fileinfo.c | 5 +++--
- sys/nfs41sys_openclose.c | 5 +++--
- sys/nfs41sys_readwrite.c | 2 +-
- 7 files changed, 16 insertions(+), 9 deletions(-)
- diff --git a/include/nfs41_driver.h b/include/nfs41_driver.h
- index dbb17ba..8aad552 100644
- --- a/include/nfs41_driver.h
- +++ b/include/nfs41_driver.h
- @@ -105,6 +105,10 @@ typedef enum _nfs41_open_delegation_type {
- NFS41_OPEN_DELEGATE_NONE_EXT = 3
- } nfs41_open_delegation_type;
- +#define IS_NFS41_OPEN_DELEGATE_NONE(dt) \
- + (((dt) == NFS41_OPEN_DELEGATE_NONE) || \
- + ((dt) == NFS41_OPEN_DELEGATE_NONE_EXT))
- +
- /*
- * Same as |FILE_FS_ATTRIBUTE_INFORMATION| but with inline buffer
- * for 32 characters
- diff --git a/sys/nfs41sys_acl.c b/sys/nfs41sys_acl.c
- index 1ef55ca..0ab1f80 100644
- --- a/sys/nfs41sys_acl.c
- +++ b/sys/nfs41sys_acl.c
- @@ -521,7 +521,7 @@ NTSTATUS nfs41_SetSecurityInformation(
- status = map_query_acl_error(entry->status);
- if (!status) {
- - if ((nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) &&
- + if ((IS_NFS41_OPEN_DELEGATE_NONE(nfs41_srvopen->deleg_type)) &&
- entry->ChangeTime &&
- (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index b906e64..564087d 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -1090,7 +1090,7 @@ void enable_caching(
- }
- pEntry = pEntry->Flink;
- }
- - if (!found && (nfs41_srvopen->deleg_type != NFS41_OPEN_DELEGATE_NONE)) {
- + if (!found && (!IS_NFS41_OPEN_DELEGATE_NONE(nfs41_srvopen->deleg_type))) {
- nfs41_fcb_list_entry *oentry;
- #ifdef DEBUG_TIME_BASED_COHERENCY
- DbgP("enable_caching: delegation recalled: srv_open=0x%p\n", SrvOpen);
- diff --git a/sys/nfs41sys_ea.c b/sys/nfs41sys_ea.c
- index 6e690f6..8ba33f4 100644
- --- a/sys/nfs41sys_ea.c
- +++ b/sys/nfs41sys_ea.c
- @@ -412,8 +412,9 @@ NTSTATUS nfs41_SetEaInformation(
- #endif
- status = map_setea_error(entry->status);
- if (!status) {
- - if ((nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) && entry->ChangeTime &&
- - (SrvOpen->DesiredAccess &
- + if (IS_NFS41_OPEN_DELEGATE_NONE(nfs41_srvopen->deleg_type) &&
- + entry->ChangeTime &&
- + (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- nfs41_fcb->changeattr = entry->ChangeTime;
- diff --git a/sys/nfs41sys_fileinfo.c b/sys/nfs41sys_fileinfo.c
- index be92f0a..b1642bf 100644
- --- a/sys/nfs41sys_fileinfo.c
- +++ b/sys/nfs41sys_fileinfo.c
- @@ -824,8 +824,9 @@ NTSTATUS nfs41_SetFileInformationImpl(
- status = map_setfile_error(entry->status);
- if (!status) {
- - if ((nfs41_srvopen->deleg_type != NFS41_OPEN_DELEGATE_NONE) && entry->ChangeTime &&
- - (SrvOpen->DesiredAccess &
- + if ((!IS_NFS41_OPEN_DELEGATE_NONE(nfs41_srvopen->deleg_type)) &&
- + entry->ChangeTime &&
- + (SrvOpen->DesiredAccess &
- (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- nfs41_fcb->changeattr = entry->ChangeTime;
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 1d2378c..bde50a0 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -1196,7 +1196,8 @@ retry_on_link:
- #endif
- SrvOpen->BufferingFlags = FCB_STATE_DISABLE_LOCAL_BUFFERING;
- nfs41_fobx->nocache = TRUE;
- - } else if ((entry->u.Open.deleg_type == NFS41_OPEN_DELEGATE_NONE) && !Fcb->OpenCount) {
- + } else if (IS_NFS41_OPEN_DELEGATE_NONE(entry->u.Open.deleg_type) &&
- + (Fcb->OpenCount == 0)) {
- nfs41_fcb_list_entry *oentry;
- #ifdef DEBUG_OPEN
- DbgP("nfs41_Create: received no delegations: srv_open=0x%p "
- @@ -1459,7 +1460,7 @@ NTSTATUS nfs41_CloseSrvOpen(
- #endif
- FsRtlEnterFileSystem();
- - if ((nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) &&
- + if (IS_NFS41_OPEN_DELEGATE_NONE(nfs41_srvopen->deleg_type) &&
- !nfs41_fcb->StandardInfo.Directory &&
- RxContext->pFcb->OpenCount == 0) {
- nfs41_remove_fcb_entry(RxContext->pFcb);
- diff --git a/sys/nfs41sys_readwrite.c b/sys/nfs41sys_readwrite.c
- index c9f95db..75145a5 100644
- --- a/sys/nfs41sys_readwrite.c
- +++ b/sys/nfs41sys_readwrite.c
- @@ -443,7 +443,7 @@ NTSTATUS nfs41_Write(
- FCB_STATE_WRITECACHING_ENABLED))) {
- enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
- pVNetRootContext->session);
- - } else if (nfs41_srvopen->deleg_type == NFS41_OPEN_DELEGATE_NONE) {
- + } else if (IS_NFS41_OPEN_DELEGATE_NONE(nfs41_srvopen->deleg_type)) {
- nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
- }
- } else {
- --
- 2.51.0
- From 102158222e0b9fa45087dd21dbe1501d6e7799cf Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 1 Dec 2025 10:56:27 +0100
- Subject: [PATCH 25/28] sys: Move |nfs41_AreFilesAliased()| and
- |nfs41_DeallocateForFobx()| to nfs41sys_openclose.c
- Move |nfs41_AreFilesAliased()| and |nfs41_DeallocateForFobx()| to
- nfs41sys_openclose.c.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_driver.c | 86 ----------------------------------------
- sys/nfs41sys_driver.h | 5 +++
- sys/nfs41sys_openclose.c | 86 ++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 91 insertions(+), 86 deletions(-)
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index 564087d..69616c4 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -871,40 +871,6 @@ VOID nfs41_remove_fcb_entry(
- ExReleaseFastMutexUnsafe(&openlist.lock);
- }
- -static
- -VOID nfs41_invalidate_fobx_entry(
- - IN OUT PMRX_FOBX pFobx)
- -{
- - PLIST_ENTRY pEntry;
- - nfs41_fcb_list_entry *cur;
- - __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
- -
- - ExAcquireFastMutexUnsafe(&openlist.lock);
- -
- - pEntry = openlist.head.Flink;
- - while (!IsListEmpty(&openlist.head)) {
- - cur = (nfs41_fcb_list_entry *)CONTAINING_RECORD(pEntry,
- - nfs41_fcb_list_entry, next);
- - if (cur->nfs41_fobx == nfs41_fobx) {
- -#ifdef DEBUG_CLOSE
- - DbgP("nfs41_invalidate_fobx_entry: Found match for nfs41_fobx=0x%p\n",
- - nfs41_fobx);
- -#endif
- - cur->nfs41_fobx = NULL;
- - break;
- - }
- - if (pEntry->Flink == &openlist.head) {
- -#ifdef DEBUG_CLOSE
- - DbgP("nfs41_invalidate_fobx_entry: reached EOL looking "
- - "for nfs41_fobx=0x%p\n", nfs41_fobx);
- -#endif
- - break;
- - }
- - pEntry = pEntry->Flink;
- - }
- - ExReleaseFastMutexUnsafe(&openlist.lock);
- -}
- -
- NTSTATUS nfs41_Flush(
- IN OUT PRX_CONTEXT RxContext)
- {
- @@ -929,22 +895,6 @@ NTSTATUS nfs41_DeallocateForFcb(
- return STATUS_SUCCESS;
- }
- -NTSTATUS nfs41_DeallocateForFobx(
- - IN OUT PMRX_FOBX pFobx)
- -{
- - __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
- -
- - nfs41_invalidate_fobx_entry(pFobx);
- - nfs41_remove_offloadcontext_for_fobx(pFobx);
- -
- - if (nfs41_fobx->sec_ctx.ClientToken) {
- - SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
- - nfs41_fobx->sec_ctx.ClientToken = NULL;
- - }
- -
- - return STATUS_SUCCESS;
- -}
- -
- VOID nfs41_update_fcb_list(
- PMRX_FCB fcb,
- ULONGLONG ChangeTime)
- @@ -1164,42 +1114,6 @@ NTSTATUS nfs41_Unimplemented(
- return STATUS_NOT_IMPLEMENTED;
- }
- -NTSTATUS nfs41_AreFilesAliased(
- - PFCB a,
- - PFCB b)
- -{
- - __notnull PNFS41_FCB nfs41_fcb_a = (PNFS41_FCB)a;
- - __notnull PNFS41_FCB nfs41_fcb_b = (PNFS41_FCB)b;
- -
- - if ((nfs41_fcb_a->fileid == nfs41_fcb_b->fileid) &&
- - (nfs41_fcb_a->fsid_major == nfs41_fcb_b->fsid_major) &&
- - (nfs41_fcb_a->fsid_minor == nfs41_fcb_b->fsid_minor)) {
- -
- - DbgP("nfs41_AreFilesAliased: "
- - "a=0x%p b=0x%p aliases, fileid=0x%llx "
- - "fsid_major=0x%llx fsid_minor=0x%llx\n",
- - (void *)a, (void *)b,
- - (long long)nfs41_fcb_a->fileid,
- - (long long)nfs41_fcb_a->fsid_major,
- - (long long)nfs41_fcb_a->fsid_minor);
- - return STATUS_MORE_PROCESSING_REQUIRED;
- - }
- - else {
- - DbgP("nfs41_AreFilesAliased: "
- - "a=0x%p b=0x%p NOT aliases, "
- - "a=(fileid=0x%llx fsid_major=0x%llx fsid_minor=0x%llx) "
- - "b=(fileid=0x%llx fsid_major=0x%llx fsid_minor=0x%llx)\n",
- - (void *)a, (void *)b,
- - (long long)nfs41_fcb_a->fileid,
- - (long long)nfs41_fcb_a->fsid_major,
- - (long long)nfs41_fcb_a->fsid_minor,
- - (long long)nfs41_fcb_b->fileid,
- - (long long)nfs41_fcb_b->fsid_major,
- - (long long)nfs41_fcb_b->fsid_minor);
- - return STATUS_SUCCESS;
- - }
- -}
- -
- static
- NTSTATUS nfs41_init_ops(void)
- {
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index a3a74c7..8459d3c 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -865,6 +865,11 @@ NTSTATUS marshal_nfs41_close(
- NTSTATUS unmarshal_nfs41_open(
- nfs41_updowncall_entry *cur,
- const unsigned char *restrict *restrict buf);
- +NTSTATUS nfs41_AreFilesAliased(
- + PFCB a,
- + PFCB b);
- +NTSTATUS nfs41_DeallocateForFobx(
- + IN OUT PMRX_FOBX pFobx);
- NTSTATUS nfs41_Create(
- IN OUT PRX_CONTEXT RxContext);
- NTSTATUS nfs41_CollapseOpen(
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index bde50a0..a14684c 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -347,6 +347,92 @@ out:
- return status;
- }
- +NTSTATUS nfs41_AreFilesAliased(
- + PFCB a,
- + PFCB b)
- +{
- + __notnull PNFS41_FCB nfs41_fcb_a = (PNFS41_FCB)a;
- + __notnull PNFS41_FCB nfs41_fcb_b = (PNFS41_FCB)b;
- +
- + if ((nfs41_fcb_a->fileid == nfs41_fcb_b->fileid) &&
- + (nfs41_fcb_a->fsid_major == nfs41_fcb_b->fsid_major) &&
- + (nfs41_fcb_a->fsid_minor == nfs41_fcb_b->fsid_minor)) {
- +
- + DbgP("nfs41_AreFilesAliased: "
- + "a=0x%p b=0x%p aliases, fileid=0x%llx "
- + "fsid_major=0x%llx fsid_minor=0x%llx\n",
- + (void *)a, (void *)b,
- + (long long)nfs41_fcb_a->fileid,
- + (long long)nfs41_fcb_a->fsid_major,
- + (long long)nfs41_fcb_a->fsid_minor);
- + return STATUS_MORE_PROCESSING_REQUIRED;
- + }
- + else {
- + DbgP("nfs41_AreFilesAliased: "
- + "a=0x%p b=0x%p NOT aliases, "
- + "a=(fileid=0x%llx fsid_major=0x%llx fsid_minor=0x%llx) "
- + "b=(fileid=0x%llx fsid_major=0x%llx fsid_minor=0x%llx)\n",
- + (void *)a, (void *)b,
- + (long long)nfs41_fcb_a->fileid,
- + (long long)nfs41_fcb_a->fsid_major,
- + (long long)nfs41_fcb_a->fsid_minor,
- + (long long)nfs41_fcb_b->fileid,
- + (long long)nfs41_fcb_b->fsid_major,
- + (long long)nfs41_fcb_b->fsid_minor);
- + return STATUS_SUCCESS;
- + }
- +}
- +
- +static
- +VOID nfs41_invalidate_fobx_entry(
- + IN OUT PMRX_FOBX pFobx)
- +{
- + PLIST_ENTRY pEntry;
- + nfs41_fcb_list_entry *cur;
- + __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
- +
- + ExAcquireFastMutexUnsafe(&openlist.lock);
- +
- + pEntry = openlist.head.Flink;
- + while (!IsListEmpty(&openlist.head)) {
- + cur = (nfs41_fcb_list_entry *)CONTAINING_RECORD(pEntry,
- + nfs41_fcb_list_entry, next);
- + if (cur->nfs41_fobx == nfs41_fobx) {
- +#ifdef DEBUG_CLOSE
- + DbgP("nfs41_invalidate_fobx_entry: Found match for nfs41_fobx=0x%p\n",
- + nfs41_fobx);
- +#endif
- + cur->nfs41_fobx = NULL;
- + break;
- + }
- + if (pEntry->Flink == &openlist.head) {
- +#ifdef DEBUG_CLOSE
- + DbgP("nfs41_invalidate_fobx_entry: reached EOL looking "
- + "for nfs41_fobx=0x%p\n", nfs41_fobx);
- +#endif
- + break;
- + }
- + pEntry = pEntry->Flink;
- + }
- + ExReleaseFastMutexUnsafe(&openlist.lock);
- +}
- +
- +NTSTATUS nfs41_DeallocateForFobx(
- + IN OUT PMRX_FOBX pFobx)
- +{
- + __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
- +
- + nfs41_invalidate_fobx_entry(pFobx);
- + nfs41_remove_offloadcontext_for_fobx(pFobx);
- +
- + if (nfs41_fobx->sec_ctx.ClientToken) {
- + SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
- + nfs41_fobx->sec_ctx.ClientToken = NULL;
- + }
- +
- + return STATUS_SUCCESS;
- +}
- +
- static BOOLEAN isDataAccess(
- ACCESS_MASK mask)
- {
- --
- 2.51.0
- From c3432735bdb1ef54121e2256567d34c62d4b9cb0 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 1 Dec 2025 11:28:10 +0100
- Subject: [PATCH 26/28] sys: Implement |MRxCleanupFobx()| dummy function
- Implement |MRxCleanupFobx()| dummy function, document that...
- 1. |MRxCleanupFobx()| is usually called before |MRxCloseSrvOpen()|
- 2. |MRxDeallocateForFobx()| is usually called after |MRxCloseSrvOpen()|
- ... and move |nfs41_DeallocateForFobx()| after |nfs41_CloseSrvOpen()|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_driver.c | 4 ++++
- sys/nfs41sys_driver.h | 3 +++
- sys/nfs41sys_openclose.c | 52 +++++++++++++++++++++++++++-------------
- 3 files changed, 43 insertions(+), 16 deletions(-)
- diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
- index 69616c4..e043602 100644
- --- a/sys/nfs41sys_driver.c
- +++ b/sys/nfs41sys_driver.c
- @@ -1210,6 +1210,8 @@ NTSTATUS nfs41_init_ops(void)
- (PMRX_EXTENDFILE_CALLDOWN)nfs41_ExtendForCache;
- nfs41_ops.MRxExtendForNonCache =
- (PMRX_EXTENDFILE_CALLDOWN)nfs41_ExtendForCache;
- + nfs41_ops.MRxCleanupFobx =
- + (PMRX_CALLDOWN)nfs41_CleanupFobx;
- nfs41_ops.MRxCloseSrvOpen =
- (PMRX_CALLDOWN)nfs41_CloseSrvOpen;
- nfs41_ops.MRxFlush =
- @@ -1218,6 +1220,8 @@ NTSTATUS nfs41_init_ops(void)
- (PMRX_DEALLOCATE_FOR_FCB)nfs41_DeallocateForFcb;
- nfs41_ops.MRxDeallocateForFobx =
- (PMRX_DEALLOCATE_FOR_FOBX)nfs41_DeallocateForFobx;
- +
- +
- nfs41_ops.MRxIsLockRealizable =
- (PMRX_IS_LOCK_REALIZABLE)nfs41_IsLockRealizable;
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 8459d3c..389e67f 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -870,6 +870,9 @@ NTSTATUS nfs41_AreFilesAliased(
- PFCB b);
- NTSTATUS nfs41_DeallocateForFobx(
- IN OUT PMRX_FOBX pFobx);
- +NTSTATUS
- +nfs41_CleanupFobx(
- + IN PRX_CONTEXT RxContext);
- NTSTATUS nfs41_Create(
- IN OUT PRX_CONTEXT RxContext);
- NTSTATUS nfs41_CollapseOpen(
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index a14684c..eb4465b 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -417,22 +417,6 @@ VOID nfs41_invalidate_fobx_entry(
- ExReleaseFastMutexUnsafe(&openlist.lock);
- }
- -NTSTATUS nfs41_DeallocateForFobx(
- - IN OUT PMRX_FOBX pFobx)
- -{
- - __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
- -
- - nfs41_invalidate_fobx_entry(pFobx);
- - nfs41_remove_offloadcontext_for_fobx(pFobx);
- -
- - if (nfs41_fobx->sec_ctx.ClientToken) {
- - SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
- - nfs41_fobx->sec_ctx.ClientToken = NULL;
- - }
- -
- - return STATUS_SUCCESS;
- -}
- -
- static BOOLEAN isDataAccess(
- ACCESS_MASK mask)
- {
- @@ -1522,6 +1506,20 @@ NTSTATUS map_close_errors(
- }
- }
- +/* |MRxCleanupFobx()| is usually called before |MRxCloseSrvOpen()| */
- +NTSTATUS
- +nfs41_CleanupFobx(
- + IN PRX_CONTEXT RxContext)
- +{
- +#ifdef DEBUG_CLOSE
- + DbgP("nfs41_CleanupFobx: FileName is '%wZ'\n",
- + &RxContext->CurrentIrpSp->FileObject->FileName);
- +#endif /* DEBUG_CLOSE */
- +
- + return STATUS_SUCCESS;
- +}
- +
- +
- NTSTATUS nfs41_CloseSrvOpen(
- IN OUT PRX_CONTEXT RxContext)
- {
- @@ -1599,3 +1597,25 @@ out:
- #endif
- return status;
- }
- +
- +/* |MRxDeallocateForFobx()| is usually called after |MRxCloseSrvOpen()| */
- +NTSTATUS nfs41_DeallocateForFobx(
- + IN OUT PMRX_FOBX pFobx)
- +{
- + __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
- +
- +#ifdef DEBUG_CLOSE
- + DbgP("nfs41_DeallocateForFobx: FileName is '%wZ'\n",
- + pFobx->pSrvOpen->pAlreadyPrefixedName);
- +#endif /* DEBUG_CLOSE */
- +
- + nfs41_invalidate_fobx_entry(pFobx);
- + nfs41_remove_offloadcontext_for_fobx(pFobx);
- +
- + if (nfs41_fobx->sec_ctx.ClientToken) {
- + SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
- + nfs41_fobx->sec_ctx.ClientToken = NULL;
- + }
- +
- + return STATUS_SUCCESS;
- +}
- --
- 2.51.0
- From b598019c582d8b48b080d526b4415f861f60dce8 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 1 Dec 2025 12:06:36 +0100
- Subject: [PATCH 27/28] sys: |nfs41_AreFilesAliased()| should use
- NFS41GetFcbExtension() to get the FCB extension
- |nfs41_AreFilesAliased()| should use NFS41GetFcbExtension() to get the FCB extension.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_openclose.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index eb4465b..ce3aec2 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -351,8 +351,8 @@ NTSTATUS nfs41_AreFilesAliased(
- PFCB a,
- PFCB b)
- {
- - __notnull PNFS41_FCB nfs41_fcb_a = (PNFS41_FCB)a;
- - __notnull PNFS41_FCB nfs41_fcb_b = (PNFS41_FCB)b;
- + __notnull PNFS41_FCB nfs41_fcb_a = NFS41GetFcbExtension(a);
- + __notnull PNFS41_FCB nfs41_fcb_b = NFS41GetFcbExtension(b);
- if ((nfs41_fcb_a->fileid == nfs41_fcb_b->fileid) &&
- (nfs41_fcb_a->fsid_major == nfs41_fcb_b->fsid_major) &&
- --
- 2.51.0
- From e9641566cc867aefdd0c7143b69909aff0b7b2f5 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 1 Dec 2025 13:00:25 +0100
- Subject: [PATCH 28/28] sys: |offloadcontext_entry| should use a
- |PMRX_SRV_OPEN| instead of a |PMRX_FOBX|
- |offloadcontext_entry| (used by |FSCTL_OFFLOAD_READ|+|FSCTL_OFFLOAD_WRITE|)
- should use a |PMRX_SRV_OPEN| instead of a |PMRX_FOBX|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_driver.h | 4 ++--
- sys/nfs41sys_fsctl.c | 35 ++++++++++++-----------------------
- sys/nfs41sys_openclose.c | 5 ++++-
- 3 files changed, 18 insertions(+), 26 deletions(-)
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 389e67f..d6bd5ca 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -760,8 +760,8 @@ NTSTATUS marshal_nfs41_duplicatedata(
- NTSTATUS unmarshal_nfs41_duplicatedata(
- nfs41_updowncall_entry *cur,
- const unsigned char *restrict *restrict buf);
- -void nfs41_remove_offloadcontext_for_fobx(
- - IN PMRX_FOBX pFobx);
- +void nfs41_remove_offloadcontext_for_srvopen(
- + IN PMRX_SRV_OPEN pSrvopen);
- /* nfs41sys_ioctl.c */
- NTSTATUS nfs41_IoCtl(
- diff --git a/sys/nfs41sys_fsctl.c b/sys/nfs41sys_fsctl.c
- index f31b976..25c1290 100644
- --- a/sys/nfs41sys_fsctl.c
- +++ b/sys/nfs41sys_fsctl.c
- @@ -755,7 +755,6 @@ NTSTATUS nfs41_DuplicateData(
- PFOBX srcfox = srcfo->FsContext2;
- PNFS41_FCB nfs41_src_fcb = NFS41GetFcbExtension(srcfcb);
- PNFS41_SRV_OPEN src_nfs41_srvopen = NFS41GetSrvOpenExtension(srcfox->SrvOpen);
- - PNFS41_FOBX nfs41_src_fobx = NFS41GetFobxExtension(srcfox);
- if (!nfs41_src_fcb) {
- DbgP("nfs41_DuplicateData: No nfs41_src_fcb\n");
- @@ -763,12 +762,6 @@ NTSTATUS nfs41_DuplicateData(
- goto out;
- }
- - if (!nfs41_src_fobx) {
- - DbgP("nfs41_DuplicateData: No nfs41_src_fobx\n");
- - status = STATUS_INVALID_PARAMETER;
- - goto out;
- - }
- -
- if (nfs41_src_fcb->StandardInfo.Directory) {
- DbgP("nfs41_DuplicateData: src is a dir\n");
- status = STATUS_FILE_IS_A_DIRECTORY;
- @@ -953,14 +946,14 @@ typedef struct _offloadcontext_entry
- */
- ERESOURCE resource;
- STORAGE_OFFLOAD_TOKEN token;
- - PMRX_FOBX src_fobx;
- + PMRX_SRV_OPEN src_srvopen;
- ULONGLONG src_fileoffset;
- ULONGLONG src_length;
- } offloadcontext_entry;
- -void nfs41_remove_offloadcontext_for_fobx(
- - IN PMRX_FOBX pFobx)
- +void nfs41_remove_offloadcontext_for_srvopen(
- + IN PMRX_SRV_OPEN pSrvopen)
- {
- PLIST_ENTRY pEntry;
- offloadcontext_entry *cur, *found = NULL;
- @@ -971,7 +964,7 @@ void nfs41_remove_offloadcontext_for_fobx(
- while (!IsListEmpty(&offloadcontextlist.head)) {
- cur = (offloadcontext_entry *)CONTAINING_RECORD(pEntry,
- offloadcontext_entry, next);
- - if (cur->src_fobx == pFobx) {
- + if (cur->src_srvopen == pSrvopen) {
- found = cur;
- break;
- }
- @@ -982,9 +975,9 @@ void nfs41_remove_offloadcontext_for_fobx(
- }
- if (found) {
- - DbgP("nfs41_remove_offloadcontext(pFobx=0x%p): "
- + DbgP("nfs41_remove_offloadcontext_for_srvopen(pSrvopen=0x%p): "
- "removing found=0x%p\n",
- - pFobx,
- + pSrvopen,
- found);
- /* Wait for any shared access in |nfs41_OffloadWrite()| to finish */
- @@ -998,8 +991,9 @@ void nfs41_remove_offloadcontext_for_fobx(
- }
- else {
- #ifdef DEBUG_FSCTL_OFFLOAD_READWRITE
- - DbgP("nfs41_remove_offloadcontext(pFobx=0x%p): Nothing found.\n",
- - pFobx);
- + DbgP("nfs41_remove_offloadcontext_for_srvopen(pSrvopen=0x%p): "
- + "Nothing found.\n",
- + pSrvopen);
- #endif /* DEBUG_FSCTL_OFFLOAD_READWRITE */
- }
- @@ -1126,7 +1120,7 @@ NTSTATUS nfs41_OffloadRead(
- *((USHORT *)(&oce->token.TokenIdLength[0])) =
- STORAGE_OFFLOAD_TOKEN_ID_LENGTH;
- *((void **)(&oce->token.Token[0])) = oce;
- - oce->src_fobx = RxContext->pFobx;
- + oce->src_srvopen = RxContext->pRelevantSrvOpen;
- oce->src_fileoffset = ori->FileOffset;
- oce->src_length = ori->CopyLength;
- @@ -1294,13 +1288,8 @@ NTSTATUS nfs41_OffloadWrite(
- goto out;
- }
- - PNFS41_FOBX nfs41_src_fobx = NFS41GetFobxExtension(src_oce->src_fobx);
- - if (!nfs41_src_fobx) {
- - DbgP("nfs41_OffloadWrite: No nfs41_src_fobx\n");
- - status = STATUS_INVALID_PARAMETER;
- - goto out;
- - }
- - PNFS41_SRV_OPEN src_nfs41_srvopen = NFS41GetSrvOpenExtension(((PFOBX)src_oce->src_fobx)->SrvOpen);
- + PNFS41_SRV_OPEN src_nfs41_srvopen =
- + NFS41GetSrvOpenExtension(src_oce->src_srvopen);
- /*
- * Disable caching because NFSv4.2 COPY is basically a
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index ce3aec2..5d4c16c 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -1578,6 +1578,10 @@ NTSTATUS nfs41_CloseSrvOpen(
- /* map windows ERRORs to NTSTATUS */
- status = map_close_errors(entry->status);
- +
- + if (NT_SUCCESS(status)) {
- + nfs41_remove_offloadcontext_for_srvopen(SrvOpen);
- + }
- out:
- if (entry) {
- nfs41_UpcallDestroy(entry);
- @@ -1610,7 +1614,6 @@ NTSTATUS nfs41_DeallocateForFobx(
- #endif /* DEBUG_CLOSE */
- nfs41_invalidate_fobx_entry(pFobx);
- - nfs41_remove_offloadcontext_for_fobx(pFobx);
- if (nfs41_fobx->sec_ctx.ClientToken) {
- SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
- --
- 2.51.0
msnfs41client: 28 patches for Extended Create Parameter support, ACL fixes, SRV_OPEN collapsing support+misc, 2025-12-01
Posted by Anonymous on Mon 1st Dec 2025 12:16
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