Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libnfs for openSUSE:Factory checked 
in at 2022-08-19 17:53:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libnfs (Old)
 and      /work/SRC/openSUSE:Factory/.libnfs.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libnfs"

Fri Aug 19 17:53:10 2022 rev:9 rq:997685 version:5.0.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/libnfs/libnfs.changes    2022-05-17 
17:23:50.619138837 +0200
+++ /work/SRC/openSUSE:Factory/.libnfs.new.2083/libnfs.changes  2022-08-19 
17:54:14.163818378 +0200
@@ -1,0 +2,10 @@
+Wed Aug 17 19:03:56 UTC 2022 - Dirk M??ller <[email protected]>
+
+- update to 5.0.2:
+  * Various small multithreading fixes
+  * Add opaque pointer to service_proc to make it easier to build server apps.
+  * BSD compile fix
+  * OpenBSD support
+  * fix double free in nfs3_pread_mcb() 
+
+-------------------------------------------------------------------

Old:
----
  libnfs-5.0.1.tar.gz

New:
----
  libnfs-5.0.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libnfs.spec ++++++
--- /var/tmp/diff_new_pack.8LASpo/_old  2022-08-19 17:54:14.835819788 +0200
+++ /var/tmp/diff_new_pack.8LASpo/_new  2022-08-19 17:54:14.843819804 +0200
@@ -18,16 +18,14 @@
 
 
 %define sover   14
-
 Name:           libnfs
-Version:        5.0.1
+Version:        5.0.2
 Release:        0
 Summary:        Client library for accessing NFS shares over a network
 License:        BSD-2-Clause AND LGPL-2.1-or-later AND GPL-3.0-or-later
 Group:          Productivity/Networking/NFS
 URL:            https://github.com/sahlberg/libnfs
 Source0:        %{url}/archive/libnfs-%{version}.tar.gz
-
 BuildRequires:  autoconf
 BuildRequires:  libtool
 BuildRequires:  pkgconfig

++++++ libnfs-5.0.1.tar.gz -> libnfs-5.0.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/.github/workflows/build.yml 
new/libnfs-libnfs-5.0.2/.github/workflows/build.yml
--- old/libnfs-libnfs-5.0.1/.github/workflows/build.yml 1970-01-01 
01:00:00.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/.github/workflows/build.yml 2022-08-10 
05:59:10.000000000 +0200
@@ -0,0 +1,95 @@
+on:
+  push:
+  pull_request:
+  workflow_dispatch:
+
+jobs:
+  Linux:
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@main
+      - run: sudo apt install -y cmake
+      - run: mkdir build
+      - run: cmake -B build
+      - run: make --directory build
+      - run: sudo make --directory build install
+
+  Linux-Musl-QEMU:
+    runs-on: ubuntu-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        platform:
+          - i386
+          - s390x   # Test big-endian
+          - arm32v6
+          - arm32v7
+
+    steps:
+      - uses: actions/checkout@main
+      - name: Get the qemu container
+        run: docker run --rm --privileged multiarch/qemu-user-static --reset 
-p yes
+      - name: ${{ matrix.platform }}
+        run: docker run --rm --interactive --mount 
type=bind,source=$(pwd),target=/host ${{ matrix.platform }}/alpine sh -c "apk 
add cmake make gcc libc-dev git; cp -r /host from-host; cd from-host; mkdir 
build; cmake -B build; make --directory build install"
+
+  macOS:
+    runs-on: macos-latest
+
+    steps:
+      - uses: actions/checkout@main
+      - run: brew install cmake
+      - run: mkdir build
+      - run: cmake -B build
+      - run: make --directory build install
+
+  BSDs:
+    runs-on: macos-latest
+
+    strategy:
+      matrix:
+        os:
+          - name: FreeBSD
+            version: '13.0'
+            pkginstall: pkg install -y cmake
+
+          - name: OpenBSD
+            version: 6.9
+            pkginstall: pkg_add cmake
+
+    name: ${{ matrix.os.name }} ${{ matrix.os.version }}
+
+    steps:
+      - uses: actions/checkout@main
+
+      - name: Test on ${{ matrix.os.name }}
+        uses: cross-platform-actions/[email protected]
+        with:
+          operating_system: ${{ matrix.os.name }}
+          version: ${{ matrix.os.version }}
+          shell: bash
+          run: |
+            sudo ${{ matrix.os.pkginstall }}
+            mkdir build
+            cmake -B build
+            cd build
+            make
+            sudo make install
+
+  Cygwin:
+    runs-on: windows-latest
+
+    steps:
+      - name: Set up Cygwin
+        uses: egor-tensin/setup-cygwin@v3
+        with:
+            platform: x64
+            packages: make gcc-g++ bash cmake
+      - uses: actions/checkout@main
+      - run: cd $GITHUB_WORKSPACE; mkdir build
+        shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o 
igncr '{0}'
+      - run: cd $GITHUB_WORKSPACE; cmake -B build
+        shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o 
igncr '{0}'
+      - run: cd $GITHUB_WORKSPACE; make --directory build install
+        shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o 
igncr '{0}'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/CHANGELOG 
new/libnfs-libnfs-5.0.2/CHANGELOG
--- old/libnfs-libnfs-5.0.1/CHANGELOG   2022-01-31 18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/CHANGELOG   2022-08-10 05:59:10.000000000 +0200
@@ -1,3 +1,10 @@
+Changes since 5.0.1
+Various small multithreading fixes
+Add opaque pointer to service_proc to make it easier to build server apps.
+BSD compile fix
+OpenBSD support
+fix double free in nfs3_pread_mcb()
+
 Changes since 5.0.0
 Fix non-pthread build
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/CMakeLists.txt 
new/libnfs-libnfs-5.0.2/CMakeLists.txt
--- old/libnfs-libnfs-5.0.1/CMakeLists.txt      2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/CMakeLists.txt      2022-08-10 05:59:10.000000000 
+0200
@@ -2,9 +2,9 @@
 
 project(libnfs
         LANGUAGES C
-        VERSION 5.0.1)
+        VERSION 5.0.2)
 
