pastebin - collaborative debugging tool
rovema.kpaste.net RSS


backup_FILE_SUPPORTS_POSIX_UNLINK_RENAME_20231202_001.diff prototype
Posted by Anonymous on Sat 2nd Dec 2023 19:13
raw | new post

  1. diff --git a/daemon/from_kernel.h b/daemon/from_kernel.h
  2. index 221ee3b..9fd97ac 100644
  3. --- a/daemon/from_kernel.h
  4. +++ b/daemon/from_kernel.h
  5. @@ -109,9 +109,36 @@ typedef enum _FILE_INFORMATION_CLASS {
  6.      FileNormalizedNameInformation,           // 48
  7.      FileNetworkPhysicalNameInformation,      // 49
  8.      FileIdGlobalTxDirectoryInformation,      // 50
  9. +    FileIsRemoteDeviceInformation,           // 51
  10. +    FileUnusedInformation,                   // 52
  11. +    FileNumaNodeInformation,                 // 53
  12. +    FileStandardLinkInformation,             // 54
  13. +    FileRemoteProtocolInformation,           // 55
  14. +    FileRenameInformationBypassAccessCheck,  // 56
  15. +    FileLinkInformationBypassAccessCheck,    // 57
  16. +    FileVolumeNameInformation,               // 58
  17. +    FileIdInformation,                       // 59
  18. +    FileIdExtdDirectoryInformation,          // 60
  19. +    FileReplaceCompletionInformation,        // 61
  20. +    FileHardLinkFullIdInformation,           // 62
  21. +    FileIdExtdBothDirectoryInformation,      // 63
  22. +    FileDispositionInformationEx,            // 64
  23. +    FileRenameInformationEx,                 // 65
  24. +    FileRenameInformationExBypassAccessCheck,// 66
  25. +    FileDesiredStorageClassInformation,      // 67
  26. +    FileStatInformation,                     // 68
  27. +    FileMemoryPartitionInformation,          // 69
  28. +    FileStatLxInformation,                   // 70
  29. +    FileCaseSensitiveInformation,            // 71
  30. +    FileLinkInformationEx,                   // 72
  31. +    FileLinkInformationExBypassAccessCheck,  // 73
  32. +    FileStorageReserveIdInformation,         // 74
  33. +    FileCaseSensitiveInformationForceAccessCheck, // 75
  34.      FileMaximumInformation
  35.  } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
  36.  
  37. +#define FILE_RENAME_REPLACE_IF_EXISTS   (0x00000001)
  38. +#define FILE_RENAME_POSIX_SEMANTICS     (0x00000002)
  39.  
  40.  /* kernel structures for QueryDirectory results */
  41.  typedef struct _FILE_NAMES_INFORMATION {
  42. diff --git a/daemon/getattr.c b/daemon/getattr.c
  43. index 7c5f241..7621dba 100644
  44. --- a/daemon/getattr.c
  45. +++ b/daemon/getattr.c
  46. @@ -59,8 +59,19 @@ int nfs41_cached_getattr(
  47.  static int parse_getattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
  48.  {
  49.      int status;
  50. +#if 1
  51. +    EASSERT(length > 4);
  52. +    if (length <= 4) {
  53. +        status = ERROR_INVALID_PARAMETER;
  54. +        goto out;
  55. +    }
  56. +    EASSERT(upcall->state_ref != NULL);
  57. +    if (upcall->state_ref == NULL) {
  58. +        status = ERROR_INVALID_PARAMETER;
  59. +        goto out;
  60. +    }
  61. +#endif
  62.      getattr_upcall_args *args = &upcall->args.getattr;
  63. -
  64.      status = safe_read(&buffer, &length, &args->query_class, sizeof(args->query_class));
  65.      if (status) goto out;
  66.      status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
  67. @@ -80,6 +91,21 @@ static int handle_getattr(void *daemon_context, nfs41_upcall *upcall)
  68.      nfs41_open_state *state = upcall->state_ref;
  69.      nfs41_file_info info = { 0 };
  70.  
  71. +#if 1
  72. +    if (((char *)state->session) == ((char *)0xdddddddddddddddd)) {
  73. +        eprintf("handle_getattr: Invalid session pointer 0xdddddddddddddddd\n");
  74. +        status = ERROR_INVALID_PARAMETER;
  75. +        goto out;
  76. +    }
  77. +
  78. +    EASSERT(state->file.fh.superblock != NULL);
  79. +    if (state->file.fh.superblock == NULL) {
  80. +        /* gisburn: fixme: maybe this should be |ERROR_INTERNAL_ERROR| ? */
  81. +        status = ERROR_INVALID_PARAMETER;
  82. +        goto out;
  83. +    }
  84. +#endif
  85. +
  86.      status = nfs41_cached_getattr(state->session, &state->file, &info);
  87.      if (status) {
  88.          eprintf("nfs41_cached_getattr() failed with %d\n", status);
  89. diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c
  90. index bcca070..f2a4f22 100644
  91. --- a/daemon/nfs41_ops.c
  92. +++ b/daemon/nfs41_ops.c
  93. @@ -400,6 +400,9 @@ int nfs41_open(
  94.      bool_t already_delegated = delegation->type == OPEN_DELEGATE_READ
  95.          || delegation->type == OPEN_DELEGATE_WRITE;
  96.  
  97. +    EASSERT(parent);
  98. +    EASSERT(parent->fh.superblock);
  99. +
  100.      /* depending on the claim type, OPEN expects CURRENT_FH set
  101.       * to either the parent directory, or to the file itself */
  102.      switch (claim->claim) {
  103. diff --git a/daemon/nfs41_superblock.c b/daemon/nfs41_superblock.c
  104. index b2f77fd..667e880 100644
  105. --- a/daemon/nfs41_superblock.c
  106. +++ b/daemon/nfs41_superblock.c
  107. @@ -169,6 +169,8 @@ void nfs41_superblock_fs_attributes(
  108.      FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_REMOTE_STORAGE;
  109.      /* NFSv4 protocol uses Unicode by default */
  110.      FsAttrs->FileSystemAttributes |= FILE_UNICODE_ON_DISK;
  111. +    /* NFSv4 protocol supports POSIX semantics for |unlink()|/|rename()| */
  112. +    FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_POSIX_UNLINK_RENAME;
  113.  
  114.      if (superblock->link_support)
  115.          FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_HARD_LINKS;
  116. diff --git a/daemon/open.c b/daemon/open.c
  117. index 4b2a335..487c341 100644
  118. --- a/daemon/open.c
  119. +++ b/daemon/open.c
  120. @@ -99,6 +99,24 @@ static void open_state_free(
  121.  void nfs41_open_state_ref(
  122.      IN nfs41_open_state *state)
  123.  {
  124. +#if 1
  125. +    /*
  126. +     * gisburn: fixme: sometimes this happens under high parallel
  127. +     * usage with multiple mounts - but why ?
  128. +     * 0:038> kp
  129. +     * Child-SP          RetAddr           Call Site
  130. +     * 0000006d`431fde10 00007ff7`32f7d905 nfsd!nfs41_open_state_ref(struct __nfs41_open_state * state = 0x00000000`00000000)+0x31
  131. +     * 0000006d`431fdf30 00007ff7`32f4d284 nfsd!upcall_parse(unsigned char * buffer = 0x0000006d`431fe180 "???", unsigned int length = 8, struct __nfs41_upcall * upcall = 0x0000006d`431ff1e0)+0x2e5
  132. +     * 0000006d`431fe0b0 00007ffc`1ca24c7c nfsd!thread_main(void * args = 0x00007ff7`32fb6080)+0x144
  133. +     * 0000006d`431ffe00 00007ffc`4d4b7344 ucrtbased!thread_start<unsigned int (void * parameter = 0x0000025d`a9c6def0)+0x9c
  134. +     * 0000006d`431ffe60 00007ffc`4efc26b1 KERNEL32!BaseThreadInitThunk+0x14
  135. +     * 0000006d`431ffe90 00000000`00000000 ntdll!RtlUserThreadStart+0x21
  136. +     */
  137. +    EASSERT(state != NULL);
  138. +    if (state == NULL)
  139. +        return;
  140. +#endif
  141. +
  142.      const LONG count = InterlockedIncrement(&state->ref_count);
  143.  
  144.      dprintf(2, "nfs41_open_state_ref(%s) count %d\n", state->path.path, count);
  145. diff --git a/daemon/setattr.c b/daemon/setattr.c
  146. index 369dd6f..5f285ab 100644
  147. --- a/daemon/setattr.c
  148. +++ b/daemon/setattr.c
  149. @@ -52,13 +52,13 @@ static int parse_setattr(unsigned char *buffer, uint32_t length, nfs41_upcall *u
  150.      dprintf(1, "parsing NFS41_FILE_SET: filename='%s' info_class=%d "
  151.          "buf_len=%d\n", args->path, args->set_class, args->buf_len);
  152.  out:
  153. -    return status;
  154. -}
  155. -
  156. -static int handle_nfs41_setattr(void *daemon_context, setattr_upcall_args *args)
  157. -{
  158. -    PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf;
  159. -    nfs41_open_state *state = args->state;
  160. +    return status;
  161. +}
  162. +
  163. +static int handle_nfs41_setattr(void *daemon_context, setattr_upcall_args *args)
  164. +{
  165. +    PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf;
  166. +    nfs41_open_state *state = args->state;
  167.      nfs41_superblock *superblock = state->file.fh.superblock;
  168.      stateid_arg stateid;
  169.      nfs41_file_info info = { 0 }, old_info = { 0 };
  170. @@ -146,13 +146,13 @@ static int handle_nfs41_setattr(void *daemon_context, setattr_upcall_args *args)
  171.      }
  172.      args->ctime = info.change;
  173.  out:
  174. -    return status;
  175. -}
  176. -
  177. -static int handle_nfs41_remove(void *daemon_context, setattr_upcall_args *args)
  178. -{
  179. -    nfs41_open_state *state = args->state;
  180. -    int status;
  181. +    return status;
  182. +}
  183. +
  184. +static int handle_nfs41_remove(void *daemon_context, setattr_upcall_args *args)
  185. +{
  186. +    nfs41_open_state *state = args->state;
  187. +    int status;
  188.  
  189.      /* break any delegations and truncate before REMOVE */
  190.      nfs41_delegation_return(state->session, &state->file,
  191. @@ -205,13 +205,13 @@ static int is_dst_name_opened(nfs41_abs_path *dst_path, nfs41_session *dst_sessi
  192.      else
  193.          status = FALSE;
  194.      LeaveCriticalSection(&client->state.lock);
  195. -
  196. -    return status;
  197. -}
  198. -static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  199. -{
  200. -    nfs41_open_state *state = args->state;
  201. -    nfs41_session *dst_session;
  202. +
  203. +    return status;
  204. +}
  205. +static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  206. +{
  207. +    nfs41_open_state *state = args->state;
  208. +    nfs41_session *dst_session;
  209.      PFILE_RENAME_INFO rename = (PFILE_RENAME_INFO)args->buf;
  210.      nfs41_abs_path dst_path = { 0 };
  211.      nfs41_path_fh dst_dir, dst;
  212. @@ -291,10 +291,25 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  213.      last_component(dst_path.path, dst_name.name, &dst_dir.name);
  214.  
  215.      if (status == NO_ERROR) {
  216. -        if (!rename->ReplaceIfExists) {
  217. -            status = ERROR_FILE_EXISTS;
  218. -            goto out;
  219. +        if (args->set_class == FileRenameInformationEx) {
  220. +            dprintf(0, "FileRenameInformationEx(rename->Flags=%x, POSIX=%d)\n",
  221. +                (int)rename->Flags,
  222. +                (int)(rename->Flags & FILE_RENAME_POSIX_SEMANTICS)?1:0);
  223. +            if (!rename->Flags & FILE_RENAME_REPLACE_IF_EXISTS) {
  224. +                status = ERROR_FILE_EXISTS;
  225. +                goto out;
  226. +            }
  227. +        }
  228. +        else if (args->set_class == FileRenameInformation) {
  229. +            if (!rename->ReplaceIfExists) {
  230. +                status = ERROR_FILE_EXISTS;
  231. +                goto out;
  232. +            }
  233.          }
  234. +        else {
  235. +            EASSERT(1);
  236. +        }
  237. +
  238.          /* break any delegations and truncate the destination file */
  239.          nfs41_delegation_return(dst_session, &dst,
  240.              OPEN_DELEGATE_WRITE, TRUE);
  241. @@ -338,13 +353,13 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  242.          open_state_rename(state, &dst_path);
  243.      }
  244.  out:
  245. -    return status;
  246. -}
  247. -
  248. -static int handle_nfs41_set_size(void *daemon_context, setattr_upcall_args *args)
  249. -{
  250. -    nfs41_file_info info = { 0 };
  251. -    stateid_arg stateid;
  252. +    return status;
  253. +}
  254. +
  255. +static int handle_nfs41_set_size(void *daemon_context, setattr_upcall_args *args)
  256. +{
  257. +    nfs41_file_info info = { 0 };
  258. +    stateid_arg stateid;
  259.      /* note: this is called with either FILE_END_OF_FILE_INFO or
  260.       * FILE_ALLOCATION_INFO, both of which contain a single LARGE_INTEGER */
  261.      PLARGE_INTEGER size = (PLARGE_INTEGER)args->buf;
  262. @@ -375,13 +390,13 @@ static int handle_nfs41_set_size(void *daemon_context, setattr_upcall_args *args
  263.      ReleaseSRWLockExclusive(&state->lock);
  264.      args->ctime = info.change;
  265.  out:
  266. -    return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
  267. -}
  268. -
  269. -static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
  270. -{
  271. -    nfs41_open_state *state = args->state;
  272. -    PFILE_LINK_INFORMATION link = (PFILE_LINK_INFORMATION)args->buf;
  273. +    return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
  274. +}
  275. +
  276. +static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
  277. +{
  278. +    nfs41_open_state *state = args->state;
  279. +    PFILE_LINK_INFORMATION link = (PFILE_LINK_INFORMATION)args->buf;
  280.      nfs41_session *dst_session;
  281.      nfs41_abs_path dst_path = { 0 };
  282.      nfs41_path_fh dst_dir, dst;
  283. @@ -477,36 +492,37 @@ static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
  284.      }
  285.      args->ctime = info.change;
  286.  out:
  287. -    return status;
  288. -}
  289. -
  290. -static int handle_setattr(void *daemon_context, nfs41_upcall *upcall)
  291. -{
  292. -    setattr_upcall_args *args = &upcall->args.setattr;
  293. -    int status;
  294. -
  295. -    switch (args->set_class) {
  296. -    case FileBasicInformation:
  297. -        status = handle_nfs41_setattr(daemon_context, args);
  298. -        break;
  299. -    case FileDispositionInformation:
  300. -        status = handle_nfs41_remove(daemon_context, args);
  301. -        break;
  302. -    case FileRenameInformation:
  303. -        status = handle_nfs41_rename(daemon_context, args);
  304. -        break;
  305. -    case FileAllocationInformation:
  306. -    case FileEndOfFileInformation:
  307. -        status = handle_nfs41_set_size(daemon_context, args);
  308. -        break;
  309. -    case FileLinkInformation:
  310. -        status = handle_nfs41_link(daemon_context, args);
  311. -        break;
  312. -    default:
  313. -        eprintf("handle_setattr: unknown set_file information class %d\n",
  314. -            args->set_class);
  315. -        status = ERROR_NOT_SUPPORTED;
  316. -        break;
  317. +    return status;
  318. +}
  319. +
  320. +static int handle_setattr(void *daemon_context, nfs41_upcall *upcall)
  321. +{
  322. +    setattr_upcall_args *args = &upcall->args.setattr;
  323. +    int status;
  324. +
  325. +    switch (args->set_class) {
  326. +    case FileBasicInformation:
  327. +        status = handle_nfs41_setattr(daemon_context, args);
  328. +        break;
  329. +    case FileDispositionInformation:
  330. +        status = handle_nfs41_remove(daemon_context, args);
  331. +        break;
  332. +    case FileRenameInformation:
  333. +    case FileRenameInformationEx:
  334. +        status = handle_nfs41_rename(daemon_context, args);
  335. +        break;
  336. +    case FileAllocationInformation:
  337. +    case FileEndOfFileInformation:
  338. +        status = handle_nfs41_set_size(daemon_context, args);
  339. +        break;
  340. +    case FileLinkInformation:
  341. +        status = handle_nfs41_link(daemon_context, args);
  342. +        break;
  343. +    default:
  344. +        eprintf("handle_setattr: unknown set_file information class %d\n",
  345. +            args->set_class);
  346. +        status = ERROR_NOT_SUPPORTED;
  347. +        break;
  348.      }
  349.  
  350.      return status;
  351. diff --git a/daemon/upcall.c b/daemon/upcall.c
  352. index bd13c61..7778429 100644
  353. --- a/daemon/upcall.c
  354. +++ b/daemon/upcall.c
  355. @@ -121,6 +121,7 @@ int upcall_parse(
  356.      /* parse the operation's arguments */
  357.      op = g_upcall_op_table[upcall->opcode];
  358.      if (op && op->parse) {
  359. +        EASSERT(length > 0);
  360.          status = op->parse(buffer, length, upcall);
  361.          if (status) {
  362.              eprintf("parsing of upcall '%s' failed with %d.\n",
  363. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  364. index 8b259bb..6d3429f 100644
  365. --- a/dll/nfs41_np.c
  366. +++ b/dll/nfs41_np.c
  367. @@ -28,6 +28,8 @@
  368.  #include "nfs41_np.h"
  369.  #include "options.h"
  370.  
  371. +#define DBG 1
  372. +
  373.  #ifdef DBG
  374.  #define DbgP(_x_) NFS41DbgPrint _x_
  375.  #else
  376. diff --git a/sys/nfs41_build_features.h b/sys/nfs41_build_features.h
  377. index 93ee7a9..d43334a 100644
  378. --- a/sys/nfs41_build_features.h
  379. +++ b/sys/nfs41_build_features.h
  380. @@ -32,19 +32,19 @@
  381.  /*
  382.   * NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES - return local uid/gid values
  383.   */
  384. -// #define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES 1
  385. +#define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES 1
  386.  
  387.  /*
  388.   * NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID - give NFS
  389.   * files which do not map to a local account a SID in the
  390.   * Unix_User+x/Unix_Group+x range
  391.   */
  392. -// #define NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID 1
  393. +#define NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID 1
  394.  
  395.  /*
  396.   * NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN - use Cygwin /usr/bin/getent
  397.   * as "name service"
  398.   */
  399. -// #define NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN 1
  400. +#define NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN 1
  401.  
  402.  #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
  403. diff --git a/sys/nfs41_debug.c b/sys/nfs41_debug.c
  404. index d52d580..7a51f9f 100644
  405. --- a/sys/nfs41_debug.c
  406. +++ b/sys/nfs41_debug.c
  407. @@ -539,6 +539,8 @@ unsigned char * print_file_information_class(int InfoClass)
  408.              return (unsigned char *)"FileLinkInformation";
  409.          case FileRenameInformation:
  410.              return (unsigned char *)"FileRenameInformation";
  411. +        case FileRenameInformationEx:
  412. +            return (unsigned char *)"FileRenameInformationEx";
  413.          case FileValidDataLengthInformation:
  414.              return (unsigned char *)"FileValidDataLengthInformation";
  415.          default:
  416. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  417. index dcec443..da85dab 100644
  418. --- a/sys/nfs41_driver.c
  419. +++ b/sys/nfs41_driver.c
  420. @@ -5604,6 +5604,7 @@ NTSTATUS check_nfs41_setattr_args(
  421.  
  422.      switch (InfoClass) {
  423.      case FileRenameInformation:
  424. +    case FileRenameInformationEx:
  425.      {
  426.          PFILE_RENAME_INFORMATION rinfo =
  427.              (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
  428. @@ -5704,11 +5705,11 @@ NTSTATUS nfs41_SetFileInformation(
  429.                      break;
  430.                  nfs41_fcb->StandardInfo.DeletePending = TRUE;
  431.                  if (RxContext->pFcb->OpenCount > 1) {
  432. -                    rinfo.ReplaceIfExists = 0;
  433. +                    rinfo.Flags = 0;
  434.                      rinfo.RootDirectory = INVALID_HANDLE_VALUE;
  435.                      rinfo.FileNameLength = 0;
  436.                      rinfo.FileName[0] = L'\0';
  437. -                    InfoClass = FileRenameInformation;
  438. +                    InfoClass = FileRenameInformationEx;
  439.                      nfs41_fcb->Renamed = TRUE;
  440.                      break;
  441.                  }
  442. @@ -5733,6 +5734,7 @@ NTSTATUS nfs41_SetFileInformation(
  443.              break;
  444.          }
  445.      case FileRenameInformation:
  446. +    case FileRenameInformationEx:
  447.          {
  448.              /* noop if filename and destination are the same */
  449.              PFILE_RENAME_INFORMATION prinfo =
  450. @@ -5756,8 +5758,9 @@ NTSTATUS nfs41_SetFileInformation(
  451.  
  452.      /* original irp has infoclass for remove but we need to rename instead,
  453.       * thus we changed the local variable infoclass */
  454. -    if (RxContext->Info.FileInformationClass == FileDispositionInformation &&
  455. -            InfoClass == FileRenameInformation) {
  456. +    if ((RxContext->Info.FileInformationClass == FileDispositionInformation) &&
  457. +            ((InfoClass == FileRenameInformation) ||
  458. +             (InfoClass == FileRenameInformationEx))) {
  459.          entry->buf = &rinfo;
  460.          entry->buf_len = sizeof(rinfo);
  461.      } else {

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at