pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Patches for Win32 timestamps if server has no timestamp data, winfsinfo+misc, 2024-04-13 ...
Posted by Anonymous on Sat 13th Apr 2024 13:25
raw | new post

  1. From 7334641ac3cf3a046b96804a0080614a6a4c36b1 Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Sat, 13 Apr 2024 11:30:41 +0200
  4. Subject: [PATCH 1/3] winfsinfo: Add subcommands and switch to ksh93 compound
  5.  variable output
  6.  
  7. Add subcommands ("getvolumeinfo", "filebasicinfo", "filestandardinfo")
  8. and switch to ksh93 compound variable output (so ksh93 can read
  9. the info via ksh93 -c 'compound cpy; read -C cpv ; ...'
  10.  
  11. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  12. ---
  13. tests/winfsinfo1/winfsinfo.c | 255 +++++++++++++++++++++++++++++------
  14.  1 file changed, 213 insertions(+), 42 deletions(-)
  15.  
  16. diff --git a/tests/winfsinfo1/winfsinfo.c b/tests/winfsinfo1/winfsinfo.c
  17. index 361e2d2..3c5a2bb 100644
  18. --- a/tests/winfsinfo1/winfsinfo.c
  19. +++ b/tests/winfsinfo1/winfsinfo.c
  20. @@ -1,7 +1,7 @@
  21.  /*
  22.   * MIT License
  23.   *
  24. - * Copyright (c) 2023 Roland Mainz <roland.mainz@nrubsig.org>
  25. + * Copyright (c) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
  26.   *
  27.   * Permission is hereby granted, free of charge, to any person obtaining a copy
  28.   * of this software and associated documentation files (the "Software"), to deal
  29. @@ -23,7 +23,8 @@
  30.   */
  31.  
  32.  /*
  33. - * winfsinfo1.c - print Windows filesystem info
  34. + * winfsinfo1.c - print Windows filesystem info in ksh93 compound
  35. + * variable format (suiteable for ksh93 $ read -C varnname #)
  36.   *
  37.   * Written by Roland Mainz <roland.mainz@nrubsig.org>
  38.   */
  39. @@ -37,9 +38,10 @@
  40.  #include <stdbool.h>
  41.  
  42.  static
  43. -bool print_volume_info(const char *progname, const char *filename)
  44. +bool getvolumeinfo(const char *progname, const char *filename)
  45.  {
  46. -    bool ok = false;
  47. +    int res = EXIT_FAILURE;
  48. +    bool ok;
  49.  
  50.      HANDLE fileHandle = CreateFileA(filename,
  51.          GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  52. @@ -50,11 +52,9 @@ bool print_volume_info(const char *progname, const char *filename)
  53.              progname,
  54.              filename,
  55.              GetLastError());
  56. -        return false;
  57. +        return EXIT_FAILURE;
  58.      }
  59.  
  60. -    (void)printf("filename='%s'\n", filename);
  61. -
  62.      DWORD volumeFlags = 0;
  63.      ok = GetVolumeInformationByHandleW(fileHandle, NULL, 0,
  64.          NULL, NULL, &volumeFlags, NULL, 0);
  65. @@ -64,68 +64,239 @@ bool print_volume_info(const char *progname, const char *filename)
  66.              "error. GetLastError()==%d.\n",
  67.              progname,
  68.              GetLastError());
  69. -        ok = false;
  70. +        res = EXIT_FAILURE;
  71.          goto done;
  72.      }
  73.  
  74. -#define TESTFSATTR(s) \
  75. +    (void)printf("(\n");
  76. +    (void)printf("\tfilename='%s'\n", filename);
  77. +    (void)printf("\ttypeset -a volumeflags=(\n");
  78. +
  79. +#define TESTVOLFLAG(s) \
  80.      if (volumeFlags & (s)) { \
  81. -        (void)puts("volumeflag="#s); \
  82. +        (void)puts("\t\t"#s); \
  83.          volumeFlags &= ~(s); \
  84.      }
  85.  
  86. -    TESTFSATTR(FILE_SUPPORTS_USN_JOURNAL);
  87. -    TESTFSATTR(FILE_SUPPORTS_OPEN_BY_FILE_ID);
  88. -    TESTFSATTR(FILE_SUPPORTS_EXTENDED_ATTRIBUTES);
  89. -    TESTFSATTR(FILE_SUPPORTS_HARD_LINKS);
  90. -    TESTFSATTR(FILE_SUPPORTS_TRANSACTIONS);
  91. -    TESTFSATTR(FILE_SEQUENTIAL_WRITE_ONCE);
  92. -    TESTFSATTR(FILE_READ_ONLY_VOLUME);
  93. -    TESTFSATTR(FILE_NAMED_STREAMS);
  94. -    TESTFSATTR(FILE_SUPPORTS_ENCRYPTION);
  95. -    TESTFSATTR(FILE_SUPPORTS_OBJECT_IDS);
  96. -    TESTFSATTR(FILE_VOLUME_IS_COMPRESSED);
  97. -    TESTFSATTR(FILE_SUPPORTS_REMOTE_STORAGE);
  98. -    TESTFSATTR(FILE_RETURNS_CLEANUP_RESULT_INFO);
  99. -    TESTFSATTR(FILE_SUPPORTS_POSIX_UNLINK_RENAME);
  100. -    TESTFSATTR(FILE_SUPPORTS_REPARSE_POINTS);
  101. -    TESTFSATTR(FILE_SUPPORTS_SPARSE_FILES);
  102. -    TESTFSATTR(FILE_VOLUME_QUOTAS);
  103. -    TESTFSATTR(FILE_FILE_COMPRESSION);
  104. -    TESTFSATTR(FILE_PERSISTENT_ACLS);
  105. -    TESTFSATTR(FILE_UNICODE_ON_DISK);
  106. -    TESTFSATTR(FILE_CASE_PRESERVED_NAMES);
  107. -    TESTFSATTR(FILE_CASE_SENSITIVE_SEARCH);
  108. -    TESTFSATTR(FILE_SUPPORTS_INTEGRITY_STREAMS);
  109. +    TESTVOLFLAG(FILE_SUPPORTS_USN_JOURNAL);
  110. +    TESTVOLFLAG(FILE_SUPPORTS_OPEN_BY_FILE_ID);
  111. +    TESTVOLFLAG(FILE_SUPPORTS_EXTENDED_ATTRIBUTES);
  112. +    TESTVOLFLAG(FILE_SUPPORTS_HARD_LINKS);
  113. +    TESTVOLFLAG(FILE_SUPPORTS_TRANSACTIONS);
  114. +    TESTVOLFLAG(FILE_SEQUENTIAL_WRITE_ONCE);
  115. +    TESTVOLFLAG(FILE_READ_ONLY_VOLUME);
  116. +    TESTVOLFLAG(FILE_NAMED_STREAMS);
  117. +    TESTVOLFLAG(FILE_SUPPORTS_ENCRYPTION);
  118. +    TESTVOLFLAG(FILE_SUPPORTS_OBJECT_IDS);
  119. +    TESTVOLFLAG(FILE_VOLUME_IS_COMPRESSED);
  120. +    TESTVOLFLAG(FILE_SUPPORTS_REMOTE_STORAGE);
  121. +    TESTVOLFLAG(FILE_RETURNS_CLEANUP_RESULT_INFO);
  122. +    TESTVOLFLAG(FILE_SUPPORTS_POSIX_UNLINK_RENAME);
  123. +    TESTVOLFLAG(FILE_SUPPORTS_REPARSE_POINTS);
  124. +    TESTVOLFLAG(FILE_SUPPORTS_SPARSE_FILES);
  125. +    TESTVOLFLAG(FILE_VOLUME_QUOTAS);
  126. +    TESTVOLFLAG(FILE_FILE_COMPRESSION);
  127. +    TESTVOLFLAG(FILE_PERSISTENT_ACLS);
  128. +    TESTVOLFLAG(FILE_UNICODE_ON_DISK);
  129. +    TESTVOLFLAG(FILE_CASE_PRESERVED_NAMES);
  130. +    TESTVOLFLAG(FILE_CASE_SENSITIVE_SEARCH);
  131. +    TESTVOLFLAG(FILE_SUPPORTS_INTEGRITY_STREAMS);
  132.  #ifdef FILE_SUPPORTS_BLOCK_REFCOUNTING
  133. -    TESTFSATTR(FILE_SUPPORTS_BLOCK_REFCOUNTING);
  134. +    TESTVOLFLAG(FILE_SUPPORTS_BLOCK_REFCOUNTING);
  135.  #endif
  136.  #ifdef FILE_SUPPORTS_SPARSE_VDL
  137. -    TESTFSATTR(FILE_SUPPORTS_SPARSE_VDL);
  138. +    TESTVOLFLAG(FILE_SUPPORTS_SPARSE_VDL);
  139.  #endif
  140.  #ifdef FILE_DAX_VOLUME
  141. -    TESTFSATTR(FILE_DAX_VOLUME);
  142. +    TESTVOLFLAG(FILE_DAX_VOLUME);
  143.  #endif
  144.  #ifdef FILE_SUPPORTS_GHOSTING
  145. -    TESTFSATTR(FILE_SUPPORTS_GHOSTING);
  146. +    TESTVOLFLAG(FILE_SUPPORTS_GHOSTING);
  147.  #endif
  148.  
  149. +    (void)printf("\t)\n");
  150. +
  151.      /*
  152. -     * print any leftover flags not covered by |TESTFSATTR(FILE_*)|
  153. +     * print any leftover flags not covered by |TESTVOLFLAG(FILE_*)|
  154.       * above
  155.       */
  156.      if (volumeFlags) {
  157. -        (void)printf("attr=0x%lx\n", (long)volumeFlags);
  158. +        (void)printf("\tattr=0x%lx\n", (long)volumeFlags);
  159. +    }
  160. +    (void)printf(")\n");
  161. +    res = EXIT_SUCCESS;
  162. +
  163. +done:
  164. +    CloseHandle(fileHandle);
  165. +    return res;
  166. +}
  167. +
  168. +
  169. +static
  170. +bool get_file_basic_info(const char *progname, const char *filename)
  171. +{
  172. +    int res = EXIT_FAILURE;
  173. +    bool ok;
  174. +    FILE_BASIC_INFO finfo = { 0 };
  175. +
  176. +    HANDLE fileHandle = CreateFileA(filename,
  177. +        GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  178. +        FILE_FLAG_BACKUP_SEMANTICS, NULL);
  179. +    if (fileHandle == INVALID_HANDLE_VALUE) {
  180. +        (void)fprintf(stderr,
  181. +            "%s: Error opening file '%s'. Last error was %d.\n",
  182. +            progname,
  183. +            filename,
  184. +            GetLastError());
  185. +        return EXIT_FAILURE;
  186.      }
  187. -    ok = true;
  188. +
  189. +    ok = GetFileInformationByHandleEx(fileHandle, FileBasicInfo, &finfo,
  190. +        sizeof(finfo));
  191. +
  192. +    if (!ok) {
  193. +        (void)fprintf(stderr, "%s: GetFileInformationByHandleEx() "
  194. +            "error. GetLastError()==%d.\n",
  195. +            progname,
  196. +            GetLastError());
  197. +        res = EXIT_FAILURE;
  198. +        goto done;
  199. +    }
  200. +
  201. +    (void)printf("(\n");
  202. +    (void)printf("\tfilename='%s'\n", filename);
  203. +
  204. +    (void)printf("\tCreationTime=%lld\n", (long long)finfo.CreationTime.QuadPart);
  205. +    (void)printf("\tLastAccessTime=%lld\n", (long long)finfo.LastAccessTime.QuadPart);
  206. +    (void)printf("\tLastWriteTime=%lld\n", (long long)finfo.LastWriteTime.QuadPart);
  207. +    (void)printf("\tChangeTime=%lld\n", (long long)finfo.ChangeTime.QuadPart);
  208. +    DWORD fattr = finfo.FileAttributes;
  209. +
  210. +    (void)printf("\ttypeset -a FileAttributes=(\n");
  211. +
  212. +#define TESTFBIA(s) \
  213. +    if (fattr & (s)) { \
  214. +        (void)puts("\t\t"#s); \
  215. +        fattr &= ~(s); \
  216. +    }
  217. +    TESTFBIA(FILE_ATTRIBUTE_READONLY);
  218. +    TESTFBIA(FILE_ATTRIBUTE_HIDDEN);
  219. +    TESTFBIA(FILE_ATTRIBUTE_SYSTEM);
  220. +    TESTFBIA(FILE_ATTRIBUTE_DIRECTORY);
  221. +    TESTFBIA(FILE_ATTRIBUTE_ARCHIVE);
  222. +    TESTFBIA(FILE_ATTRIBUTE_DEVICE);
  223. +    TESTFBIA(FILE_ATTRIBUTE_NORMAL);
  224. +    TESTFBIA(FILE_ATTRIBUTE_TEMPORARY);
  225. +    TESTFBIA(FILE_ATTRIBUTE_SPARSE_FILE);
  226. +    TESTFBIA(FILE_ATTRIBUTE_REPARSE_POINT);
  227. +    TESTFBIA(FILE_ATTRIBUTE_COMPRESSED);
  228. +    TESTFBIA(FILE_ATTRIBUTE_OFFLINE);
  229. +    TESTFBIA(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
  230. +    TESTFBIA(FILE_ATTRIBUTE_ENCRYPTED);
  231. +    TESTFBIA(FILE_ATTRIBUTE_INTEGRITY_STREAM);
  232. +    TESTFBIA(FILE_ATTRIBUTE_VIRTUAL);
  233. +    TESTFBIA(FILE_ATTRIBUTE_NO_SCRUB_DATA);
  234. +    TESTFBIA(FILE_ATTRIBUTE_EA);
  235. +    TESTFBIA(FILE_ATTRIBUTE_PINNED);
  236. +    TESTFBIA(FILE_ATTRIBUTE_UNPINNED);
  237. +    TESTFBIA(FILE_ATTRIBUTE_RECALL_ON_OPEN);
  238. +    TESTFBIA(FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
  239. +
  240. +    (void)printf("\t)\n");
  241. +
  242. +    /*
  243. +     * print any leftover flags not covered by |TESTFBIA(FILE_*)|
  244. +     * above
  245. +     */
  246. +    if (fattr) {
  247. +        (void)printf("\tfattr=0x%lx\n", (long)fattr);
  248. +    }
  249. +    (void)printf(")\n");
  250. +    res = EXIT_SUCCESS;
  251.  
  252.  done:
  253.      CloseHandle(fileHandle);
  254. -    return ok;
  255. +    return res;
  256. +}
  257. +
  258. +
  259. +static
  260. +bool get_file_standard_info(const char *progname, const char *filename)
  261. +{
  262. +    int res = EXIT_FAILURE;
  263. +    bool ok;
  264. +    FILE_STANDARD_INFO finfo = { 0 };
  265. +
  266. +    HANDLE fileHandle = CreateFileA(filename,
  267. +        GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  268. +        FILE_FLAG_BACKUP_SEMANTICS, NULL);
  269. +    if (fileHandle == INVALID_HANDLE_VALUE) {
  270. +        (void)fprintf(stderr,
  271. +            "%s: Error opening file '%s'. Last error was %d.\n",
  272. +            progname,
  273. +            filename,
  274. +            GetLastError());
  275. +        return EXIT_FAILURE;
  276. +    }
  277. +
  278. +    ok = GetFileInformationByHandleEx(fileHandle, FileStandardInfo, &finfo,
  279. +        sizeof(finfo));
  280. +
  281. +    if (!ok) {
  282. +        (void)fprintf(stderr, "%s: GetFileInformationByHandleEx() "
  283. +            "error. GetLastError()==%d.\n",
  284. +            progname,
  285. +            GetLastError());
  286. +        res = EXIT_FAILURE;
  287. +        goto done;
  288. +    }
  289. +
  290. +    (void)printf("(\n");
  291. +    (void)printf("\tfilename='%s'\n", filename);
  292. +
  293. +    (void)printf("\tAllocationSize=%lld\n", (long long)finfo.AllocationSize.QuadPart);
  294. +    (void)printf("\tEndOfFile=%lld\n",      (long long)finfo.EndOfFile.QuadPart);
  295. +    (void)printf("\tNumberOfLinks=%ld\n",   (long)finfo.NumberOfLinks);
  296. +    (void)printf("\tDeletePending=%s\n",    finfo.DeletePending?"true":"false");
  297. +    (void)printf("\tDirectory=%s\n",        finfo.Directory?"true":"false");
  298. +    (void)printf(")\n");
  299. +    res = EXIT_SUCCESS;
  300. +
  301. +done:
  302. +    CloseHandle(fileHandle);
  303. +    return res;
  304. +}
  305. +
  306. +static
  307. +void usage(void)
  308. +{
  309. +    (void)fprintf(stderr, "winfsinfo <getvolumeinfo|filebasicinfo|filestandardinfo> path\n");
  310.  }
  311.  
  312.  int main(int ac, char *av[])
  313.  {
  314. -    print_volume_info(av[0], av[1]);
  315. +    const char *subcmd;
  316. +
  317. +    if (ac < 3) {
  318. +        usage();
  319. +        return 2;
  320. +    }
  321. +
  322. +    subcmd = av[1];
  323. +
  324. +    if (!strcmp(subcmd, "getvolumeinfo")) {
  325. +        return getvolumeinfo(av[0], av[2]);
  326. +    }
  327. +    else if (!strcmp(subcmd, "filebasicinfo")) {
  328. +        return get_file_basic_info(av[0], av[2]);
  329. +    }
  330. +    else if (!strcmp(subcmd, "filestandardinfo")) {
  331. +        return get_file_standard_info(av[0], av[2]);
  332. +    }
  333. +    else {
  334. +        (void)fprintf(stderr, "%s: Unknown subcmd '%s'\n", av[0], subcmd);
  335. +        return EXIT_FAILURE;
  336. +    }
  337. +
  338.      return EXIT_SUCCESS;
  339.  }
  340. --
  341. 2.43.0
  342.  
  343. From 22cb8e3c199312686482592bd6f92e3f67e2f6d9 Mon Sep 17 00:00:00 2001
  344. From: Roland Mainz <roland.mainz@nrubsig.org>
  345. Date: Sat, 13 Apr 2024 11:54:00 +0200
  346. Subject: [PATCH 2/3] daemon: Set Win32 timestamps to 0 if matching
  347.  |FATTR4_WORD1_TIME_*| is not provided
  348.  
  349. Set Win32 timestamps { |CreationTime|, |LastAccessTime|,
  350. |LastWriteTime|, |ChangeTime| } to |0| if NFSv4.1 dir info or getattr
  351. do not return information for them (e.g. one or more of
  352. |FATTR4_WORD1_TIME_CREATE|, |FATTR4_WORD1_TIME_ACCESS|,
  353. |FATTR4_WORD1_TIME_MODIFY| not being set).
  354.  
  355. This can happen for example with NFSv4.1 servers which do not support
  356. |FATTR4_WORD1_TIME_CREATE|, or filesystems being exported by the NFS
  357. server which do not support access timestamps etc.
  358.  
  359. This avoids that we invent timestamp information which does not
  360. exists.
  361.  
  362. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  363. ---
  364. cygwin/README.bintarball.txt |  2 +
  365.  daemon/getattr.c             |  4 +-
  366.  daemon/name_cache.c          | 26 +++++++----
  367.  daemon/nfs41_xdr.c           |  1 +
  368.  daemon/open.c                |  6 +--
  369.  daemon/readdir.c             | 52 ++++++++++++++++++----
  370.  daemon/util.c                | 83 ++++++++++++++++++++++++++++++++----
  371.  daemon/util.h                | 11 +++++
  372.  8 files changed, 155 insertions(+), 30 deletions(-)
  373.  
  374. diff --git a/cygwin/README.bintarball.txt b/cygwin/README.bintarball.txt
  375. index cc275d1..bc0209d 100644
  376. --- a/cygwin/README.bintarball.txt
  377. +++ b/cygwin/README.bintarball.txt
  378. @@ -283,6 +283,8 @@ $ /sbin/nfs_mount
  379.  - Does not allow renaming a file on top of an existing open file.
  380.    Connectathon's special test op_ren has been commented out.
  381.  
  382. +- File access timestamps might be wrong for delegations.
  383. +
  384.  - Extended attributes are supported with some limitations:
  385.    a) the server must support NFS Named Attributes,
  386.    b) the order of listings cannot be guaranteed by NFS, and
  387. diff --git a/daemon/getattr.c b/daemon/getattr.c
  388. index 6708702..9cf1852 100644
  389. --- a/daemon/getattr.c
  390. +++ b/daemon/getattr.c
  391. @@ -149,7 +149,7 @@ static int handle_getattr(void *daemon_context, nfs41_upcall *upcall)
  392.  
  393.      switch (args->query_class) {
  394.      case FileBasicInformation:
  395. -        nfs_to_basic_info(&info, &args->basic_info);
  396. +        nfs_to_basic_info(state->file.name.name, &info, &args->basic_info);
  397.          args->ctime = info.change;
  398.          break;
  399.      case FileStandardInformation:
  400. @@ -164,7 +164,7 @@ static int handle_getattr(void *daemon_context, nfs41_upcall *upcall)
  401.          args->intr_info.IndexNumber.QuadPart = info.fileid;
  402.          break;
  403.      case FileNetworkOpenInformation:
  404. -        nfs_to_network_openinfo(&info, &args->network_info);
  405. +        nfs_to_network_openinfo(state->file.name.name, &info, &args->network_info);
  406.          break;
  407.      default:
  408.          eprintf("unhandled file query class %d\n", args->query_class);
  409. diff --git a/daemon/name_cache.c b/daemon/name_cache.c
  410. index 6e9f7bc..284fc2f 100644
  411. --- a/daemon/name_cache.c
  412. +++ b/daemon/name_cache.c
  413. @@ -3,6 +3,7 @@
  414.   *
  415.   * Olga Kornievskaia <aglo@umich.edu>
  416.   * Casey Bodley <cbodley@umich.edu>
  417. + * Roland Mainz <roland.mainz@nrubsig.org>
  418.   *
  419.   * This library is free software; you can redistribute it and/or modify it
  420.   * under the terms of the GNU Lesser General Public License as published by
  421. @@ -339,14 +340,31 @@ static void copy_attrs(
  422.      OUT nfs41_file_info *dst,
  423.      IN const struct attr_cache_entry *src)
  424.  {
  425. +    dst->attrmask.count = 2;
  426. +    dst->attrmask.arr[0] = FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE
  427. +        | FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID
  428. +        | FATTR4_WORD0_HIDDEN | FATTR4_WORD0_ARCHIVE;
  429. +    dst->attrmask.arr[1] = FATTR4_WORD1_MODE
  430. +        | FATTR4_WORD1_NUMLINKS
  431. +        | FATTR4_WORD1_SYSTEM;
  432. +
  433.      dst->change = src->change;
  434.      dst->size = src->size;
  435. +    if (!((src->time_access_s == 0) && (src->time_access_ns == 0))) {
  436. +        dst->attrmask.arr[1] |= FATTR4_WORD1_TIME_ACCESS;
  437.      dst->time_access.seconds = src->time_access_s;
  438.      dst->time_access.nseconds = src->time_access_ns;
  439. +    }
  440. +    if (!((src->time_create_s == 0) && (src->time_create_ns == 0))) {
  441. +        dst->attrmask.arr[1] |= FATTR4_WORD1_TIME_CREATE;
  442.      dst->time_create.seconds = src->time_create_s;
  443.      dst->time_create.nseconds = src->time_create_ns;
  444. +    }
  445. +    if (!((src->time_modify_s == 0) && (src->time_modify_ns == 0))) {
  446. +        dst->attrmask.arr[1] |= FATTR4_WORD1_TIME_MODIFY;
  447.      dst->time_modify.seconds = src->time_modify_s;
  448.      dst->time_modify.nseconds = src->time_modify_ns;
  449. +    }
  450.      dst->type = src->type;
  451.      dst->numlinks = src->numlinks;
  452.      dst->mode = src->mode;
  453. @@ -373,14 +391,6 @@ static void copy_attrs(
  454.      dst->system = src->system;
  455.      dst->archive = src->archive;
  456.  
  457. -    dst->attrmask.count = 2;
  458. -    dst->attrmask.arr[0] = FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE
  459. -        | FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID
  460. -        | FATTR4_WORD0_HIDDEN | FATTR4_WORD0_ARCHIVE;
  461. -    dst->attrmask.arr[1] = FATTR4_WORD1_MODE
  462. -        | FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_TIME_ACCESS
  463. -        | FATTR4_WORD1_TIME_CREATE | FATTR4_WORD1_TIME_MODIFY
  464. -        | FATTR4_WORD1_SYSTEM;
  465.      if (dst->owner)
  466.          dst->attrmask.arr[1] |= FATTR4_WORD1_OWNER;
  467.      if (dst->owner_group)
  468. diff --git a/daemon/nfs41_xdr.c b/daemon/nfs41_xdr.c
  469. index 90f0e61..1b0abf1 100644
  470. --- a/daemon/nfs41_xdr.c
  471. +++ b/daemon/nfs41_xdr.c
  472. @@ -2344,6 +2344,7 @@ static bool_t decode_readdir_entry(
  473.          xdrmem_create(&fattr_xdr, (char *)attrs.attr_vals, attrs.attr_vals_len, XDR_DECODE);
  474.          if (!(decode_file_attrs(&fattr_xdr, &attrs, &entry->attr_info)))
  475.              entry->attr_info.rdattr_error = NFS4ERR_BADXDR;
  476. +        (void)memcpy(&entry->attr_info.attrmask, &attrs.attrmask, sizeof(bitmap4));
  477.          StringCchCopyA(entry->name, name_len, (STRSAFE_LPCSTR)name);
  478.  
  479.          it->buf_pos += (size_t)entry_len + name_len;
  480. diff --git a/daemon/open.c b/daemon/open.c
  481. index 15c9c28..b9739da 100644
  482. --- a/daemon/open.c
  483. +++ b/daemon/open.c
  484. @@ -745,7 +745,7 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  485.              status = map_symlink_errors(status);
  486.              goto out_free_state;
  487.          }
  488. -        nfs_to_basic_info(&info, &args->basic_info);
  489. +        nfs_to_basic_info(state->file.name.name, &info, &args->basic_info);
  490.          nfs_to_standard_info(&info, &args->std_info);
  491.          args->mode = info.mode;
  492.          args->changeattr = info.change;
  493. @@ -756,7 +756,7 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  494.              goto out_free_state;
  495.          }
  496.  
  497. -        nfs_to_basic_info(&info, &args->basic_info);
  498. +        nfs_to_basic_info(state->file.name.name, &info, &args->basic_info);
  499.          nfs_to_standard_info(&info, &args->std_info);
  500.          args->mode = info.mode;
  501.          args->changeattr = info.change;
  502. @@ -941,7 +941,7 @@ supersede_retry:
  503.              status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
  504.              goto out_free_state;
  505.          } else {
  506. -            nfs_to_basic_info(&info, &args->basic_info);
  507. +            nfs_to_basic_info(state->file.name.name, &info, &args->basic_info);
  508.              nfs_to_standard_info(&info, &args->std_info);
  509.              args->mode = info.mode;
  510.              args->changeattr = info.change;
  511. diff --git a/daemon/readdir.c b/daemon/readdir.c
  512. index 07607ef..31d7047 100644
  513. --- a/daemon/readdir.c
  514. +++ b/daemon/readdir.c
  515. @@ -3,6 +3,7 @@
  516.   *
  517.   * Olga Kornievskaia <aglo@umich.edu>
  518.   * Casey Bodley <cbodley@umich.edu>
  519. + * Roland Mainz <roland.mainz@nrubsig.org>
  520.   *
  521.   * This library is free software; you can redistribute it and/or modify it
  522.   * under the terms of the GNU Lesser General Public License as published by
  523. @@ -323,15 +324,50 @@ static void readdir_copy_dir_info(
  524.      IN PFILE_DIR_INFO_UNION info)
  525.  {
  526.      info->fdi.FileIndex = (ULONG)entry->attr_info.fileid;
  527. -    nfs_time_to_file_time(&entry->attr_info.time_create,
  528. -        &info->fdi.CreationTime);
  529. -    nfs_time_to_file_time(&entry->attr_info.time_access,
  530. -        &info->fdi.LastAccessTime);
  531. -    nfs_time_to_file_time(&entry->attr_info.time_modify,
  532. -        &info->fdi.LastWriteTime);
  533. +
  534. +    uint32_t attrmask_arr1 = entry->attr_info.attrmask.arr[1];
  535. +
  536. +    if (attrmask_arr1 & FATTR4_WORD1_TIME_CREATE) {
  537. +        nfs_time_to_file_time(&entry->attr_info.time_create,
  538. +            &info->fdi.CreationTime);
  539. +    }
  540. +    else {
  541. +        DPRINTF(1, ("readdir_copy_dir_info(entry->name='%s'): "
  542. +            "time_create not set\n", entry->name));
  543. +        info->fdi.CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  544. +    }
  545. +
  546. +    if (attrmask_arr1 & FATTR4_WORD1_TIME_ACCESS) {
  547. +        nfs_time_to_file_time(&entry->attr_info.time_access,
  548. +            &info->fdi.LastAccessTime);
  549. +    }
  550. +    else {
  551. +        DPRINTF(1, ("readdir_copy_dir_info(entry->name='%s'): "
  552. +            "time_access not set\n", entry->name));
  553. +        info->fdi.LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  554. +    }
  555. +
  556. +    if (attrmask_arr1 & FATTR4_WORD1_TIME_MODIFY) {
  557. +        nfs_time_to_file_time(&entry->attr_info.time_modify,
  558. +            &info->fdi.LastWriteTime);
  559. +    }
  560. +    else {
  561. +        DPRINTF(1, ("readdir_copy_dir_info(entry->name='%s'): "
  562. +            "time_modify not set\n", entry->name));
  563. +        info->fdi.LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  564. +    }
  565. +
  566.      /* XXX: was using 'change' attr, but that wasn't giving a time */
  567. -    nfs_time_to_file_time(&entry->attr_info.time_modify,
  568. -        &info->fdi.ChangeTime);
  569. +    if (attrmask_arr1 & FATTR4_WORD1_TIME_MODIFY) {
  570. +        nfs_time_to_file_time(&entry->attr_info.time_modify,
  571. +            &info->fdi.ChangeTime);
  572. +    }
  573. +    else {
  574. +        DPRINTF(1, ("readdir_copy_dir_info(entry->name='%s'): "
  575. +            "time_modify2 not set\n", entry->name));
  576. +        info->fdi.ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  577. +    }
  578. +
  579.      info->fdi.EndOfFile.QuadPart =
  580.          info->fdi.AllocationSize.QuadPart =
  581.              entry->attr_info.size;
  582. diff --git a/daemon/util.c b/daemon/util.c
  583. index 382944a..2c78e9e 100644
  584. --- a/daemon/util.c
  585. +++ b/daemon/util.c
  586. @@ -164,14 +164,47 @@ ULONG nfs_file_info_to_attributes(
  587.  }
  588.  
  589.  void nfs_to_basic_info(
  590. +    IN const char *name,
  591.      IN const nfs41_file_info *info,
  592.      OUT PFILE_BASIC_INFO basic_out)
  593.  {
  594. -    nfs_time_to_file_time(&info->time_create, &basic_out->CreationTime);
  595. -    nfs_time_to_file_time(&info->time_access, &basic_out->LastAccessTime);
  596. -    nfs_time_to_file_time(&info->time_modify, &basic_out->LastWriteTime);
  597. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  598. +        nfs_time_to_file_time(&info->time_create, &basic_out->CreationTime);
  599. +    }
  600. +    else {
  601. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  602. +            "time_create not set\n", name));
  603. +        basic_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  604. +    }
  605. +
  606. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  607. +        nfs_time_to_file_time(&info->time_access, &basic_out->LastAccessTime);
  608. +    }
  609. +    else {
  610. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  611. +            "time_access not set\n", name));
  612. +        basic_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  613. +    }
  614. +
  615. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  616. +        nfs_time_to_file_time(&info->time_modify, &basic_out->LastWriteTime);
  617. +    }
  618. +    else {
  619. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  620. +            "time_modify not set\n", name));
  621. +        basic_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  622. +    }
  623. +
  624.      /* XXX: was using 'change' attr, but that wasn't giving a time */
  625. -    nfs_time_to_file_time(&info->time_modify, &basic_out->ChangeTime);
  626. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  627. +        nfs_time_to_file_time(&info->time_modify, &basic_out->ChangeTime);
  628. +    }
  629. +    else {
  630. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  631. +            "time_modify2 not set\n", name));
  632. +        basic_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  633. +    }
  634. +
  635.      basic_out->FileAttributes = nfs_file_info_to_attributes(info);
  636.  }
  637.  
  638. @@ -190,15 +223,47 @@ void nfs_to_standard_info(
  639.  }
  640.  
  641.  void nfs_to_network_openinfo(
  642. +    IN const char *name,
  643.      IN const nfs41_file_info *info,
  644.      OUT PFILE_NETWORK_OPEN_INFORMATION net_out)
  645.  {
  646. -    
  647. -    nfs_time_to_file_time(&info->time_create, &net_out->CreationTime);
  648. -    nfs_time_to_file_time(&info->time_access, &net_out->LastAccessTime);
  649. -    nfs_time_to_file_time(&info->time_modify, &net_out->LastWriteTime);
  650. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  651. +        nfs_time_to_file_time(&info->time_create, &net_out->CreationTime);
  652. +    }
  653. +    else {
  654. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  655. +            "time_create not set\n", name));
  656. +        net_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  657. +    }
  658. +
  659. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  660. +        nfs_time_to_file_time(&info->time_access, &net_out->LastAccessTime);
  661. +    }
  662. +    else {
  663. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  664. +            "time_access not set\n", name));
  665. +        net_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  666. +    }
  667. +
  668. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  669. +        nfs_time_to_file_time(&info->time_modify, &net_out->LastWriteTime);
  670. +    }
  671. +    else {
  672. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  673. +            "time_modify not set\n", name));
  674. +        net_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  675. +    }
  676. +
  677.      /* XXX: was using 'change' attr, but that wasn't giving a time */
  678. -    nfs_time_to_file_time(&info->time_modify, &net_out->ChangeTime);
  679. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  680. +        nfs_time_to_file_time(&info->time_modify, &net_out->ChangeTime);
  681. +    }
  682. +    else {
  683. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  684. +            "time_modify2 not set\n", name));
  685. +        net_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  686. +    }
  687. +
  688.      net_out->AllocationSize.QuadPart =
  689.          net_out->EndOfFile.QuadPart = (LONGLONG)info->size;
  690.      net_out->FileAttributes = nfs_file_info_to_attributes(info);
  691. diff --git a/daemon/util.h b/daemon/util.h
  692. index bc12f55..d54f9dd 100644
  693. --- a/daemon/util.h
  694. +++ b/daemon/util.h
  695. @@ -3,6 +3,7 @@
  696.   *
  697.   * Olga Kornievskaia <aglo@umich.edu>
  698.   * Casey Bodley <cbodley@umich.edu>
  699. + * Roland Mainz <roland.mainz@nrubsig.org>
  700.   *
  701.   * This library is free software; you can redistribute it and/or modify it
  702.   * under the terms of the GNU Lesser General Public License as published by
  703. @@ -32,6 +33,14 @@ struct __nfs41_session;
  704.  struct __nfs41_write_verf;
  705.  enum stable_how4;
  706.  
  707. +/*
  708. + * LargeInteger.QuadPart value to indicate a time value was not
  709. + * available
  710. + *
  711. + * gisburn: FIXME: We need a better header for this
  712. + */
  713. +#define FILE_INFO_TIME_NOT_SET (0LL)
  714. +
  715.  int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
  716.  int safe_write(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
  717.  int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name);
  718. @@ -100,12 +109,14 @@ static __inline void bitmap_intersect(
  719.  ULONG nfs_file_info_to_attributes(
  720.      IN const nfs41_file_info *info);
  721.  void nfs_to_basic_info(
  722. +    IN const char *name,
  723.      IN const nfs41_file_info *info,
  724.      OUT PFILE_BASIC_INFO basic_out);
  725.  void nfs_to_standard_info(
  726.      IN const nfs41_file_info *info,
  727.      OUT PFILE_STANDARD_INFO std_out);
  728.  void nfs_to_network_openinfo(
  729. +    IN const char *name,
  730.      IN const nfs41_file_info *info,
  731.      OUT PFILE_NETWORK_OPEN_INFORMATION std_out);
  732.  void nfs41_file_info_cpy(
  733. --
  734. 2.43.0
  735.  
  736. From 0b159cd52bd379354caccbe368def82625eca16e Mon Sep 17 00:00:00 2001
  737. From: Roland Mainz <roland.mainz@nrubsig.org>
  738. Date: Sat, 13 Apr 2024 14:18:19 +0200
  739. Subject: [PATCH 3/3] daemon: name cache should print number of entries on
  740.  creation
  741.  
  742. |nfs41_name_cache_create()| should print the number of name cache
  743. entries on creation.
  744.  
  745. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  746. ---
  747. daemon/name_cache.c | 3 ++-
  748.  1 file changed, 2 insertions(+), 1 deletion(-)
  749.  
  750. diff --git a/daemon/name_cache.c b/daemon/name_cache.c
  751. index 284fc2f..acf4604 100644
  752. --- a/daemon/name_cache.c
  753. +++ b/daemon/name_cache.c
  754. @@ -798,7 +798,8 @@ int nfs41_name_cache_create(
  755.      struct nfs41_name_cache *cache;
  756.      int status = NO_ERROR;
  757.  
  758. -    DPRINTF(NCLVL1, ("nfs41_name_cache_create()\n"));
  759. +    DPRINTF(NCLVL1, ("nfs41_name_cache_create() with %ld entries\n",
  760. +        (long)NAME_CACHE_MAX_ENTRIES));
  761.  
  762.      /* allocate the cache */
  763.      cache = calloc(1, sizeof(struct nfs41_name_cache));
  764. --
  765. 2.43.0

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