-set(SOVERSION 11.0.0 CACHE STRING "" FORCE)
+set(SOVERSION 11.1.0 CACHE STRING "" FORCE)
 
 set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation 
directory for libraries")
 set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation 
directory for headers")
@@ -116,6 +116,7 @@
 
 install(FILES mount/libnfs-raw-mount.h
               nfs/libnfs-raw-nfs.h
+              nfs4/libnfs-raw-nfs4.h
               nlm/libnfs-raw-nlm.h
               nsm/libnfs-raw-nsm.h
               portmap/libnfs-raw-portmap.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/cmake/Macros.cmake 
new/libnfs-libnfs-5.0.2/cmake/Macros.cmake
--- old/libnfs-libnfs-5.0.1/cmake/Macros.cmake  2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/cmake/Macros.cmake  2022-08-10 05:59:10.000000000 
+0200
@@ -12,4 +12,12 @@
   add_library(${name} OBJECT ${SOURCES} ${HEADERS})
   target_include_directories(${name} PUBLIC 
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
   set(CORE_LIBRARIES "${name};${CORE_LIBRARIES}" CACHE INTERNAL "")
+
+  # no need to install core libs if we build shared library
+  if(NOT BUILD_SHARED_LIBS)
+    install(TARGETS ${name} EXPORT libnfs
+            RUNTIME DESTINATION bin
+            ARCHIVE DESTINATION lib
+            LIBRARY DESTINATION lib)
+  endif()
 endfunction()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/configure.ac 
new/libnfs-libnfs-5.0.2/configure.ac
--- old/libnfs-libnfs-5.0.1/configure.ac        2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/configure.ac        2022-08-10 05:59:10.000000000 
+0200
@@ -1,5 +1,5 @@
 AC_PREREQ(2.50)
-AC_INIT([libnfs], [5.0.1], [[email protected]])
+AC_INIT([libnfs], [5.0.2], [[email protected]])
 AC_CONFIG_HEADERS([config.h])
 AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
 AC_CANONICAL_HOST
@@ -88,7 +88,7 @@
     AC_DEFINE(HAVE_MULTITHREADING,1,[Whether we have multithreading support])
 fi
 fi
-AM_CONDITIONAL([HAVE_PTHREAD], [test $libnfs_cv_HAVE_PTHREAD = yes])
+AM_CONDITIONAL([HAVE_PTHREAD], [test x$libnfs_cv_HAVE_PTHREAD = xyes])
 
 AC_MSG_CHECKING(whether SO_BINDTODEVICE is available)
 AC_TRY_COMPILE([#include <net/if.h>], [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/examples/nfs4-cat-talloc.c 
new/libnfs-libnfs-5.0.2/examples/nfs4-cat-talloc.c
--- old/libnfs-libnfs-5.0.1/examples/nfs4-cat-talloc.c  2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/examples/nfs4-cat-talloc.c  2022-08-10 
05:59:10.000000000 +0200
@@ -680,7 +680,7 @@
 /*
  * NULL procedure for the callback protocol.
  */
-static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque)
 {
         rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
 
@@ -691,7 +691,7 @@
  * CB_COMPOUND procedure for the callback protocol.
  * This is where the server will inform us about lease breaks and similar.
  */
-static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call, 
void *opaque)
 {
         CB_COMPOUND4args *args = call->body.cbody.args;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/examples/nfs4-cat.c 
new/libnfs-libnfs-5.0.2/examples/nfs4-cat.c
--- old/libnfs-libnfs-5.0.1/examples/nfs4-cat.c 2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/examples/nfs4-cat.c 2022-08-10 05:59:10.000000000 
+0200
@@ -682,7 +682,7 @@
 /*
  * NULL procedure for the callback protocol.
  */
-static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque)
 {
         rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
 
@@ -693,7 +693,7 @@
  * CB_COMPOUND procedure for the callback protocol.
  * This is where the server will inform us about lease breaks and similar.
  */
-static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call, 
void *opaque)
 {
         CB_COMPOUND4args *args = call->body.cbody.args;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/examples/portmap-server.c 
new/libnfs-libnfs-5.0.2/examples/portmap-server.c
--- old/libnfs-libnfs-5.0.1/examples/portmap-server.c   2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/examples/portmap-server.c   2022-08-10 
05:59:10.000000000 +0200
@@ -248,7 +248,7 @@
  * It is used by clients, and rpcinfo, to "ping" a service and verify that
  * the service is available and that it does support the indicated version.
  */
-static int pmap2_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int pmap2_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque)
 {
         rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
 
@@ -262,7 +262,7 @@
  * and portmapper returns which port that service is available on,
  * (or 0 if no such program is registered.)
  */
-static int pmap2_getport_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int pmap2_getport_proc(struct rpc_context *rpc, struct rpc_msg *call, 
void *opaque)
 {
         PMAP2GETPORTargs *args = call->body.cbody.args;
         struct mapping *tmp;
@@ -290,7 +290,7 @@
  * This RPC returns a list of all endpoints that are registered with
  * portmapper.
  */
-static int pmap2_dump_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int pmap2_dump_proc(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque)
 {
         PMAP2DUMPres reply;
         struct mapping *tmp;
@@ -336,7 +336,7 @@
  * v2 SET
  * This procedure is used to register and endpoint with portmapper.
  */
-static int pmap2_set_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int pmap2_set_proc(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque)
 {
         PMAP2GETPORTargs *args = call->body.cbody.args;
         char *prot;
@@ -369,7 +369,7 @@
  * This procedure is used to remove a registration from portmappers
  * list of endpoints.
  */
-static int pmap2_unset_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int pmap2_unset_proc(struct rpc_context *rpc, struct rpc_msg *call, 
void *opaque)
 {
         PMAP2GETPORTargs *args = call->body.cbody.args;
         char *prot;
@@ -424,7 +424,7 @@
  * It is used by clients, and rpcinfo, to "ping" a service and verify that
  * the service is available and that it does support the indicated version.
  */
-static int pmap3_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int pmap3_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque)
 {
         rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
 
@@ -436,7 +436,7 @@
  * This RPC returns a list of all endpoints that are registered with
  * portmapper.
  */
-static int pmap3_dump_proc(struct rpc_context *rpc, struct rpc_msg *call)
+static int pmap3_dump_proc(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque)
 {
         PMAP3DUMPres reply;
         struct mapping *tmp;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/include/libnfs-private.h 
new/libnfs-libnfs-5.0.2/include/libnfs-private.h
--- old/libnfs-libnfs-5.0.1/include/libnfs-private.h    2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/include/libnfs-private.h    2022-08-10 
05:59:10.000000000 +0200
@@ -133,6 +133,7 @@
        struct rpc_queue waitpdu[HASHES];
        uint32_t waitpdu_len;
 #ifdef HAVE_MULTITHREADING
+        int multithreading_enabled;
         libnfs_mutex_t rpc_mutex;
 #endif /* HAVE_MULTITHREADING */
 
@@ -312,10 +313,10 @@
        uint32_t open_counter;
        int has_lock_owner;
 #ifdef HAVE_MULTITHREADING
-       int multithreading_enabled;
        libnfs_thread_t service_thread;
        libnfs_mutex_t nfs_mutex;
-       libnfs_mutex_t nfs4_open_mutex;
+       libnfs_mutex_t nfs4_open_counter_mutex;
+       libnfs_mutex_t nfs4_open_call_mutex;
        struct nfs_thread_context *thread_ctx;
 #endif /* HAVE_MULTITHREADING */
 };
@@ -422,7 +423,7 @@
 
         /* NFSv4 */
         struct stateid stateid;
-        uint32_t lock_owner;
+        uint32_t open_owner;
         /* locking */
         uint32_t open_seqid;
         uint32_t lock_seqid;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/include/nfsc/libnfs-raw.h 
new/libnfs-libnfs-5.0.2/include/nfsc/libnfs-raw.h
--- old/libnfs-libnfs-5.0.1/include/nfsc/libnfs-raw.h   2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/include/nfsc/libnfs-raw.h   2022-08-10 
05:59:10.000000000 +0200
@@ -79,12 +79,13 @@
 EXTERN int rpc_queue_length(struct rpc_context *rpc);
 
 /*
- * Set which UID/GID to use in the authenticator.
+ * Set which UID/GIDs to use in the authenticator.
  * By default libnfs will use getuid()/getgid() where available
- * and 65534/65534 where not.
+ * and 65534/65534 where not, with no auxiliary GIDs.
  */
 EXTERN void rpc_set_uid(struct rpc_context *rpc, int uid);
 EXTERN void rpc_set_gid(struct rpc_context *rpc, int gid);
+EXTERN void rpc_set_auxiliary_gids(struct rpc_context *rpc, uint32_t len, 
uint32_t* gids);
 
 /*
  * Create a server context.
@@ -114,13 +115,14 @@
  * !0:  An abnormal error has occured. It is unrecoverable and the only
  *      meaningful action is to tear down the connection to the server.
  */
-typedef int (*service_fn)(struct rpc_context *rpc, struct rpc_msg *call);
+typedef int (*service_fn)(struct rpc_context *rpc, struct rpc_msg *call, void 
*opaque);
 
 struct service_proc {
         int proc;
         service_fn func;
         zdrproc_t decode_fn;
         int decode_buf_size;
+        void *opaque;
 };
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/include/nfsc/libnfs.h 
new/libnfs-libnfs-5.0.2/include/nfsc/libnfs.h
--- old/libnfs-libnfs-5.0.1/include/nfsc/libnfs.h       2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/include/nfsc/libnfs.h       2022-08-10 
05:59:10.000000000 +0200
@@ -29,7 +29,7 @@
 
 #include <stdint.h>
 #if defined(__ANDROID__) || defined(AROS) || defined(__PPU__) \
- || ( defined(__APPLE__) && defined(__MACH__) )
+ || ( defined(__APPLE__) && defined(__MACH__) ) || defined(__FreeBSD__) || 
defined(__OpenBSD__)
 #include <sys/time.h>
 #else
 #include <time.h>
@@ -214,7 +214,6 @@
  *                         times before failing and returing an error back
  *                         to the application.
  * version=<3|4>     : NFS version. Default is 3.
- *                     Version 4 is not yet functional. Do not use.
  * nfsport=<port>    : Use this port for NFS instead of using the portmapper.
  * mountport=<port>  : Use this port for the MOUNT protocol instead of
  *                     using portmapper. This argument is ignored for NFSv4
@@ -277,6 +276,7 @@
 EXTERN void nfs_set_tcp_syncnt(struct nfs_context *nfs, int v);
 EXTERN void nfs_set_uid(struct nfs_context *nfs, int uid);
 EXTERN void nfs_set_gid(struct nfs_context *nfs, int gid);
+EXTERN void nfs_set_auxiliary_gids(struct nfs_context *nfs, uint32_t len, 
uint32_t* gids);
 EXTERN void nfs_set_pagecache(struct nfs_context *nfs, uint32_t v);
 EXTERN void nfs_set_pagecache_ttl(struct nfs_context *nfs, uint32_t v);
 EXTERN void nfs_set_readahead(struct nfs_context *nfs, uint32_t v);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/init.c 
new/libnfs-libnfs-5.0.2/lib/init.c
--- old/libnfs-libnfs-5.0.1/lib/init.c  2022-01-31 18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/lib/init.c  2022-08-10 05:59:10.000000000 +0200
@@ -109,13 +109,17 @@
        rpc->gid = getgid();
 #endif
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        rpc_reset_queue(&rpc->outqueue);
        for (i = 0; i < HASHES; i++)
                rpc_reset_queue(&rpc->waitpdu[i]);
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 
        /* Default is no timeout */
@@ -260,13 +264,22 @@
        rpc_set_uid_gid(rpc, rpc->uid, gid);
 }
 
+void rpc_set_auxiliary_gids(struct rpc_context *rpc, uint32_t len, uint32_t* 
gids) {
+       struct AUTH *auth = libnfs_authunix_create("libnfs", rpc->uid, 
rpc->gid, len, gids);
+       if (auth != NULL) {
+               rpc_set_auth(rpc, auth);
+       }
+}
+
 void rpc_set_error(struct rpc_context *rpc, const char *error_string, ...)
 {
         va_list ap;
        char *old_error_string;
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
         old_error_string = rpc->error_string;
         va_start(ap, error_string);
@@ -280,7 +293,9 @@
                free(old_error_string);
        }
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 }
 
@@ -307,7 +322,9 @@
         */
 
 #ifdef HAVE_MULTITHREADING
-       nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        outqueue = rpc->outqueue;
 
@@ -319,19 +336,25 @@
                rpc_free_pdu(rpc, pdu);
        }
 #ifdef HAVE_MULTITHREADING
-       nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 
        for (i = 0; i < HASHES; i++) {
                struct rpc_queue waitqueue;
 
 #ifdef HAVE_MULTITHREADING
-               nfs_mt_mutex_lock(&rpc->rpc_mutex);
+                if (rpc->multithreading_enabled) {
+                        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+                }
 #endif /* HAVE_MULTITHREADING */
                waitqueue = rpc->waitpdu[i];
                rpc_reset_queue(&rpc->waitpdu[i]);
 #ifdef HAVE_MULTITHREADING
-               nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                if (rpc->multithreading_enabled) {
+                        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                }
 #endif /* HAVE_MULTITHREADING */
                while((pdu = waitqueue.head) != NULL) {
                        waitqueue.head = pdu->next;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/libnfs-sync.c 
new/libnfs-libnfs-5.0.2/lib/libnfs-sync.c
--- old/libnfs-libnfs-5.0.1/lib/libnfs-sync.c   2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/lib/libnfs-sync.c   2022-08-10 05:59:10.000000000 
+0200
@@ -125,7 +125,7 @@
 {
        cb_data->is_finished = 0;
 #ifdef HAVE_MULTITHREADING
-        if (nfs && (*nfs)->nfsi->multithreading_enabled && (*nfs)->master_ctx 
== NULL) {
+        if (nfs && (*nfs)->rpc->multithreading_enabled && (*nfs)->master_ctx 
== NULL) {
                 struct nfs_thread_context *ntc;
 
                 for(ntc = (*nfs)->nfsi->thread_ctx; ntc; ntc = ntc->next) {
@@ -260,7 +260,7 @@
        int ret;
 
 #ifdef HAVE_MULTITHREADING
-        if(nfs->nfsi->multithreading_enabled) {
+        if(nfs->rpc->multithreading_enabled) {
                 nfs_mt_sem_wait(&cb_data->wait_sem);
                 return;
         }
@@ -539,7 +539,11 @@
          struct nfsfh **nfsfh)
 {
        struct sync_cb_data cb_data;
-
+        int retry = 0;
+        struct nfs_context *onfs = nfs;
+        
+ try_again:
+        nfs = onfs;
        cb_data.return_data = nfsfh;
         if (nfs_init_cb_data(&nfs, &cb_data)) {
                 return -1;
@@ -555,6 +559,10 @@
        wait_for_nfs_reply(nfs, &cb_data);
         nfs_destroy_cb_sem(&cb_data);
 
+        if (cb_data.status == -EIO && retry < 10) {
+                retry++;
+                goto try_again;
+        }
        return cb_data.status;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/libnfs-win32.def 
new/libnfs-libnfs-5.0.2/lib/libnfs-win32.def
--- old/libnfs-libnfs-5.0.1/lib/libnfs-win32.def        2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/lib/libnfs-win32.def        2022-08-10 
05:59:10.000000000 +0200
@@ -86,6 +86,7 @@
 nfs_service
 nfs_set_auth
 nfs_set_autoreconnect
+rpc_set_auxiliary_gids
 nfs_set_debug
 nfs_set_dircache
 nfs_set_gid
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/libnfs.c 
new/libnfs-libnfs-5.0.2/lib/libnfs.c
--- old/libnfs-libnfs-5.0.1/lib/libnfs.c        2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/lib/libnfs.c        2022-08-10 05:59:10.000000000 
+0200
@@ -110,7 +110,9 @@
 {
        int i = 0;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        }
 #endif
        LIBNFS_LIST_ADD(&nfs->nfsi->dircache, nfsdir);
 
@@ -122,7 +124,9 @@
                }
        }
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        }
 #endif
 }
 
@@ -132,7 +136,9 @@
        struct nfsdir *nfsdir;
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        }
 #endif
        for (nfsdir = nfs->nfsi->dircache; nfsdir; nfsdir = nfsdir->next) {
                if (nfsdir->fh.len == fh->len &&
@@ -143,7 +149,9 @@
        }
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        }
 #endif
        return nfsdir;
 }
@@ -270,7 +278,7 @@
 nfs_get_error(struct nfs_context *nfs)
 {
 #ifdef HAVE_MULTITHREADING
-        if (nfs && nfs->nfsi->multithreading_enabled) {
+        if (nfs && nfs->rpc->multithreading_enabled) {
                 struct nfs_thread_context *ntc;
 
                 for(ntc = nfs->nfsi->thread_ctx; ntc; ntc = ntc->next) {
@@ -577,7 +585,8 @@
 
 #ifdef HAVE_MULTITHREADING
         nfs_mt_mutex_init(&nfs->nfsi->nfs_mutex);
-        nfs_mt_mutex_init(&nfs->nfsi->nfs4_open_mutex);
+        nfs_mt_mutex_init(&nfs->nfsi->nfs4_open_counter_mutex);
+        nfs_mt_mutex_init(&nfs->nfsi->nfs4_open_call_mutex);
 #endif /* HAVE_MULTITHREADING */
        return nfs;
 }
@@ -625,7 +634,8 @@
        }
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_destroy(&nfs->nfsi->nfs4_open_mutex);
+        nfs_mt_mutex_destroy(&nfs->nfsi->nfs4_open_call_mutex);
+        nfs_mt_mutex_destroy(&nfs->nfsi->nfs4_open_counter_mutex);
         nfs_mt_mutex_destroy(&nfs->nfsi->nfs_mutex);
         while (nfs->nfsi->thread_ctx) {
                 struct nfs_thread_context *tmp = nfs->nfsi->thread_ctx->next;
@@ -1904,6 +1914,11 @@
 }
 
 void
+nfs_set_auxiliary_gids(struct nfs_context *nfs, uint32_t len, uint32_t* gids) {
+       rpc_set_auxiliary_gids(nfs->rpc, len, gids);
+}
+
+void
 nfs_set_pagecache(struct nfs_context *nfs, uint32_t v) {
        rpc_set_pagecache(nfs->rpc, v);
 }
@@ -1962,7 +1977,9 @@
         /* All thread contexts share the same rpc_context so
          * use the mutex from the rpc_context.
          */
-        nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
         va_start(ap, error_string);
        str = malloc(1024);
@@ -1973,7 +1990,9 @@
        nfs->error_string = str;
        va_end(ap);
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/multithreading.c 
new/libnfs-libnfs-5.0.2/lib/multithreading.c
--- old/libnfs-libnfs-5.0.1/lib/multithreading.c        2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/lib/multithreading.c        2022-08-10 
05:59:10.000000000 +0200
@@ -54,11 +54,17 @@
 #ifdef HAVE_MULTITHREADING
 
 #ifdef HAVE_PTHREAD
-pid_t gettid(void);
+#include <unistd.h>
+#include <sys/syscall.h>
 
 nfs_tid_t nfs_mt_get_tid(void)
 {
-        return gettid();
+#ifdef SYS_gettid
+        pid_t tid = syscall(SYS_gettid);
+        return tid;
+#else
+#error "SYS_gettid unavailable on this system"
+#endif
 }
 
 static void *nfs_mt_service_thread(void *arg)
@@ -68,9 +74,9 @@
        int revents;
        int ret;
 
-        nfs->nfsi->multithreading_enabled = 1;
+        nfs->rpc->multithreading_enabled = 1;
 
-       while (nfs->nfsi->multithreading_enabled) {
+       while (nfs->rpc->multithreading_enabled) {
                pfd.fd = nfs_get_fd(nfs);
                pfd.events = nfs_which_events(nfs);
                pfd.revents = 0;
@@ -97,7 +103,7 @@
                 nfs_set_error(nfs, "Failed to start service thread");
                 return -1;
         }
-        while (nfs->nfsi->multithreading_enabled == 0) {
+        while (nfs->rpc->multithreading_enabled == 0) {
                 struct timespec ts = {0, 1000000};
                 nanosleep(&ts, NULL);
         }
@@ -106,7 +112,7 @@
 
 void nfs_mt_service_thread_stop(struct nfs_context *nfs)
 {
-        nfs->nfsi->multithreading_enabled = 0;
+        nfs->rpc->multithreading_enabled = 0;
         pthread_join(nfs->nfsi->service_thread, NULL);
 }
         
@@ -164,9 +170,9 @@
     int revents;
     int ret;
 
-    nfs->nfsi->multithreading_enabled = 1;
+    nfs->rpc->multithreading_enabled = 1;
 
-    while (nfs->nfsi->multithreading_enabled) {
+    while (nfs->rpc->multithreading_enabled) {
         pfd.fd = nfs_get_fd(nfs);
         pfd.events = nfs_which_events(nfs);
         pfd.revents = 0;
@@ -197,7 +203,6 @@
         return 1;
     }
     nfs = (struct nfs_context *)lpParam;
-    printf("SERVICE THREAD\n");
     nfs_mt_service_thread(nfs);
     return 0;
 }
@@ -209,7 +214,7 @@
         nfs_set_error(nfs, "Failed to start service thread");
         return -1;
     }
-    while (nfs->nfsi->multithreading_enabled == 0) {
+    while (nfs->rpc->multithreading_enabled == 0) {
         Sleep(100);
     }
     return 0;
@@ -217,13 +222,13 @@
 
 void nfs_mt_service_thread_stop(struct nfs_context* nfs)
 {
-    nfs->nfsi->multithreading_enabled = 0;
+    nfs->rpc->multithreading_enabled = 0;
     while (WaitForSingleObject(nfs->nfsi->service_thread, INFINITE) != 
WAIT_OBJECT_0);
 }
 
 int nfs_mt_mutex_init(libnfs_mutex_t* mutex)
 {
-    *mutex = CreateMutex(NULL, 0, NULL);
+    *mutex = CreateSemaphoreA(NULL, 1, 1, NULL);
     return 0;
 }
 
@@ -241,7 +246,7 @@
 
 int nfs_mt_mutex_unlock(libnfs_mutex_t* mutex)
 {
-    ReleaseMutex(*mutex);
+    ReleaseSemaphore(*mutex, 1, NULL);
     return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/nfs_v3.c 
new/libnfs-libnfs-5.0.2/lib/nfs_v3.c
--- old/libnfs-libnfs-5.0.1/lib/nfs_v3.c        2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/lib/nfs_v3.c        2022-08-10 05:59:10.000000000 
+0200
@@ -4067,7 +4067,6 @@
        struct nfs_cb_data *data;
         GETACL3args args;
 
-        printf("getacl async\n");
        data = malloc(sizeof(struct nfs_cb_data));
        if (data == NULL) {
                nfs_set_error(nfs, "out of memory: failed to allocate "
@@ -4511,12 +4510,13 @@
                                                              mdata->offset,
                                                              mdata->count,
                                                              
&data->usrbuf[mdata->offset - data->offset]);
+                                       data->num_calls++;
                                        if (rpc_nfs3_write_async(nfs->rpc,
                                                                  
nfs3_pwrite_mcb,
                                                                  &args, mdata) 
== 0) {
-                                               data->num_calls++;
                                                return;
                                        } else {
+                                               data->num_calls--;
                                                nfs_set_error(nfs, "RPC error: 
Failed to send WRITE call for %s", data->path);
                                                data->oom = 1;
                                        }
@@ -4623,8 +4623,10 @@
                nfs3_fill_WRITE3args(&args, nfsfh, offset, writecount,
                                      &buf[offset - data->offset]);
 
+               data->num_calls++;
                if (rpc_nfs3_write_async(nfs->rpc, nfs3_pwrite_mcb,
                                          &args, mdata) != 0) {
+                       data->num_calls--;
                        nfs_set_error(nfs, "RPC error: Failed to send WRITE "
                                       "call for %s", data->path);
                        free(mdata);
@@ -4638,7 +4640,6 @@
 
                count               -= writecount;
                offset              += writecount;
-               data->num_calls++;
        } while (count > 0);
 
        return 0;
@@ -4773,13 +4774,14 @@
                                        nfs3_fill_READ3args(&args, data->nfsfh,
                                                             mdata->offset,
                                                             mdata->count);
+                                       data->num_calls++;
                                        if (rpc_nfs3_read_async(nfs->rpc,
                                                                 nfs3_pread_mcb,
                                                                 &args, mdata)
                                             == 0) {
-                                               data->num_calls++;
                                                return;
                                        } else {
+                                               data->num_calls--;
                                                nfs_set_error(nfs, "RPC error: 
Failed to send READ call for %s", data->path);
                                                data->oom = 1;
                                        }
@@ -4956,8 +4958,10 @@
 
                nfs3_fill_READ3args(&args, nfsfh, offset, readcount);
 
+               data->num_calls++;
                if (rpc_nfs3_read_async(nfs->rpc, nfs3_pread_mcb,
                                         &args, mdata) != 0) {
+                       data->num_calls--;
                        nfs_set_error(nfs, "RPC error: Failed to send READ "
                                       "call for %s", data->path);
                        free(mdata);
@@ -4971,7 +4975,6 @@
 
                count               -= readcount;
                offset              += readcount;
-               data->num_calls++;
         } while (count > 0);
 
         return 0;
@@ -4984,12 +4987,16 @@
 {
        /* steal saved_path */
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        }
 #endif
        free(nfs->nfsi->cwd);
         nfs->nfsi->cwd = data->saved_path;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        }
 #endif
 
        data->saved_path = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/nfs_v4.c 
new/libnfs-libnfs-5.0.2/lib/nfs_v4.c
--- old/libnfs-libnfs-5.0.1/lib/nfs_v4.c        2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/lib/nfs_v4.c        2022-08-10 05:59:10.000000000 
+0200
@@ -162,8 +162,8 @@
         nfs_cb cb;
         void *private_data;
 
-        /* Used to track lock_owner during open() */
-        uint32_t lock_owner;
+        /* Used to track open_owner during open() */
+        uint32_t open_owner;
         
         /* internal callback */
         rpc_cb continue_cb;
@@ -247,6 +247,11 @@
 static void
 free_nfs4_cb_data(struct nfs4_cb_data *data)
 {
+#ifdef HAVE_MULTITHREADING
+        if (data->flags & MUTEX_HELD) {
+                nfs_mt_mutex_unlock(&data->nfs->nfsi->nfs4_open_call_mutex);
+        }
+#endif        
         free(data->path);
         free(data->filler.data);
         if (data->filler.blob0.val && data->filler.blob0.free) {
@@ -643,23 +648,6 @@
         return 1;
 }
 
-#ifdef HAVE_MULTITHREADING
-static int
-nfs4_op_release_lockowner(struct nfs_context *nfs, nfs_argop4 *op, struct 
nfsfh *fh)
-{
-        RELEASE_LOCKOWNER4args *rlargs;
-
-        op->argop = OP_RELEASE_LOCKOWNER;
-        rlargs = &op->nfs_argop4_u.oprelease_lockowner;
-
-        rlargs->lock_owner.clientid = nfs->nfsi->clientid;
-        rlargs->lock_owner.owner.owner_len = 4;
-        rlargs->lock_owner.owner.owner_val = (char *)&fh->lock_owner;
-        
-        return 1;
-}
-#endif
-
 static int
 nfs4_op_close(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh)
 {
@@ -676,10 +664,6 @@
         clargs->open_stateid.seqid = fh->stateid.seqid;
         memcpy(clargs->open_stateid.other, fh->stateid.other, 12);
 
-#ifdef HAVE_MULTITHREADING
-        i += nfs4_op_release_lockowner(nfs, &op[i], fh);
-#endif
-
         return i;
 }
 
@@ -1690,12 +1674,16 @@
 
         /* Ok, all good. Lets steal the path string. */
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex);
+        }
 #endif
         free(nfs->nfsi->cwd);
         nfs->nfsi->cwd = data->path;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex);
+        }
 #endif
 
         data->path = NULL;
@@ -2151,7 +2139,7 @@
         }
         memcpy(fh->fh.val, gresok->object.nfs_fh4_val, fh->fh.len);
         fh->open_seqid = 1;
-        fh->lock_owner = data->lock_owner;
+        fh->open_owner = data->open_owner;
         
         if (data->filler.flags & O_SYNC) {
                 fh->is_sync = 1;
@@ -2259,7 +2247,7 @@
         oargs->share_deny = OPEN4_SHARE_DENY_NONE;
         oargs->owner.clientid = nfs->nfsi->clientid;
         oargs->owner.owner.owner_len = 4;
-        oargs->owner.owner.owner_val = (char *)&data->lock_owner;
+        oargs->owner.owner.owner_val = (char *)&data->open_owner;
         oargs->seqid = 0;
         if (data->filler.flags & O_CREAT) {
                 createhow4 *ch;
@@ -2352,11 +2340,15 @@
         data_split_path(data);
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&data->nfs->nfsi->nfs4_open_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_counter_mutex);
+        }
 #endif
-        data->lock_owner = nfs->nfsi->open_counter++;
+        data->open_owner = nfs->nfsi->open_counter++;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&data->nfs->nfsi->nfs4_open_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&nfs->nfsi->nfs4_open_counter_mutex);
+        }
 #endif
         
         data->filler.func = nfs4_populate_open;
@@ -2476,11 +2468,15 @@
         }
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&data->nfs->nfsi->nfs4_open_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_counter_mutex);
+        }
 #endif        
-        data->lock_owner = nfs->nfsi->open_counter++;
+        data->open_owner = nfs->nfsi->open_counter++;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&data->nfs->nfsi->nfs4_open_mutex);
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&nfs->nfsi->nfs4_open_counter_mutex);
+        }
 #endif        
         data->filler.func = nfs4_populate_open;
         data->filler.max_op = 3;
@@ -2547,6 +2543,12 @@
                 memcpy(data->filler.blob3.val, &m, sizeof(uint32_t));
         }
 
+#ifdef HAVE_MULTITHREADING
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_call_mutex);
+                data->flags |= MUTEX_HELD;
+        }
+#endif        
         ret = nfs4_open_async_internal(nfs, data, flags, mode);
         return ret;
 }
