- diff --git a/cygwin/devel/msnfs41client.bash b/cygwin/devel/msnfs41client.bash
- index 7a21fbc..2968729 100755
- --- a/cygwin/devel/msnfs41client.bash
- +++ b/cygwin/devel/msnfs41client.bash
- @@ -691,7 +691,7 @@ function nfsclient_rundeamon
- "${nfsd_args[@]}"
- )
- "${nfsd_args[@]}"
- - elif false ; then
- + elif true ; then
- export _NT_ALT_SYMBOL_PATH="$(cygpath -w "$PWD");srv*https://msdl.microsoft.com/download/symbols"
- #
- # Useful cdb cmds:
- @@ -831,7 +831,7 @@ function nfsclient_system_rundeamon
- )
- "${nfsd_args[@]}"
- - elif false ; then
- + elif true ; then
- export _NT_ALT_SYMBOL_PATH="$(cygpath -w "${sbinpath}");srv*https://msdl.microsoft.com/download/symbols"
- # - heap tests (eats lots of memory):
- # '-c' '!gflag +full;g' for heap tests
- diff --git a/daemon/setattr.c b/daemon/setattr.c
- index 5efcc1a..aa1af37 100644
- --- a/daemon/setattr.c
- +++ b/daemon/setattr.c
- @@ -61,14 +61,23 @@ static int parse_setattr(
- status = get_safe_read_bufferpos(&buffer, &length,
- args->buf_len, (const void **)&args->buf);
- if (status) goto out;
- + if (args->set_class == FileRenameInformation) {
- + status = safe_read(&buffer, &length,
- + &args->rootdir_state, sizeof(args->rootdir_state));
- + if (status) goto out;
- + }
- + else {
- + args->rootdir_state = NULL;
- + }
- args->root = upcall->root_ref;
- args->state = upcall->state_ref;
- - DPRINTF(1, ("parsing '%s': filename='%s' info_class=%d "
- - "buf_len=%d\n",
- - opcode2string(upcall->opcode),
- - args->path, args->set_class, args->buf_len));
- + DPRINTF(1,
- + ("parsing '%s': "
- + "filename='%s' info_class=%d rootdir_state=0x%p buf_len=%d\n",
- + opcode2string(upcall->opcode), args->path,
- + args->set_class, (void *)args->rootdir_state, args->buf_len));
- out:
- return status;
- }
- @@ -634,63 +643,109 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
- goto out;
- }
- else if ((dst_path.len > 0) && (dst_path.path[0] != '\\')) {
- - nfs41_abs_path *src_path = &state->path;
- -
- - AcquireSRWLockShared(&src_path->lock);
- -
- /*
- - * FIXME: We do not support relative paths like "abc\def\x.txt" yet,
- - * this would require support for
- - * |FILE_RENAME_INFORMATION.RootDirectory|
- + * Relative paths like "abc\def\x.txt" are not allowed here
- */
- if (memchr(dst_path.path, '\\', dst_path.len)) {
- - eprintf("handle_nfs41_rename(src_path->path='%s'): "
- - "relative path in dst_path.name='%s' not supported\n",
- - src_path->path, dst_path.path);
- + eprintf("handle_nfs41_rename(state->path.path='%s'): "
- + "relative path in dst_path.name='%s' not allowed\n",
- + state->path.path, dst_path.path);
- status = ERROR_INVALID_PARAMETER;
- - ReleaseSRWLockShared(&src_path->lock);
- goto out;
- }
- if (dst_path.len > NFS41_MAX_COMPONENT_LEN) {
- - eprintf("handle_nfs41_rename(src_path->path='%s'): "
- - "relative path dst_path.name='%s' length > NFS41_MAX_COMPONENT_LEN\n",
- - src_path->path, dst_path.path);
- + eprintf("handle_nfs41_rename(state->path.path='%s'): "
- + "relative path dst_path.name='%s' "
- + "len > NFS41_MAX_COMPONENT_LEN\n",
- + state->path.path, dst_path.path);
- status = ERROR_INVALID_PARAMETER;
- - ReleaseSRWLockShared(&src_path->lock);
- goto out;
- }
- - char tmprelname[NFS41_MAX_COMPONENT_LEN+1];
- + if (args->rootdir_state != NULL) {
- + nfs41_abs_path *rootdir_path = &args->rootdir_state->path;
- - /*
- - * Save relative destination filename because we first copy the src
- - * path to dst_path and then append our saved filename
- - */
- - (void)memcpy(tmprelname, dst_path.path, dst_path.len);
- - size_t tmprelname_len = dst_path.len;
- + AcquireSRWLockShared(&rootdir_path->lock);
- - DPRINTF(1,
- - ("handle_nfs41_rename: "
- - "relative destfile, "
- - "src_path->path='%s' dst_path.name='%s'\n",
- - src_path->path, dst_path.path));
- + char tmprelname[NFS41_MAX_COMPONENT_LEN+1];
- - abs_path_copy(&dst_path, &state->path);
- - ReleaseSRWLockShared(&src_path->lock);
- + /*
- + * Save relative destination filename because we first copy the src
- + * path to dst_path and then append our saved filename
- + */
- + (void)memcpy(tmprelname, dst_path.path, dst_path.len);
- + size_t tmprelname_len = dst_path.len;
- - fh_copy(&dst_dir.fh, &state->parent.fh);
- + DPRINTF(0,
- + ("handle_nfs41_rename: "
- + "relative destfile, "
- + "rootdir_path->path='%s' dst_path.name='%s'\n",
- + rootdir_path->path, dst_path.path));
- - /*
- - * Take the src path and replace the last path element with the
- - * relative filename
- - */
- - last_component(dst_path.path, dst_path.path + dst_path.len, &dst_name);
- - char *dst_name_name = (char *)dst_name.name;
- - (void)memcpy(dst_name_name, tmprelname, tmprelname_len);
- - dst_name_name[tmprelname_len] = '\0';
- - dst_path.len = (unsigned short)
- - (&dst_name_name[tmprelname_len] - &dst_path.path[0]);
- + abs_path_copy(&dst_path, rootdir_path);
- + ReleaseSRWLockShared(&rootdir_path->lock);
- +
- + fh_copy(&dst_dir.fh, &args->rootdir_state->parent.fh);
- +
- + /*
- + * Append the relative filename to |rootdir_path|
- + */
- + char *append_pos = dst_path.path + dst_path.len;
- + *(append_pos++) = '\\';
- + (void)memcpy(append_pos, tmprelname, tmprelname_len);
- + append_pos[tmprelname_len] = '\0';
- +
- + dst_path.len = (unsigned short)strlen(dst_path.path);
- + DPRINTF(0,
- + ("XXX: new dst_path='%s' len=%d calculated_len=%d\n",
- + dst_path.path,
- + (int)dst_path.len,
- + (int)(rootdir_path->len + 1 + tmprelname_len)));
- + }
- + else {
- + nfs41_abs_path *src_path = &state->path;
- +
- + AcquireSRWLockShared(&src_path->lock);
- +
- + char tmprelname[NFS41_MAX_COMPONENT_LEN+1];
- +
- + /*
- + * Save relative destination filename because we first copy the src
- + * path to dst_path and then append our saved filename
- + */
- + (void)memcpy(tmprelname, dst_path.path, dst_path.len);
- + size_t tmprelname_len = dst_path.len;
- +
- + DPRINTF(0,
- + ("handle_nfs41_rename: "
- + "relative destfile, "
- + "src_path->path='%s' dst_path.name='%s'\n",
- + src_path->path, dst_path.path));
- +
- + abs_path_copy(&dst_path, &state->path);
- + ReleaseSRWLockShared(&src_path->lock);
- +
- + fh_copy(&dst_dir.fh, &state->parent.fh);
- +
- + /*
- + * Take the src path and replace the last path element with the
- + * relative filename
- + */
- + last_component(dst_path.path, dst_path.path + dst_path.len, &dst_name);
- + char *dst_name_name = (char *)dst_name.name;
- + (void)memcpy(dst_name_name, tmprelname, tmprelname_len);
- + dst_name_name[tmprelname_len] = '\0';
- + dst_path.len = (unsigned short)
- + (&dst_name_name[tmprelname_len] - &dst_path.path[0]);
- + }
- + }
- + else {
- + DPRINTF(0,
- + ("handle_nfs41_rename: "
- + "absolute dst path, "
- + "src_name->name='%s' dst_path.name='%s'\n",
- + src_name->name, dst_path.path));
- }
- /* |dst_path| should be non-empty and start with a backslash */
- diff --git a/daemon/upcall.h b/daemon/upcall.h
- index 01a84ed..a38c9b7 100644
- --- a/daemon/upcall.h
- +++ b/daemon/upcall.h
- @@ -136,6 +136,8 @@ typedef struct __setattr_upcall_args {
- const char *path;
- nfs41_root *root;
- nfs41_open_state *state;
- + /* |RootDirectory| for |FILE_RENAME_INFORMATION| */
- + nfs41_open_state *rootdir_state;
- unsigned char *buf;
- uint32_t buf_len;
- int set_class;
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index 3835bca..c260a6d 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -276,6 +276,8 @@ typedef struct _updowncall_entry {
- FILE_INFORMATION_CLASS InfoClass;
- PVOID buf;
- ULONG buf_len;
- + /* |RootDirectory| state for |FILE_RENAME_INFORMATION| */
- + void *rootdir_state;
- } SetFile;
- struct {
- DWORD mode;
- diff --git a/sys/nfs41sys_fileinfo.c b/sys/nfs41sys_fileinfo.c
- index 6de73b5..8d70ab8 100644
- --- a/sys/nfs41sys_fileinfo.c
- +++ b/sys/nfs41sys_fileinfo.c
- @@ -129,6 +129,10 @@ NTSTATUS marshal_nfs41_fileset(
- header_len = *len + length_as_utf8(entry->filename) +
- 2 * sizeof(ULONG) + entry->u.SetFile.buf_len;
- + if (entry->u.SetFile.InfoClass == FileRenameInformation) {
- + header_len += sizeof(void *);
- + }
- +
- if (header_len > buf_len) {
- DbgP("marshal_nfs41_fileset: "
- "upcall buffer too small: header_len(=%ld) > buf_len(=%ld)\n",
- @@ -144,6 +148,10 @@ NTSTATUS marshal_nfs41_fileset(
- tmp += sizeof(ULONG);
- RtlCopyMemory(tmp, entry->u.SetFile.buf, entry->u.SetFile.buf_len);
- tmp += entry->u.SetFile.buf_len;
- + if (entry->u.SetFile.InfoClass == FileRenameInformation) {
- + RtlCopyMemory(tmp, &entry->u.SetFile.rootdir_state, sizeof(void *));
- + tmp += sizeof(void *);
- + }
- *len = (ULONG)(tmp - buf);
- if (*len != header_len) {
- @@ -652,12 +660,6 @@ NTSTATUS check_nfs41_setattr_args(
- status = STATUS_OBJECT_NAME_INVALID;
- goto out;
- }
- - if (rinfo->RootDirectory) {
- - DbgP("check_nfs41_setattr_args: "
- - "rinfo->RootDirectory != NULL not supported\n");
- - status = STATUS_INVALID_PARAMETER;
- - goto out;
- - }
- break;
- }
- case FileLinkInformation:
- @@ -724,6 +726,8 @@ NTSTATUS nfs41_SetFileInformationImpl(
- __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
- NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
- __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
- + PFILE_OBJECT rootdirfo = NULL;
- +
- #ifdef ENABLE_TIMINGS
- LARGE_INTEGER t1, t2;
- t1 = KeQueryPerformanceCounter(NULL);
- @@ -850,6 +854,38 @@ NTSTATUS nfs41_SetFileInformationImpl(
- entry->u.SetFile.buf = RxContext->Info.Buffer;
- entry->u.SetFile.buf_len = RxContext->Info.Length;
- }
- +
- + if (InfoClass == FileRenameInformation) {
- + PFILE_RENAME_INFORMATION prinfo =
- + (PFILE_RENAME_INFORMATION)entry->u.SetFile.buf;
- + HANDLE rootdir_handle = prinfo->RootDirectory;
- +
- + if ((rootdir_handle == NULL) ||
- + (rootdir_handle == INVALID_HANDLE_VALUE)) {
- + entry->u.SetFile.rootdir_state = NULL;
- + }
- + else {
- + status = ObReferenceObjectByHandle(rootdir_handle,
- + 0,
- + *IoFileObjectType,
- + RxContext->CurrentIrp->RequestorMode,
- + (void **)&rootdirfo,
- + NULL);
- + if (!NT_SUCCESS(status)) {
- + DbgP("nfs41_SetFileInformationImpl: "
- + "rootdir ObReferenceObjectByHandle returned 0x%lx\n",
- + status);
- + goto out;
- + }
- +
- + PFOBX rootdirfox = rootdirfo->FsContext2;
- + PNFS41_SRV_OPEN rootdir_nfs41_srvopen =
- + NFS41GetSrvOpenExtension(rootdirfox->SrvOpen);
- + entry->u.SetFile.rootdir_state =
- + rootdir_nfs41_srvopen->nfs41_open_state;
- + }
- + }
- +
- #ifdef ENABLE_TIMINGS
- InterlockedIncrement(&setattr.sops);
- InterlockedAdd64(&setattr.size, entry->u.SetFile.buf_len);
- @@ -875,6 +911,11 @@ out:
- if (entry) {
- nfs41_UpcallDestroy(entry);
- }
- +
- + if (rootdirfo) {
- + ObDereferenceObject(rootdirfo);
- + }
- +
- #ifdef ENABLE_TIMINGS
- t2 = KeQueryPerformanceCounter(NULL);
- InterlockedIncrement(&setattr.tops);
msnfs41client_filerename_with_rootdir20260207.diff
Posted by Anonymous on Sat 7th Feb 2026 12:31
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.
nrubsig.kpaste.net RSS