- diff --git a/daemon/from_kernel.h b/daemon/from_kernel.h
- index 221ee3b..9fd97ac 100644
- --- a/daemon/from_kernel.h
- +++ b/daemon/from_kernel.h
- @@ -109,9 +109,36 @@ typedef enum _FILE_INFORMATION_CLASS {
- FileNormalizedNameInformation, // 48
- FileNetworkPhysicalNameInformation, // 49
- FileIdGlobalTxDirectoryInformation, // 50
- + FileIsRemoteDeviceInformation, // 51
- + FileUnusedInformation, // 52
- + FileNumaNodeInformation, // 53
- + FileStandardLinkInformation, // 54
- + FileRemoteProtocolInformation, // 55
- + FileRenameInformationBypassAccessCheck, // 56
- + FileLinkInformationBypassAccessCheck, // 57
- + FileVolumeNameInformation, // 58
- + FileIdInformation, // 59
- + FileIdExtdDirectoryInformation, // 60
- + FileReplaceCompletionInformation, // 61
- + FileHardLinkFullIdInformation, // 62
- + FileIdExtdBothDirectoryInformation, // 63
- + FileDispositionInformationEx, // 64
- + FileRenameInformationEx, // 65
- + FileRenameInformationExBypassAccessCheck,// 66
- + FileDesiredStorageClassInformation, // 67
- + FileStatInformation, // 68
- + FileMemoryPartitionInformation, // 69
- + FileStatLxInformation, // 70
- + FileCaseSensitiveInformation, // 71
- + FileLinkInformationEx, // 72
- + FileLinkInformationExBypassAccessCheck, // 73
- + FileStorageReserveIdInformation, // 74
- + FileCaseSensitiveInformationForceAccessCheck, // 75
- FileMaximumInformation
- } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
- +#define FILE_RENAME_REPLACE_IF_EXISTS (0x00000001)
- +#define FILE_RENAME_POSIX_SEMANTICS (0x00000002)
- /* kernel structures for QueryDirectory results */
- typedef struct _FILE_NAMES_INFORMATION {
- diff --git a/daemon/getattr.c b/daemon/getattr.c
- index 7c5f241..7621dba 100644
- --- a/daemon/getattr.c
- +++ b/daemon/getattr.c
- @@ -59,8 +59,19 @@ int nfs41_cached_getattr(
- static int parse_getattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
- {
- int status;
- +#if 1
- + EASSERT(length > 4);
- + if (length <= 4) {
- + status = ERROR_INVALID_PARAMETER;
- + goto out;
- + }
- + EASSERT(upcall->state_ref != NULL);
- + if (upcall->state_ref == NULL) {
- + status = ERROR_INVALID_PARAMETER;
- + goto out;
- + }
- +#endif
- getattr_upcall_args *args = &upcall->args.getattr;
- -
- status = safe_read(&buffer, &length, &args->query_class, sizeof(args->query_class));
- if (status) goto out;
- status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
- @@ -80,6 +91,21 @@ static int handle_getattr(void *daemon_context, nfs41_upcall *upcall)
- nfs41_open_state *state = upcall->state_ref;
- nfs41_file_info info = { 0 };
- +#if 1
- + if (((char *)state->session) == ((char *)0xdddddddddddddddd)) {
- + eprintf("handle_getattr: Invalid session pointer 0xdddddddddddddddd\n");
- + status = ERROR_INVALID_PARAMETER;
- + goto out;
- + }
- +
- + EASSERT(state->file.fh.superblock != NULL);
- + if (state->file.fh.superblock == NULL) {
- + /* gisburn: fixme: maybe this should be |ERROR_INTERNAL_ERROR| ? */
- + status = ERROR_INVALID_PARAMETER;
- + goto out;
- + }
- +#endif
- +
- status = nfs41_cached_getattr(state->session, &state->file, &info);
- if (status) {
- eprintf("nfs41_cached_getattr() failed with %d\n", status);
- diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c
- index bcca070..f2a4f22 100644
- --- a/daemon/nfs41_ops.c
- +++ b/daemon/nfs41_ops.c
- @@ -400,6 +400,9 @@ int nfs41_open(
- bool_t already_delegated = delegation->type == OPEN_DELEGATE_READ
- || delegation->type == OPEN_DELEGATE_WRITE;
- + EASSERT(parent);
- + EASSERT(parent->fh.superblock);
- +
- /* depending on the claim type, OPEN expects CURRENT_FH set
- * to either the parent directory, or to the file itself */
- switch (claim->claim) {
- diff --git a/daemon/nfs41_superblock.c b/daemon/nfs41_superblock.c
- index b2f77fd..667e880 100644
- --- a/daemon/nfs41_superblock.c
- +++ b/daemon/nfs41_superblock.c
- @@ -169,6 +169,8 @@ void nfs41_superblock_fs_attributes(
- FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_REMOTE_STORAGE;
- /* NFSv4 protocol uses Unicode by default */
- FsAttrs->FileSystemAttributes |= FILE_UNICODE_ON_DISK;
- + /* NFSv4 protocol supports POSIX semantics for |unlink()|/|rename()| */
- + FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_POSIX_UNLINK_RENAME;
- if (superblock->link_support)
- FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_HARD_LINKS;
- diff --git a/daemon/open.c b/daemon/open.c
- index 4b2a335..487c341 100644
- --- a/daemon/open.c
- +++ b/daemon/open.c
- @@ -99,6 +99,24 @@ static void open_state_free(
- void nfs41_open_state_ref(
- IN nfs41_open_state *state)
- {
- +#if 1
- + /*
- + * gisburn: fixme: sometimes this happens under high parallel
- + * usage with multiple mounts - but why ?
- + * 0:038> kp
- + * Child-SP RetAddr Call Site
- + * 0000006d`431fde10 00007ff7`32f7d905 nfsd!nfs41_open_state_ref(struct __nfs41_open_state * state = 0x00000000`00000000)+0x31
- + * 0000006d`431fdf30 00007ff7`32f4d284 nfsd!upcall_parse(unsigned char * buffer = 0x0000006d`431fe180 "???", unsigned int length = 8, struct __nfs41_upcall * upcall = 0x0000006d`431ff1e0)+0x2e5
- + * 0000006d`431fe0b0 00007ffc`1ca24c7c nfsd!thread_main(void * args = 0x00007ff7`32fb6080)+0x144
- + * 0000006d`431ffe00 00007ffc`4d4b7344 ucrtbased!thread_start<unsigned int (void * parameter = 0x0000025d`a9c6def0)+0x9c
- + * 0000006d`431ffe60 00007ffc`4efc26b1 KERNEL32!BaseThreadInitThunk+0x14
- + * 0000006d`431ffe90 00000000`00000000 ntdll!RtlUserThreadStart+0x21
- + */
- + EASSERT(state != NULL);
- + if (state == NULL)
- + return;
- +#endif
- +
- const LONG count = InterlockedIncrement(&state->ref_count);
- dprintf(2, "nfs41_open_state_ref(%s) count %d\n", state->path.path, count);
- diff --git a/daemon/setattr.c b/daemon/setattr.c
- index 369dd6f..5f285ab 100644
- --- a/daemon/setattr.c
- +++ b/daemon/setattr.c
- @@ -52,13 +52,13 @@ static int parse_setattr(unsigned char *buffer, uint32_t length, nfs41_upcall *u
- dprintf(1, "parsing NFS41_FILE_SET: filename='%s' info_class=%d "
- "buf_len=%d\n", args->path, args->set_class, args->buf_len);
- out:
- - return status;
- -}
- -
- -static int handle_nfs41_setattr(void *daemon_context, setattr_upcall_args *args)
- -{
- - PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf;
- - nfs41_open_state *state = args->state;
- + return status;
- +}
- +
- +static int handle_nfs41_setattr(void *daemon_context, setattr_upcall_args *args)
- +{
- + PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf;
- + nfs41_open_state *state = args->state;
- nfs41_superblock *superblock = state->file.fh.superblock;
- stateid_arg stateid;
- nfs41_file_info info = { 0 }, old_info = { 0 };
- @@ -146,13 +146,13 @@ static int handle_nfs41_setattr(void *daemon_context, setattr_upcall_args *args)
- }
- args->ctime = info.change;
- out:
- - return status;
- -}
- -
- -static int handle_nfs41_remove(void *daemon_context, setattr_upcall_args *args)
- -{
- - nfs41_open_state *state = args->state;
- - int status;
- + return status;
- +}
- +
- +static int handle_nfs41_remove(void *daemon_context, setattr_upcall_args *args)
- +{
- + nfs41_open_state *state = args->state;
- + int status;
- /* break any delegations and truncate before REMOVE */
- nfs41_delegation_return(state->session, &state->file,
- @@ -205,13 +205,13 @@ static int is_dst_name_opened(nfs41_abs_path *dst_path, nfs41_session *dst_sessi
- else
- status = FALSE;
- LeaveCriticalSection(&client->state.lock);
- -
- - return status;
- -}
- -static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
- -{
- - nfs41_open_state *state = args->state;
- - nfs41_session *dst_session;
- +
- + return status;
- +}
- +static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
- +{
- + nfs41_open_state *state = args->state;
- + nfs41_session *dst_session;
- PFILE_RENAME_INFO rename = (PFILE_RENAME_INFO)args->buf;
- nfs41_abs_path dst_path = { 0 };
- nfs41_path_fh dst_dir, dst;
- @@ -291,10 +291,25 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
- last_component(dst_path.path, dst_name.name, &dst_dir.name);
- if (status == NO_ERROR) {
- - if (!rename->ReplaceIfExists) {
- - status = ERROR_FILE_EXISTS;
- - goto out;
- + if (args->set_class == FileRenameInformationEx) {
- + dprintf(0, "FileRenameInformationEx(rename->Flags=%x, POSIX=%d)\n",
- + (int)rename->Flags,
- + (int)(rename->Flags & FILE_RENAME_POSIX_SEMANTICS)?1:0);
- + if (!rename->Flags & FILE_RENAME_REPLACE_IF_EXISTS) {
- + status = ERROR_FILE_EXISTS;
- + goto out;
- + }
- + }
- + else if (args->set_class == FileRenameInformation) {
- + if (!rename->ReplaceIfExists) {
- + status = ERROR_FILE_EXISTS;
- + goto out;
- + }
- }
- + else {
- + EASSERT(1);
- + }
- +
- /* break any delegations and truncate the destination file */
- nfs41_delegation_return(dst_session, &dst,
- OPEN_DELEGATE_WRITE, TRUE);
- @@ -338,13 +353,13 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
- open_state_rename(state, &dst_path);
- }
- out:
- - return status;
- -}
- -
- -static int handle_nfs41_set_size(void *daemon_context, setattr_upcall_args *args)
- -{
- - nfs41_file_info info = { 0 };
- - stateid_arg stateid;
- + return status;
- +}
- +
- +static int handle_nfs41_set_size(void *daemon_context, setattr_upcall_args *args)
- +{
- + nfs41_file_info info = { 0 };
- + stateid_arg stateid;
- /* note: this is called with either FILE_END_OF_FILE_INFO or
- * FILE_ALLOCATION_INFO, both of which contain a single LARGE_INTEGER */
- PLARGE_INTEGER size = (PLARGE_INTEGER)args->buf;
- @@ -375,13 +390,13 @@ static int handle_nfs41_set_size(void *daemon_context, setattr_upcall_args *args
- ReleaseSRWLockExclusive(&state->lock);
- args->ctime = info.change;
- out:
- - return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
- -}
- -
- -static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
- -{
- - nfs41_open_state *state = args->state;
- - PFILE_LINK_INFORMATION link = (PFILE_LINK_INFORMATION)args->buf;
- + return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
- +}
- +
- +static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
- +{
- + nfs41_open_state *state = args->state;
- + PFILE_LINK_INFORMATION link = (PFILE_LINK_INFORMATION)args->buf;
- nfs41_session *dst_session;
- nfs41_abs_path dst_path = { 0 };
- nfs41_path_fh dst_dir, dst;
- @@ -477,36 +492,37 @@ static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
- }
- args->ctime = info.change;
- out:
- - return status;
- -}
- -
- -static int handle_setattr(void *daemon_context, nfs41_upcall *upcall)
- -{
- - setattr_upcall_args *args = &upcall->args.setattr;
- - int status;
- -
- - switch (args->set_class) {
- - case FileBasicInformation:
- - status = handle_nfs41_setattr(daemon_context, args);
- - break;
- - case FileDispositionInformation:
- - status = handle_nfs41_remove(daemon_context, args);
- - break;
- - case FileRenameInformation:
- - status = handle_nfs41_rename(daemon_context, args);
- - break;
- - case FileAllocationInformation:
- - case FileEndOfFileInformation:
- - status = handle_nfs41_set_size(daemon_context, args);
- - break;
- - case FileLinkInformation:
- - status = handle_nfs41_link(daemon_context, args);
- - break;
- - default:
- - eprintf("handle_setattr: unknown set_file information class %d\n",
- - args->set_class);
- - status = ERROR_NOT_SUPPORTED;
- - break;
- + return status;
- +}
- +
- +static int handle_setattr(void *daemon_context, nfs41_upcall *upcall)
- +{
- + setattr_upcall_args *args = &upcall->args.setattr;
- + int status;
- +
- + switch (args->set_class) {
- + case FileBasicInformation:
- + status = handle_nfs41_setattr(daemon_context, args);
- + break;
- + case FileDispositionInformation:
- + status = handle_nfs41_remove(daemon_context, args);
- + break;
- + case FileRenameInformation:
- + case FileRenameInformationEx:
- + status = handle_nfs41_rename(daemon_context, args);
- + break;
- + case FileAllocationInformation:
- + case FileEndOfFileInformation:
- + status = handle_nfs41_set_size(daemon_context, args);
- + break;
- + case FileLinkInformation:
- + status = handle_nfs41_link(daemon_context, args);
- + break;
- + default:
- + eprintf("handle_setattr: unknown set_file information class %d\n",
- + args->set_class);
- + status = ERROR_NOT_SUPPORTED;
- + break;
- }
- return status;
- diff --git a/daemon/upcall.c b/daemon/upcall.c
- index bd13c61..7778429 100644
- --- a/daemon/upcall.c
- +++ b/daemon/upcall.c
- @@ -121,6 +121,7 @@ int upcall_parse(
- /* parse the operation's arguments */
- op = g_upcall_op_table[upcall->opcode];
- if (op && op->parse) {
- + EASSERT(length > 0);
- status = op->parse(buffer, length, upcall);
- if (status) {
- eprintf("parsing of upcall '%s' failed with %d.\n",
- diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
- index 8b259bb..6d3429f 100644
- --- a/dll/nfs41_np.c
- +++ b/dll/nfs41_np.c
- @@ -28,6 +28,8 @@
- #include "nfs41_np.h"
- #include "options.h"
- +#define DBG 1
- +
- #ifdef DBG
- #define DbgP(_x_) NFS41DbgPrint _x_
- #else
- diff --git a/sys/nfs41_build_features.h b/sys/nfs41_build_features.h
- index 93ee7a9..d43334a 100644
- --- a/sys/nfs41_build_features.h
- +++ b/sys/nfs41_build_features.h
- @@ -32,19 +32,19 @@
- /*
- * NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES - return local uid/gid values
- */
- -// #define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES 1
- +#define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES 1
- /*
- * NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID - give NFS
- * files which do not map to a local account a SID in the
- * Unix_User+x/Unix_Group+x range
- */
- -// #define NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID 1
- +#define NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID 1
- /*
- * NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN - use Cygwin /usr/bin/getent
- * as "name service"
- */
- -// #define NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN 1
- +#define NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN 1
- #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
- diff --git a/sys/nfs41_debug.c b/sys/nfs41_debug.c
- index d52d580..7a51f9f 100644
- --- a/sys/nfs41_debug.c
- +++ b/sys/nfs41_debug.c
- @@ -539,6 +539,8 @@ unsigned char * print_file_information_class(int InfoClass)
- return (unsigned char *)"FileLinkInformation";
- case FileRenameInformation:
- return (unsigned char *)"FileRenameInformation";
- + case FileRenameInformationEx:
- + return (unsigned char *)"FileRenameInformationEx";
- case FileValidDataLengthInformation:
- return (unsigned char *)"FileValidDataLengthInformation";
- default:
- diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
- index dcec443..da85dab 100644
- --- a/sys/nfs41_driver.c
- +++ b/sys/nfs41_driver.c
- @@ -5604,6 +5604,7 @@ NTSTATUS check_nfs41_setattr_args(
- switch (InfoClass) {
- case FileRenameInformation:
- + case FileRenameInformationEx:
- {
- PFILE_RENAME_INFORMATION rinfo =
- (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
- @@ -5704,11 +5705,11 @@ NTSTATUS nfs41_SetFileInformation(
- break;
- nfs41_fcb->StandardInfo.DeletePending = TRUE;
- if (RxContext->pFcb->OpenCount > 1) {
- - rinfo.ReplaceIfExists = 0;
- + rinfo.Flags = 0;
- rinfo.RootDirectory = INVALID_HANDLE_VALUE;
- rinfo.FileNameLength = 0;
- rinfo.FileName[0] = L'\0';
- - InfoClass = FileRenameInformation;
- + InfoClass = FileRenameInformationEx;
- nfs41_fcb->Renamed = TRUE;
- break;
- }
- @@ -5733,6 +5734,7 @@ NTSTATUS nfs41_SetFileInformation(
- break;
- }
- case FileRenameInformation:
- + case FileRenameInformationEx:
- {
- /* noop if filename and destination are the same */
- PFILE_RENAME_INFORMATION prinfo =
- @@ -5756,8 +5758,9 @@ NTSTATUS nfs41_SetFileInformation(
- /* original irp has infoclass for remove but we need to rename instead,
- * thus we changed the local variable infoclass */
- - if (RxContext->Info.FileInformationClass == FileDispositionInformation &&
- - InfoClass == FileRenameInformation) {
- + if ((RxContext->Info.FileInformationClass == FileDispositionInformation) &&
- + ((InfoClass == FileRenameInformation) ||
- + (InfoClass == FileRenameInformationEx))) {
- entry->buf = &rinfo;
- entry->buf_len = sizeof(rinfo);
- } else {
backup_FILE_SUPPORTS_POSIX_UNLINK_RENAME_20231202_001.diff prototype
Posted by Anonymous on Sat 2nd Dec 2023 19:13
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.