@@ -2696,7 +2698,7 @@
                  void *private_data)
 {
         COMPOUND4args args;
-        nfs_argop4 op[4];
+        nfs_argop4 op[3];
         struct nfs4_cb_data *data;
         int i;
 
@@ -2708,6 +2710,12 @@
         }
         memset(data, 0, sizeof(*data));
 
+#ifdef HAVE_MULTITHREADING
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_call_mutex);
+                data->flags |= MUTEX_HELD;
+        }
+#endif        
         data->nfs          = nfs;
         data->cb           = cb;
         data->private_data = private_data;
@@ -3903,6 +3911,12 @@
         length = nfs_hton64(length);
         memcpy(data->filler.blob3.val, &length, sizeof(uint64_t));
 
+#ifdef HAVE_MULTITHREADING
+        if (nfs->rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_call_mutex);
+                data->flags |= MUTEX_HELD;
+        }
+#endif        
         if (nfs4_open_async_internal(nfs, data, O_WRONLY, 0) < 0) {
                 return -1;
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/pdu.c 
new/libnfs-libnfs-5.0.2/lib/pdu.c
--- old/libnfs-libnfs-5.0.1/lib/pdu.c   2022-01-31 18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/lib/pdu.c   2022-08-10 05:59:10.000000000 +0200
@@ -161,11 +161,15 @@
        }
        memset(pdu, 0, pdu_size);
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        pdu->xid                = rpc->xid++;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        pdu->cb                 = cb;
        pdu->private_data       = private_data;
