pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Patches for UseGetTickCount64() for caches, nfs_mount EPERM propagation, allocationsize-vs-eofpos+misc, 2024-06-01
Posted by Anonymous on Sat 1st Jun 2024 15:10
raw | new post

  1. From 4adb0047011adf9d7baa987a2920f2152b0196f5 Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Sat, 1 Jun 2024 12:42:29 +0200
  4. Subject: [PATCH 1/4] daemon: Use |GetTickCount64()| for cache expiration
  5.  
  6. Switch over cache expiration calculations from |time()| to
  7. |GetTickCount64()|, as it is almost twice as fast.
  8.  
  9. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  10. ---
  11. daemon/idmap.c      | 17 ++++++++---------
  12.  daemon/name_cache.c | 13 ++++++-------
  13.  daemon/sid.c        | 14 +++++++-------
  14.  daemon/util.h       | 14 ++++++++++++++
  15.  4 files changed, 35 insertions(+), 23 deletions(-)
  16.  
  17. diff --git a/daemon/idmap.c b/daemon/idmap.c
  18. index 5745b7a..d7bf794 100644
  19. --- a/daemon/idmap.c
  20. +++ b/daemon/idmap.c
  21. @@ -25,7 +25,6 @@
  22.  #include <Winldap.h>
  23.  #include <stdlib.h> /* for strtoul() */
  24.  #include <errno.h>
  25. -#include <time.h>
  26.  
  27.  #include "nfs41_build_features.h"
  28.  #include "idmap.h"
  29. @@ -481,7 +480,7 @@ struct idmap_user {
  30.      char principal[VAL_LEN];
  31.      uid_t uid;
  32.      gid_t gid;
  33. -    time_t last_updated;
  34. +    util_reltimestamp last_updated;
  35.  };
  36.  
  37.  static struct list_entry* user_cache_alloc()
  38. @@ -517,7 +516,7 @@ struct idmap_group {
  39.      struct list_entry entry;
  40.      char name[VAL_LEN];
  41.      gid_t gid;
  42. -    time_t last_updated;
  43. +    util_reltimestamp last_updated;
  44.  };
  45.  
  46.  static struct list_entry* group_cache_alloc()
  47. @@ -676,7 +675,7 @@ static int idmap_lookup_user(
  48.      if (status == NO_ERROR) {
  49.          /* don't return expired entries; query new attributes
  50.           * and overwrite the entry with cache_insert() */
  51. -        if (difftime(time(NULL), user->last_updated) < (double)context->config.cache_ttl)
  52. +        if (UTIL_DIFFRELTIME(UTIL_GETRELTIME(), user->last_updated) < context->config.cache_ttl)
  53.              goto out;
  54.      }
  55.  #ifndef NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN
  56. @@ -715,7 +714,7 @@ static int idmap_lookup_user(
  57.          status = ERROR_INVALID_PARAMETER;
  58.          goto out_free_values;
  59.      }
  60. -    user->last_updated = time(NULL);
  61. +    user->last_updated = UTIL_GETRELTIME();
  62.  #else
  63.      if (lookup->attr == ATTR_USER_NAME) {
  64.          char principal_name[VAL_LEN];
  65. @@ -801,7 +800,7 @@ static int idmap_lookup_user(
  66.      }
  67.  
  68.      if (status == 0) {
  69. -        user->last_updated = time(NULL);
  70. +        user->last_updated = UTIL_GETRELTIME();
  71.          DPRINTF(CYGWINIDLVL, ("## idmap_lookup_user: "
  72.              "found username='%s', principal='%s', uid=%u, gid=%u\n",
  73.              user->username,
  74. @@ -840,7 +839,7 @@ static int idmap_lookup_group(
  75.      if (status == NO_ERROR) {
  76.          /* don't return expired entries; query new attributes
  77.           * and overwrite the entry with cache_insert() */
  78. -        if (difftime(time(NULL), group->last_updated) < (double)context->config.cache_ttl)
  79. +        if (UTIL_DIFFRELTIME(UTIL_GETRELTIME(), group->last_updated) < context->config.cache_ttl)
  80.              goto out;
  81.      }
  82.  #ifndef NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN
  83. @@ -865,7 +864,7 @@ static int idmap_lookup_group(
  84.          status = ERROR_INVALID_PARAMETER;
  85.          goto out_free_values;
  86.      }
  87. -    group->last_updated = time(NULL);
  88. +    group->last_updated = UTIL_GETRELTIME();
  89.  #else
  90.      if (lookup->attr == ATTR_GROUP_NAME) {
  91.          gid_t cy_gid = 0;
  92. @@ -908,7 +907,7 @@ static int idmap_lookup_group(
  93.      }
  94.  
  95.      if (status == 0) {
  96. -        group->last_updated = time(NULL);
  97. +        group->last_updated = UTIL_GETRELTIME();
  98.          DPRINTF(CYGWINIDLVL,
  99.              ("## idmap_lookup_group: found name='%s', gid=%u\n",
  100.              group->name,
  101. diff --git a/daemon/name_cache.c b/daemon/name_cache.c
  102. index f082edb..aa77d57 100644
  103. --- a/daemon/name_cache.c
  104. +++ b/daemon/name_cache.c
  105. @@ -75,7 +75,6 @@ static __inline bool_t is_delegation(
  106.      return type == OPEN_DELEGATE_READ || type == OPEN_DELEGATE_WRITE;
  107.  }
  108.  
  109. -
  110.  /* attribute cache */
  111.  struct attr_cache_entry {
  112.      RB_ENTRY(attr_cache_entry) rbnode;
  113. @@ -94,7 +93,7 @@ struct attr_cache_entry {
  114.      unsigned                hidden : 1;
  115.      unsigned                system : 1;
  116.      unsigned                archive : 1;
  117. -    time_t                  expiration;
  118. +    util_reltimestamp       expiration;
  119.      unsigned                ref_count : 26;
  120.      unsigned                type : 4;
  121.      unsigned                invalidated : 1;
  122. @@ -181,7 +180,7 @@ static __inline int attr_cache_entry_expired(
  123.      IN const struct attr_cache_entry *entry)
  124.  {
  125.      return entry->invalidated ||
  126. -        (!entry->delegated && time(NULL) > entry->expiration);
  127. +        ((!entry->delegated) && (UTIL_GETRELTIME() > entry->expiration));
  128.  }
  129.  
  130.  /* attr_cache */
  131. @@ -294,7 +293,7 @@ static void attr_cache_update(
  132.              entry->change = info->change;
  133.              /* revalidate whenever we get a change attribute */
  134.              entry->invalidated = 0;
  135. -            entry->expiration = time(NULL) + NAME_CACHE_EXPIRATION;
  136. +            entry->expiration = UTIL_GETRELTIME() + NAME_CACHE_EXPIRATION;
  137.          }
  138.          if (info->attrmask.arr[0] & FATTR4_WORD0_SIZE)
  139.              entry->size = info->size;
  140. @@ -408,7 +407,7 @@ struct name_cache_entry {
  141.      struct attr_cache_entry *attributes;
  142.      struct name_cache_entry *parent;
  143.      struct list_entry       exp_entry;
  144. -    time_t                  expiration;
  145. +    util_reltimestamp         expiration;
  146.      unsigned short          component_len;
  147.  };
  148.  #define NAME_ENTRY_SIZE sizeof(struct name_cache_entry)
  149. @@ -553,7 +552,7 @@ static void name_cache_entry_updated(
  150.      IN struct name_cache_entry *entry)
  151.  {
  152.      /* update the expiration timer */
  153. -    entry->expiration = time(NULL) + cache->expiration;
  154. +    entry->expiration = UTIL_GETRELTIME() + cache->expiration;
  155.      name_cache_entry_accessed(cache, entry);
  156.  }
  157.  
  158. @@ -669,7 +668,7 @@ static int entry_invis(
  159.      OUT OPTIONAL bool_t *is_negative)
  160.  {
  161.      /* name entry timer expired? */
  162. -    if (!list_empty(&entry->exp_entry) && time(NULL) > entry->expiration) {
  163. +    if (!list_empty(&entry->exp_entry) && (UTIL_GETRELTIME() > entry->expiration)) {
  164.          DPRINTF(NCLVL2, ("name_entry_expired('%s')\n", entry->component));
  165.          return 1;
  166.      }
  167. diff --git a/daemon/sid.c b/daemon/sid.c
  168. index c0a04cc..2a63763 100644
  169. --- a/daemon/sid.c
  170. +++ b/daemon/sid.c
  171. @@ -233,7 +233,7 @@ typedef struct _sidcache_entry
  172.  #pragma warning (disable : 4324)
  173.      DECLARE_SID_BUFFER(sid_buffer);
  174.  #pragma warning( pop )
  175. -    time_t  timestamp;
  176. +    util_reltimestamp  timestamp;
  177.  } sidcache_entry;
  178.  
  179.  typedef struct _sidcache
  180. @@ -259,12 +259,12 @@ void sidcache_add(sidcache *cache, const char* win32name, PSID value)
  181.  {
  182.      int i;
  183.      ssize_t freeEntryIndex;
  184. -    time_t currentTimestamp;
  185. +    util_reltimestamp currentTimestamp;
  186.  
  187.      EASSERT(win32name[0] != '\0');
  188.  
  189.      EnterCriticalSection(&cache->lock);
  190. -    currentTimestamp = time(NULL);
  191. +    currentTimestamp = UTIL_GETRELTIME();
  192.  
  193.      /* purge obsolete entries */
  194.      for (i = 0; i < SIDCACHE_SIZE; i++) {
  195. @@ -326,12 +326,12 @@ done:
  196.  PSID *sidcache_getcached_byname(sidcache *cache, const char *win32name)
  197.  {
  198.      int i;
  199. -    time_t currentTimestamp;
  200. +    util_reltimestamp currentTimestamp;
  201.      sidcache_entry *e;
  202.      PSID *ret_sid = NULL;
  203.  
  204.      EnterCriticalSection(&cache->lock);
  205. -    currentTimestamp = time(NULL);
  206. +    currentTimestamp = UTIL_GETRELTIME();
  207.  
  208.      for (i = 0; i < SIDCACHE_SIZE; i++) {
  209.          e = &cache->entries[i];
  210. @@ -361,12 +361,12 @@ done:
  211.  bool sidcache_getcached_bysid(sidcache *cache, PSID sid, char *out_win32name)
  212.  {
  213.      int i;
  214. -    time_t currentTimestamp;
  215. +    util_reltimestamp currentTimestamp;
  216.      sidcache_entry *e;
  217.      bool ret = false;
  218.  
  219.      EnterCriticalSection(&cache->lock);
  220. -    currentTimestamp = time(NULL);
  221. +    currentTimestamp = UTIL_GETRELTIME();
  222.  
  223.      for (i = 0; i < SIDCACHE_SIZE; i++) {
  224.          e = &cache->entries[i];
  225. diff --git a/daemon/util.h b/daemon/util.h
  226. index 99e2dd9..e350cf8 100644
  227. --- a/daemon/util.h
  228. +++ b/daemon/util.h
  229. @@ -34,6 +34,20 @@ struct __nfs41_session;
  230.  struct __nfs41_write_verf;
  231.  enum stable_how4;
  232.  
  233. +/*
  234. + * UTIL_GETRELTIME - Get a relative time stamp
  235. + * |GetTickCount64()| is almost twice as fast as |time()|, and
  236. + * cache code only needs a relative timestamp and not the
  237. + * absolute time to implement cache element expiration.
  238. + * |GetTickCount64()| also includes time spend in hibernation&co.,
  239. + * so hibernation longer than |NAME_CACHE_EXPIRATION| will
  240. + * automagically invalidate the cache
  241. + */
  242. +#define UTIL_GETRELTIME() (GetTickCount64()/1000UL)
  243. +#define UTIL_DIFFRELTIME(t1, t2) \
  244. +    (((signed long long)(t1))-((signed long long)(t2)))
  245. +typedef ULONGLONG util_reltimestamp;
  246. +
  247.  /*
  248.   * LargeInteger.QuadPart value to indicate a time value was not
  249.   * available
  250. --
  251. 2.43.0
  252.  
  253. From 217f69a917799a5c0fbe959388f71c8901b37cae Mon Sep 17 00:00:00 2001
  254. From: Roland Mainz <roland.mainz@nrubsig.org>
  255. Date: Sat, 1 Jun 2024 13:05:47 +0200
  256. Subject: [PATCH 2/4] sys: Add debug output to |nfs41_Flush()|
  257.  
  258. Add debug output to |nfs41_Flush()|
  259.  
  260. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  261. ---
  262. sys/nfs41_driver.c | 3 +++
  263.  1 file changed, 3 insertions(+)
  264.  
  265. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  266. index 729eb25..fa347d4 100644
  267. --- a/sys/nfs41_driver.c
  268. +++ b/sys/nfs41_driver.c
  269. @@ -4412,6 +4412,9 @@ out:
  270.  NTSTATUS nfs41_Flush(
  271.      IN OUT PRX_CONTEXT RxContext)
  272.  {
  273. +    DbgP("nfs41_Flush: FileName='%wZ'\n",
  274. +        GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext));
  275. +
  276.      return STATUS_SUCCESS;
  277.  }
  278.  
  279. --
  280. 2.43.0
  281.  
  282. From 3bf222ee6c799108e3ef62138eba627c143bddac Mon Sep 17 00:00:00 2001
  283. From: Roland Mainz <roland.mainz@nrubsig.org>
  284. Date: Sat, 1 Jun 2024 13:26:24 +0200
  285. Subject: [PATCH 3/4] sys: nfs_mount should return |ERROR_ACCESS_DENIED| for
  286.  NFSv4 |EPERM|
  287.  
  288. nfs_mount.exe returns |ERROR_NO_SYSTEM_RESOURCES|(=1450) for NFSv4
  289. |EPERM| instead of the |expected ERROR_ACCESS_DENIED|(=5).
  290.  
  291. Encountered while trying to mount a NFSv4.1 share through NAT
  292. when the server didn't export that filesystem with the "insecure"
  293. export option.
  294.  
  295. Fix is to map |ERROR_ACCESS_DENIED| (returned by nfsd.exe)
  296. in nfs41_driver.sys's |map_mount_errors()| to
  297. |STATUS_ACCESS_DENIED|, which Win32 will then turn into
  298. |ERROR_ACCESS_DENIED| again.
  299.  
  300. Reported-by: Josh Hurst <joshhurst@gmail.com>
  301. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  302. ---
  303. sys/nfs41_driver.c | 1 +
  304.  1 file changed, 1 insertion(+)
  305.  
  306. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  307. index fa347d4..2f4b912 100644
  308. --- a/sys/nfs41_driver.c
  309. +++ b/sys/nfs41_driver.c
  310. @@ -2757,6 +2757,7 @@ NTSTATUS map_mount_errors(
  311.  {
  312.      switch (status) {
  313.      case NO_ERROR:              return STATUS_SUCCESS;
  314. +    case ERROR_ACCESS_DENIED:   return STATUS_ACCESS_DENIED;
  315.      case ERROR_NETWORK_UNREACHABLE: return STATUS_NETWORK_UNREACHABLE;
  316.      case ERROR_BAD_NET_RESP:    return STATUS_UNEXPECTED_NETWORK_ERROR;
  317.      case ERROR_BAD_NET_NAME:    return STATUS_BAD_NETWORK_NAME;
  318. --
  319. 2.43.0
  320.  
  321. From fd18f1aa0a64b4f4b512b57c77fd923b420a8a7d Mon Sep 17 00:00:00 2001
  322. From: Roland Mainz <roland.mainz@nrubsig.org>
  323. Date: Sat, 1 Jun 2024 15:47:53 +0200
  324. Subject: [PATCH 4/4] sys: |nfs41_fcb->...EndOfFile| should always <=
  325.  |nfs41_fcb->...AllocationSize|
  326.  
  327. |nfs41_fcb->StandardInfo.EndOfFile.QuadPart| should always be smaller
  328. or equal to |nfs41_fcb->StandardInfo.AllocationSize|
  329.  
  330. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  331. ---
  332. sys/nfs41_driver.c | 27 ++++++++++++++++++---------
  333.  1 file changed, 18 insertions(+), 9 deletions(-)
  334.  
  335. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  336. index 2f4b912..b82de23 100644
  337. --- a/sys/nfs41_driver.c
  338. +++ b/sys/nfs41_driver.c
  339. @@ -5942,19 +5942,28 @@ NTSTATUS nfs41_SetFileInformation(
  340.              goto out;
  341.          }
  342.      case FileAllocationInformation:
  343. -        /*
  344. -         * Fixme: What is the correct way to handle
  345. -         * |FileAllocationInformation| ? NFSv4 does not have the
  346. -         * concept of a difference between "allocation size" and
  347. -         * "end-of-file" position
  348. -         */
  349. -        break;
  350. +        {
  351. +            PFILE_ALLOCATION_INFORMATION info =
  352. +                (PFILE_ALLOCATION_INFORMATION)RxContext->Info.Buffer;
  353. +
  354. +            nfs41_fcb->StandardInfo.AllocationSize.QuadPart = info->AllocationSize.QuadPart;
  355. +            if (nfs41_fcb->StandardInfo.EndOfFile.QuadPart > info->AllocationSize.QuadPart) {
  356. +                nfs41_fcb->StandardInfo.EndOfFile.QuadPart = info->AllocationSize.QuadPart;
  357. +            }
  358. +            break;
  359. +        }
  360.      case FileEndOfFileInformation:
  361.          {
  362.              PFILE_END_OF_FILE_INFORMATION info =
  363.                  (PFILE_END_OF_FILE_INFORMATION)RxContext->Info.Buffer;
  364. -            nfs41_fcb->StandardInfo.AllocationSize =
  365. -                nfs41_fcb->StandardInfo.EndOfFile = info->EndOfFile;
  366. +
  367. +            if (info->EndOfFile.QuadPart > nfs41_fcb->StandardInfo.AllocationSize.QuadPart) {
  368. +                nfs41_fcb->StandardInfo.AllocationSize.QuadPart =
  369. +                    nfs41_fcb->StandardInfo.EndOfFile.QuadPart = info->EndOfFile.QuadPart;
  370. +            }
  371. +            else {
  372. +                nfs41_fcb->StandardInfo.EndOfFile.QuadPart = info->EndOfFile.QuadPart;
  373. +            }
  374.              break;
  375.          }
  376.      case FileRenameInformation:
  377. --
  378. 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