- From 7ba53b52ad9f78959263b1bc6a7de9cc9ce7f39a Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 24 Mar 2025 13:21:58 +0100
- Subject: [PATCH 1/3] nfs41_build_features.h,sys: Add hack to avoid updating
- FCB attributes we open an already opened FCB
- Add build option (|NFS41_DRIVER_HACK_DISABLE_FCB_ATTR_UPDATE_ON_OPEN|,
- "enabled" by default) for a hack to avoid updating FCB attributes if
- opened for an already opened FCB.
- This is a hack for now, until we can figure out how
- to do this correctly (best guess is not to update FCB
- attributes if the file is opened for writing, because
- the kernel keeps updating the FCB data. The userland
- is not affected by this, they get all information from
- |nfs41_fcb->BasicInfo| and |nfs41_fcb->StandardInfo|).
- We keep this as a build flag for further testing.
- The hack passes cthon04, winfstest, building gcc, bash with gcc/clang
- and building ms-nfs41-client with Visual Studio 2019.
- Without this hack
- $ '/cygdrive/c/Program Files/Git/cmd/git' clone ... # will
- fail with read errors.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- nfs41_build_features.h | 24 ++++++++++++-
- sys/nfs41sys_openclose.c | 76 ++++++++++++++++++++++++++++++----------
- 2 files changed, 81 insertions(+), 19 deletions(-)
- diff --git a/nfs41_build_features.h b/nfs41_build_features.h
- index 0024d58..7f5c261 100644
- --- a/nfs41_build_features.h
- +++ b/nfs41_build_features.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>
- @@ -205,4 +206,25 @@
- */
- #define NFS41_DRIVER_TREAT_UNRESOLVEABLE_SYMLINKS_AS_DIRS 1
- +/*
- + * NFS41_DRIVER_HACK_DISABLE_FCB_ATTR_UPDATE_ON_OPEN -
- + * disable updating of FCB attributes for an already
- + * opened FCB
- + * This is a hack for now, until we can figure out how
- + * to do this correctly (best guess is not to update FCB
- + * attributes if the file is opened for writing, because
- + * the kernel keeps updating the FCB data. The userland
- + * is not affected by this, they get all information from
- + * |nfs41_fcb->BasicInfo| and |nfs41_fcb->StandardInfo|).
- + *
- + * We keep this as a build flag for further testing.
- + *
- + * Without this hack
- + * $ '/cygdrive/c/Program Files/Git/cmd/git' clone ... # will
- + * fail with read errors.
- + *
- + */
- +#define NFS41_DRIVER_HACK_DISABLE_FCB_ATTR_UPDATE_ON_OPEN 1
- +
- +
- #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 54ac9cb..d0cc36f 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -870,24 +870,64 @@ retry_on_link:
- !pVNetRootContext->read_only) || oldDeletePending)
- nfs41_fcb->StandardInfo.DeletePending = TRUE;
- - RxFormInitPacket(InitPacket,
- - &entry->u.Open.binfo.FileAttributes,
- - &entry->u.Open.sinfo.NumberOfLinks,
- - &entry->u.Open.binfo.CreationTime,
- - &entry->u.Open.binfo.LastAccessTime,
- - &entry->u.Open.binfo.LastWriteTime,
- - &entry->u.Open.binfo.ChangeTime,
- - &entry->u.Open.sinfo.AllocationSize,
- - &entry->u.Open.sinfo.EndOfFile,
- - &entry->u.Open.sinfo.EndOfFile);
- -
- - if (entry->u.Open.sinfo.Directory)
- - StorageType = FileTypeDirectory;
- - else
- - StorageType = FileTypeFile;
- -
- - RxFinishFcbInitialization(Fcb, RDBSS_STORAGE_NTC(StorageType),
- - &InitPacket);
- + if (Fcb->OpenCount == 0) {
- + /* Init FCB attributes */
- + RxFormInitPacket(InitPacket,
- + &entry->u.Open.binfo.FileAttributes,
- + &entry->u.Open.sinfo.NumberOfLinks,
- + &entry->u.Open.binfo.CreationTime,
- + &entry->u.Open.binfo.LastAccessTime,
- + &entry->u.Open.binfo.LastWriteTime,
- + &entry->u.Open.binfo.ChangeTime,
- + &entry->u.Open.sinfo.AllocationSize,
- + &entry->u.Open.sinfo.EndOfFile,
- + &entry->u.Open.sinfo.EndOfFile);
- +
- + if (entry->u.Open.sinfo.Directory)
- + StorageType = FileTypeDirectory;
- + else
- + StorageType = FileTypeFile;
- +
- + RxFinishFcbInitialization(Fcb,
- + RDBSS_STORAGE_NTC(StorageType),
- + &InitPacket);
- + }
- + else {
- +#ifndef NFS41_DRIVER_HACK_DISABLE_FCB_ATTR_UPDATE_ON_OPEN
- + /*
- + * NFS41_DRIVER_HACK_DISABLE_FCB_ATTR_UPDATE_ON_OPEN -
- + * disable updating of FCB attributes for an already
- + * opened FCB
- + * This is a hack for now, until we can figure out how
- + * to do this correctly (best guess is not to update FCB
- + * attributes if the file is opened for writing, because
- + * the kernel keeps updating the FCB data. The userland
- + * is not affected by this, they get all information from
- + * |nfs41_fcb->BasicInfo| and |nfs41_fcb->StandardInfo|).
- + *
- + * Without this hack
- + * $ '/cygdrive/c/Program Files/Git/cmd/git' clone ... #
- + * will fail with read errors.
- + *
- + */
- + PFCB pFcb = (PFCB)RxContext->pFcb;
- +
- + /* Update FCB attributes */
- + pFcb->Attributes = entry->u.Open.binfo.FileAttributes;
- + pFcb->NumberOfLinks = entry->u.Open.sinfo.NumberOfLinks;
- + pFcb->CreationTime = entry->u.Open.binfo.CreationTime;
- + pFcb->LastAccessTime = entry->u.Open.binfo.LastAccessTime;
- + pFcb->LastWriteTime = entry->u.Open.binfo.LastWriteTime;
- + pFcb->LastChangeTime = entry->u.Open.binfo.ChangeTime;
- + pFcb->ActualAllocationLength =
- + entry->u.Open.sinfo.AllocationSize.QuadPart;
- + pFcb->Header.AllocationSize =
- + entry->u.Open.sinfo.AllocationSize;
- + pFcb->Header.FileSize = entry->u.Open.sinfo.EndOfFile;
- + pFcb->Header.ValidDataLength =
- + entry->u.Open.sinfo.EndOfFile;
- +#endif /* !NFS41_DRIVER_HACK_DISABLE_FCB_ATTR_UPDATE_ON_OPEN */
- + }
- }
- #ifdef DEBUG_OPEN
- else
- --
- 2.45.1
- From 9e9e7758e0426ea480b4702e5feb9eed58415fb7 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 24 Mar 2025 17:23:52 +0100
- Subject: [PATCH 2/3] sys: |map_lock_errors()| shoud map |ERROR_ACCESS_DENIED|
- |map_lock_errors()| shoud map |ERROR_ACCESS_DENIED| to |STATUS_ACCESS_DENIED|
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41sys_lock.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
- diff --git a/sys/nfs41sys_lock.c b/sys/nfs41sys_lock.c
- index 12e5a45..19ff831 100644
- --- a/sys/nfs41sys_lock.c
- +++ b/sys/nfs41sys_lock.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>
- @@ -188,6 +188,7 @@ NTSTATUS map_lock_errors(
- case ERROR_OUTOFMEMORY: return STATUS_INSUFFICIENT_RESOURCES;
- case ERROR_SHARING_VIOLATION: return STATUS_SHARING_VIOLATION;
- case ERROR_FILE_INVALID: return STATUS_FILE_INVALID;
- + case ERROR_ACCESS_DENIED: return STATUS_ACCESS_DENIED;
- /* if we return ERROR_INVALID_PARAMETER, Windows translates that to
- * success!! */
- case ERROR_INVALID_PARAMETER: return STATUS_LOCK_NOT_GRANTED;
- --
- 2.45.1
- From e7408c2c3645599e4be2154aadbe32b5db6f87ec Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 24 Mar 2025 19:03:48 +0100
- Subject: [PATCH 3/3] nfs41_build_features.h,sys,tests: Add hack for Storage32
- API probing locks outside filesize
- Add a hack for Storage32 API probing locks with offsets outside a file's
- filesize (see
- https://doxygen.reactos.org/d6/d7b/storage32_8h_source.html#l00497).
- The Storage32 API uses locking outside a file's size in the
- offset range of 0x7ffffe00 - 0x7fffffff for it's internal
- machinery. Since NFSv4.1 locking API will return failure for
- locking attempts outside a file's size we have to add a workaround
- here, otherwise applications using the Storage32 API can fail.
- Without this hack
- $ msiexec /i DrMemory-Windows-2.6.20167.msi # will
- fail with read errors.
- Reported-by: Martin Wege <martin.l.wege@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- nfs41_build_features.h | 18 +++++++++++++
- sys/nfs41sys_lock.c | 55 ++++++++++++++++++++++++++++++++++++++++
- tests/manual_testing.txt | 10 ++++++++
- 3 files changed, 83 insertions(+)
- diff --git a/nfs41_build_features.h b/nfs41_build_features.h
- index 7f5c261..b15cbdf 100644
- --- a/nfs41_build_features.h
- +++ b/nfs41_build_features.h
- @@ -227,4 +227,22 @@
- #define NFS41_DRIVER_HACK_DISABLE_FCB_ATTR_UPDATE_ON_OPEN 1
- +/*
- + * |NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING| - handle
- + * rangelock probing for Storage32 API
- + * (see https://doxygen.reactos.org/d6/d7b/storage32_8h_source.html#l00497)
- + *
- + * The Storage32 API uses locking outside a file's size in the
- + * offset range of 0x7ffffe00 - 0x7fffffff for it's internal
- + * machinery. Since NFSv4.1 locking API will return failure for
- + * locking attempts outside a file's size we have to add a workaround
- + * here, otherwise applications using the Storage32 API can fail.
- + *
- + * Without this hack
- + * $ msiexec /i DrMemory-Windows-2.6.20167.msi # will
- + * fail with read errors.
- + *
- + */
- +#define NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING 1
- +
- #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
- diff --git a/sys/nfs41sys_lock.c b/sys/nfs41sys_lock.c
- index 19ff831..e6a2016 100644
- --- a/sys/nfs41sys_lock.c
- +++ b/sys/nfs41sys_lock.c
- @@ -56,6 +56,7 @@
- #include <rx.h>
- #include <windef.h>
- #include <winerror.h>
- +#include <stdbool.h>
- #include <Ntstrsafe.h>
- @@ -233,6 +234,29 @@ static void denied_lock_backoff(
- delay->QuadPart = MAX_LOCK_POLL_WAIT;
- }
- +#ifdef NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING
- +static
- +bool rangelock_hack_skiplock(
- + PLOWIO_CONTEXT LowIoContext,
- + PNFS41_FCB nfs41_fcb)
- +{
- + /*
- + * Hack for |RANGELOCK_*| constants - see
- + * https://doxygen.reactos.org/d6/d7b/storage32_8h_source.html#l00497
- + *
- + * FIXME: No clue why these constants show up here as lock offsets
- + */
- + if (nfs41_fcb->StandardInfo.EndOfFile.QuadPart <= 0x7fffffff) {
- + if ((LowIoContext->ParamsFor.Locks.ByteOffset >= 0x7ffffe00) &&
- + (LowIoContext->ParamsFor.Locks.ByteOffset <= 0x7fffffff)) {
- + return true;
- + }
- + }
- +
- + return false;
- +}
- +#endif /* NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING */
- +
- NTSTATUS nfs41_Lock(
- IN OUT PRX_CONTEXT RxContext)
- {
- @@ -245,6 +269,10 @@ NTSTATUS nfs41_Lock(
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
- +#ifdef NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING
- + __notnull PMRX_FCB Fcb = RxContext->pFcb;
- + __notnull PNFS41_FCB nfs41_fcb = (PNFS41_FCB)Fcb->Context;
- +#endif /* NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING */
- const ULONG flags = LowIoContext->ParamsFor.Locks.Flags;
- LARGE_INTEGER poll_delay = {0};
- #ifdef ENABLE_TIMINGS
- @@ -262,6 +290,15 @@ NTSTATUS nfs41_Lock(
- /* RxReleaseFcbResourceForThreadInMRx(RxContext, RxContext->pFcb,
- LowIoContext->ResourceThreadId); */
- +#ifdef NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING
- + if (rangelock_hack_skiplock(LowIoContext, nfs41_fcb)) {
- + DbgP("nfs41_Lock: RANGELOCK hack 0x%ld\n",
- + (long)LowIoContext->ParamsFor.Locks.ByteOffset);
- + status = STATUS_SUCCESS;
- + goto out;
- + }
- +#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,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- @@ -349,6 +386,10 @@ NTSTATUS nfs41_Unlock(
- NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
- +#ifdef NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING
- + __notnull PMRX_FCB Fcb = RxContext->pFcb;
- + __notnull PNFS41_FCB nfs41_fcb = (PNFS41_FCB)Fcb->Context;
- +#endif /* NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING */
- #ifdef ENABLE_TIMINGS
- LARGE_INTEGER t1, t2;
- t1 = KeQueryPerformanceCounter(NULL);
- @@ -361,6 +402,20 @@ NTSTATUS nfs41_Unlock(
- /* RxReleaseFcbResourceForThreadInMRx(RxContext, RxContext->pFcb,
- LowIoContext->ResourceThreadId); */
- +#ifdef NFS41_DRIVER_HACK_LOCKING_STORAGE32_RANGELOCK_PROBING
- + /*
- + * FIXME: This does NOT handle |LOWIO_OP_UNLOCK_MULTIPLE|
- + * correctly, but the Storage32 API in ReactOS does not
- + * use it
- + */
- + if (rangelock_hack_skiplock(LowIoContext, nfs41_fcb)) {
- + DbgP("nfs41_Unlock: RANGELOCK hack 0x%ld\n",
- + (long)LowIoContext->ParamsFor.Locks.ByteOffset);
- + status = STATUS_SUCCESS;
- + goto out;
- + }
- +#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,
- pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
- diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
- index 4740a5d..12fba86 100644
- --- a/tests/manual_testing.txt
- +++ b/tests/manual_testing.txt
- @@ -691,5 +691,15 @@ $ apt-get install clang gcc gdb nedit emacs vim x11-apps xterm ksh traceroute st
- #
- ksh93 tests/sparsefiles/testsparsefile1.ksh
- +
- +#
- +# MSI installation from network driver
- +#
- +
- +# cd /cygdrive/l/download/
- +# from https://github.com/DynamoRIO/drmemory/releases/tag/cronbuild-2.6.20167
- +wget 'https://github.com/DynamoRIO/drmemory/releases/download/cronbuild-2.6.20167/DrMemory-Windows-2.6.20167.msi'
- +msiexec /i DrMemory-Windows-2.6.20167.msi
- +
- #
- # EOF.
- --
- 2.45.1
msnfs41client: Patch for FCB-no-attr-updates-for-already-opened-FCB hack, Storage32 probe locking hack+misc, 2025-03-24
Posted by Anonymous on Mon 24th Mar 2025 18:20
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.