@@ -229,11 +233,15 @@
 void rpc_set_next_xid(struct rpc_context *rpc, uint32_t xid)
 {
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        rpc->xid = xid;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 }
 
@@ -277,12 +285,16 @@
 
                hash = rpc_hash_xid(pdu->xid);
 #ifdef HAVE_MULTITHREADING
-               nfs_mt_mutex_lock(&rpc->rpc_mutex);
+                if (rpc->multithreading_enabled) {
+                        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+                }
 #endif /* HAVE_MULTITHREADING */
                rpc_enqueue(&rpc->waitpdu[hash], pdu);
                rpc->waitpdu_len++;
 #ifdef HAVE_MULTITHREADING
-               nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                if (rpc->multithreading_enabled) {
+                        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                }
 #endif /* HAVE_MULTITHREADING */
                return 0;
        }
@@ -294,15 +306,21 @@
 
        pdu->outdata.size = size;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
         rpc_enqueue(&rpc->outqueue, pdu);
 #ifdef HAVE_MULTITHREADING
         if (rpc->outqueue.head == pdu) {
-                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                if (rpc->multithreading_enabled) {
+                        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                }
                 rpc_write_to_socket(rpc);
         } else {
-                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                if (rpc->multithreading_enabled) {
+                        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                }
         }
 #endif /* HAVE_MULTITHREADING */
         
@@ -497,7 +515,7 @@
                                               "call payload");
                                 return rpc_send_error_reply(rpc, &call, 
GARBAGE_ARGS, 0 ,0);
                         }
-                        return endpoint->procs[i].func(rpc, &call);
+                        return endpoint->procs[i].func(rpc, &call, 
endpoint->procs[i].opaque);
                 }
         }
 
@@ -593,7 +611,9 @@
        /* Look up the transaction in a hash table of our requests */
        hash = rpc_hash_xid(xid);
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        q = &rpc->waitpdu[hash];
 
@@ -616,7 +636,9 @@
                        rpc->waitpdu_len--;
                }
 #ifdef HAVE_MULTITHREADING
-                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                if (rpc->multithreading_enabled) {
+                        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+                }
 #endif /* HAVE_MULTITHREADING */
                if (rpc_process_reply(rpc, pdu, &zdr) != 0) {
                        rpc_set_error(rpc, "rpc_procdess_reply failed");
@@ -631,7 +653,9 @@
                return 0;
        }
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 
        zdr_destroy(&zdr);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/lib/socket.c 
new/libnfs-libnfs-5.0.2/lib/socket.c
--- old/libnfs-libnfs-5.0.1/lib/socket.c        2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/lib/socket.c        2022-08-10 05:59:10.000000000 
+0200
@@ -166,7 +166,7 @@
 {
        int level;
 
-       #if defined(__FreeBSD__) || defined(__sun) || (defined(__APPLE__) && 
defined(__MACH__))
+       #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun) || 
(defined(__APPLE__) && defined(__MACH__))
        struct protoent *buf;
 
        if ((buf = getprotobyname("tcp")) != NULL)
@@ -215,13 +215,17 @@
        }
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        if (rpc_has_queue(&rpc->outqueue)) {
                events |= POLLOUT;
        }
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        return events;
 }
@@ -241,7 +245,9 @@
        }
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        while ((pdu = rpc->outqueue.head) != NULL) {
                int64_t total;
@@ -283,7 +289,9 @@
 
  finished:
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        return ret;
 }
@@ -421,7 +429,9 @@
        unsigned int i;
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        for (pdu = rpc->outqueue.head; pdu; pdu = next_pdu) {
                next_pdu = pdu->next;
@@ -471,7 +481,9 @@
                }
        }
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 }
 
@@ -894,7 +906,9 @@
         */
         printf("reconnect reset waitpdu queues\n");
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        for (i = 0; i < HASHES; i++) {
                struct rpc_queue *q = &rpc->waitpdu[i];
@@ -908,7 +922,9 @@
        }
        rpc->waitpdu_len = 0;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 
        if (rpc->auto_reconnect < 0 || rpc->num_retries > 0) {
@@ -1032,11 +1048,15 @@
        }
 
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_lock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
        i += rpc->waitpdu_len;
 #ifdef HAVE_MULTITHREADING
-        nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        if (rpc->multithreading_enabled) {
+                nfs_mt_mutex_unlock(&rpc->rpc_mutex);
+        }
 #endif /* HAVE_MULTITHREADING */
 
        return i;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/nfs4/nfs4.c 
new/libnfs-libnfs-5.0.2/nfs4/nfs4.c
--- old/libnfs-libnfs-5.0.1/nfs4/nfs4.c 2022-01-31 18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/nfs4/nfs4.c 2022-08-10 05:59:10.000000000 +0200
@@ -142,10 +142,10 @@
         case NFS4ERR_DELAY: return -EIO;
         case NFS4ERR_SAME: return -EIO;
         case NFS4ERR_DENIED: return -EIO;
-        case NFS4ERR_EXPIRED: return -EIO;
+        case NFS4ERR_EXPIRED: return -EAGAIN;
         case NFS4ERR_LOCKED: return -EIO;
         case NFS4ERR_GRACE: return -EIO;
-        case NFS4ERR_FHEXPIRED: return -EIO;
+        case NFS4ERR_FHEXPIRED: return -EAGAIN;
         case NFS4ERR_SHARE_DENIED: return -EIO;
         case NFS4ERR_WRONGSEC: return -EIO;
         case NFS4ERR_CLID_INUSE: return -EIO;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/packaging/RPM/libnfs.spec.in 
new/libnfs-libnfs-5.0.2/packaging/RPM/libnfs.spec.in
--- old/libnfs-libnfs-5.0.1/packaging/RPM/libnfs.spec.in        2022-01-31 
18:31:37.000000000 +0100
+++ new/libnfs-libnfs-5.0.2/packaging/RPM/libnfs.spec.in        2022-08-10 
05:59:10.000000000 +0200
@@ -113,6 +113,12 @@
 %{_mandir}/man1/nfs-ls.1.gz
 
 %changelog
+* Wed Aug 10 2022 : Version 5.0.2
+- Various small multithreading fixes
+- Add opaque pointer to service_proc to make it easier to build server apps.
+- BSD compile fix
+- OpenBSD support
+- fix double free in nfs3_pread_mcb() 
 * Tue Feb 1 2022 : Version 5.0.1
 - Fix non-pthread build
 * Fri Jan 28 2022 : Version 5.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnfs-libnfs-5.0.1/utils/nfs-stat.c 
new/libnfs-libnfs-5.0.2/utils/nfs-stat.c
--- old/libnfs-libnfs-5.0.1/utils/nfs-stat.c    2022-01-31 18:31:37.000000000 
+0100
+++ new/libnfs-libnfs-5.0.2/utils/nfs-stat.c    2022-08-10 05:59:10.000000000 
+0200
@@ -47,6 +47,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <inttypes.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include "libnfs.h"
@@ -273,19 +274,19 @@
        }
 
        printf("  File:%s\n", argv[1]);
-       printf("  Size: %-16dBlocks: %-11d IO Block: %d  %s\n",
+       printf("  Size: %-16" PRIu64 "Blocks: %-11" PRIu64 " IO Block: %" 
PRIu64 "  %s\n",
               st.nfs_size, st.nfs_blocks, st.nfs_blksize,
               get_file_type(st.nfs_mode));
-       printf("Inode:%-12dLinks %d\n",
+       printf("Inode:%-12" PRIu64 "Links %" PRIu64 "\n",
               st.nfs_ino, st.nfs_nlink);
-       printf("Access: (%04o/%s)  Uid: ( %d/%s)  Gid: ( %d/%s)\n",
+       printf("Access: (%04" PRIo64 "/%s)  Uid: ( %" PRIu64 "/%s)  Gid: ( %" 
PRIu64 "/%s)\n",
               st.nfs_mode & 07777, get_access_bits(st.nfs_mode),
               st.nfs_uid, uid_to_name(st.nfs_uid),
               st.nfs_gid, gid_to_name(st.nfs_gid));
 
-       printf("Access: %s", ctime(&st.nfs_atime));
-       printf("Modify: %s", ctime(&st.nfs_mtime));
-       printf("Change: %s", ctime(&st.nfs_ctime));
+       printf("Access: %s", ctime( (const time_t *) &st.nfs_atime));
+       printf("Modify: %s", ctime( (const time_t *) &st.nfs_mtime));
+       printf("Change: %s", ctime( (const time_t *) &st.nfs_ctime));
        free_file_context(nf);
 
        return 0;

Reply via email to