Date: Wednesday, December 14, 2022 @ 18:39:38
  Author: freswa
Revision: 464336

archrelease: copy trunk to testing-x86_64

Added:
  db5.3/repos/testing-x86_64/PKGBUILD
    (from rev 464335, db5.3/trunk/PKGBUILD)
  db5.3/repos/testing-x86_64/db-5.3.21-memp_stat-upstream-fix.patch
    (from rev 464335, db5.3/trunk/db-5.3.21-memp_stat-upstream-fix.patch)
  db5.3/repos/testing-x86_64/db-5.3.21-mutex_leak.patch
    (from rev 464335, db5.3/trunk/db-5.3.21-mutex_leak.patch)
  db5.3/repos/testing-x86_64/db-5.3.28-atomic_compare_exchange.patch
    (from rev 464335, db5.3/trunk/db-5.3.28-atomic_compare_exchange.patch)
  db5.3/repos/testing-x86_64/db-5.3.28-lemon_hash.patch
    (from rev 464335, db5.3/trunk/db-5.3.28-lemon_hash.patch)
  db5.3/repos/testing-x86_64/db-5.3.28-mmap-high-cpu-usage.patch
    (from rev 464335, db5.3/trunk/db-5.3.28-mmap-high-cpu-usage.patch)
  db5.3/repos/testing-x86_64/db-5.3.28_cve-2019-2708.patch
    (from rev 464335, db5.3/trunk/db-5.3.28_cve-2019-2708.patch)
Deleted:
  db5.3/repos/testing-x86_64/PKGBUILD
  db5.3/repos/testing-x86_64/db-5.3.21-memp_stat-upstream-fix.patch
  db5.3/repos/testing-x86_64/db-5.3.21-mutex_leak.patch
  db5.3/repos/testing-x86_64/db-5.3.28-atomic_compare_exchange.patch
  db5.3/repos/testing-x86_64/db-5.3.28-lemon_hash.patch
  db5.3/repos/testing-x86_64/db-5.3.28-mmap-high-cpu-usage.patch
  db5.3/repos/testing-x86_64/db-5.3.28_cve-2019-2708.patch

-----------------------------------------+
 PKGBUILD                                |  141 +-
 db-5.3.21-memp_stat-upstream-fix.patch  |  366 +++----
 db-5.3.21-mutex_leak.patch              | 1436 +++++++++++++++---------------
 db-5.3.28-atomic_compare_exchange.patch |   40 
 db-5.3.28-lemon_hash.patch              |   40 
 db-5.3.28-mmap-high-cpu-usage.patch     |   38 
 db-5.3.28_cve-2019-2708.patch           | 1388 ++++++++++++++--------------
 7 files changed, 1725 insertions(+), 1724 deletions(-)

Deleted: PKGBUILD
===================================================================
--- PKGBUILD    2022-12-14 18:39:35 UTC (rev 464335)
+++ PKGBUILD    2022-12-14 18:39:38 UTC (rev 464336)
@@ -1,70 +0,0 @@
-# Maintainer: Frederik Schwan <freswa at archlinux dot org>
-# Contributor: Stéphane Gaudreault <[email protected]>
-# Contributor: Allan McRae <[email protected]>
-# Contributor: Andreas Radke <[email protected]>
-
-pkgname=db5.3
-pkgver=5.3.28
-pkgrel=1
-pkgdesc="The Berkeley DB embedded database system v5.3"
-arch=(x86_64)
-url='https://www.oracle.com/technology/software/products/berkeley-db/index.html'
-license=(AGPL3)
-depends=(gcc-libs sh)
-source=(
-  https://download.oracle.com/berkeley-db/db-${pkgver}.tar.gz
-  db-5.3.21-memp_stat-upstream-fix.patch
-  db-5.3.21-mutex_leak.patch
-  db-5.3.28-lemon_hash.patch
-  db-5.3.28_cve-2019-2708.patch
-  db-5.3.28-mmap-high-cpu-usage.patch
-  db-5.3.28-atomic_compare_exchange.patch
-)
-b2sums=('5b77a4ec0945fa96ce6c2b452fb4b029295e037fa64d5ff8dcb3b5e01ee3501fd75d9a73b8f5fa54d8907717d93546fbb5348ee70119e877fa2f17d301ecf50d'
-        
'cfbb212c60c0e75c0d8c1cdbee9bcf0be9aec718ab462f779d5b880a4f976de1423279adde20159eef067be95d0d725eaa0cb950d0a8aaae720de78b94299e72'
-        
'ba917cf9b69de39337b7141bf145153ae89849921c79b4d2f40734feefe2c0007abcc8c85ed776227875c5102354d8f61069fcee12c7db3b45c4ccabc6993760'
-        
'682539a382f4423ad4404ad2aa446356d97485a7883a26d31cc2061611b138f20e39d941c575b8997538c4dd609e3e0343505759bba3b89c669ad1830cac1fbf'
-        
'bc72ba9703cdbabbece3480fd36c22fca26f270cc4b8c66f8f19799b5120010dfdf53772a94374e45d38b25bb8a271d29ea84318aa8bc847a88940d52ee22a8f'
-        
'bc50b556653a4e33073ed4cbaf716035f0840af2659bb4d6ef900621f92515d9490a698cec70546bd3aededa02b264fcd6e6cba3c4e6412125d2d587094f872d'
-        
'c32c5236d5f1c9c112e5c6d7aee8d1d67e4f80c3826020ba71d864649bd12f2402a6d68334cfbf1bc17c920878bf64296d884436608a5b3fb9a27ba1fd4d9c75')
-
-# All Patches retrieved from Fedora
-prepare() {
-  cd db-${pkgver}
-  # memp_stat fix provided by upstream
-  patch -Np1 -i ../db-5.3.21-memp_stat-upstream-fix.patch
-  # fix for mutexes not being released provided by upstream
-  patch -Np1 -i ../db-5.3.21-mutex_leak.patch
-  # fix for overflowing hash variable inside bundled lemon
-  patch -Np1 -i ../db-5.3.28-lemon_hash.patch
-  # cve-2019-2708 fixed by mmuzila
-  patch -Np1 -i ../db-5.3.28_cve-2019-2708.patch
-  # Prevents high CPU usage
-  patch -Np1 -i ../db-5.3.28-mmap-high-cpu-usage.patch
-  # gcc fix
-  patch -Np1 -i ../db-5.3.28-atomic_compare_exchange.patch
-}
-
-
-build() {
-  cd db-${pkgver}/build_unix
-  ../dist/configure \
-    --prefix=/usr \
-    --bindir=/usr/bin/db5.3 \
-    --includedir=/usr/include/db5.3 \
-    --enable-compat185 \
-    --enable-shared \
-    --enable-static \
-    --enable-cxx \
-    --enable-dbm \
-    --enable-stl
-  make LIBSO_LIBS=-lpthread
-}
-
-package() {
-  make -C db-${pkgver}/build_unix DESTDIR="${pkgdir}" install
-  rm "${pkgdir}"/usr/lib/libdb.so
-  rm "${pkgdir}"/usr/lib/libdb_cxx.so
-  rm "${pkgdir}"/usr/lib/libdb_stl.so
-  rm -r "${pkgdir}"/usr/docs
-}

Copied: db5.3/repos/testing-x86_64/PKGBUILD (from rev 464335, 
db5.3/trunk/PKGBUILD)
===================================================================
--- PKGBUILD                            (rev 0)
+++ PKGBUILD    2022-12-14 18:39:38 UTC (rev 464336)
@@ -0,0 +1,71 @@
+# Maintainer: Frederik Schwan <freswa at archlinux dot org>
+# Contributor: Stéphane Gaudreault <[email protected]>
+# Contributor: Allan McRae <[email protected]>
+# Contributor: Andreas Radke <[email protected]>
+
+pkgname=db5.3
+pkgver=5.3.28
+pkgrel=2
+pkgdesc="The Berkeley DB embedded database system v5.3"
+arch=(x86_64)
+url='https://www.oracle.com/technology/software/products/berkeley-db/index.html'
+license=(custom:sleepycat)
+depends=(gcc-libs sh)
+source=(
+  https://download.oracle.com/berkeley-db/db-${pkgver}.tar.gz
+  db-5.3.21-memp_stat-upstream-fix.patch
+  db-5.3.21-mutex_leak.patch
+  db-5.3.28-lemon_hash.patch
+  db-5.3.28_cve-2019-2708.patch
+  db-5.3.28-mmap-high-cpu-usage.patch
+  db-5.3.28-atomic_compare_exchange.patch
+)
+b2sums=('5b77a4ec0945fa96ce6c2b452fb4b029295e037fa64d5ff8dcb3b5e01ee3501fd75d9a73b8f5fa54d8907717d93546fbb5348ee70119e877fa2f17d301ecf50d'
+        
'cfbb212c60c0e75c0d8c1cdbee9bcf0be9aec718ab462f779d5b880a4f976de1423279adde20159eef067be95d0d725eaa0cb950d0a8aaae720de78b94299e72'
+        
'ba917cf9b69de39337b7141bf145153ae89849921c79b4d2f40734feefe2c0007abcc8c85ed776227875c5102354d8f61069fcee12c7db3b45c4ccabc6993760'
+        
'682539a382f4423ad4404ad2aa446356d97485a7883a26d31cc2061611b138f20e39d941c575b8997538c4dd609e3e0343505759bba3b89c669ad1830cac1fbf'
+        
'bc72ba9703cdbabbece3480fd36c22fca26f270cc4b8c66f8f19799b5120010dfdf53772a94374e45d38b25bb8a271d29ea84318aa8bc847a88940d52ee22a8f'
+        
'bc50b556653a4e33073ed4cbaf716035f0840af2659bb4d6ef900621f92515d9490a698cec70546bd3aededa02b264fcd6e6cba3c4e6412125d2d587094f872d'
+        
'c32c5236d5f1c9c112e5c6d7aee8d1d67e4f80c3826020ba71d864649bd12f2402a6d68334cfbf1bc17c920878bf64296d884436608a5b3fb9a27ba1fd4d9c75')
+
+# All Patches retrieved from Fedora
+prepare() {
+  cd db-${pkgver}
+  # memp_stat fix provided by upstream
+  patch -Np1 -i ../db-5.3.21-memp_stat-upstream-fix.patch
+  # fix for mutexes not being released provided by upstream
+  patch -Np1 -i ../db-5.3.21-mutex_leak.patch
+  # fix for overflowing hash variable inside bundled lemon
+  patch -Np1 -i ../db-5.3.28-lemon_hash.patch
+  # cve-2019-2708 fixed by mmuzila
+  patch -Np1 -i ../db-5.3.28_cve-2019-2708.patch
+  # Prevents high CPU usage
+  patch -Np1 -i ../db-5.3.28-mmap-high-cpu-usage.patch
+  # gcc fix
+  patch -Np1 -i ../db-5.3.28-atomic_compare_exchange.patch
+}
+
+
+build() {
+  cd db-${pkgver}/build_unix
+  ../dist/configure \
+    --prefix=/usr \
+    --bindir=/usr/bin/db5.3 \
+    --includedir=/usr/include/db5.3 \
+    --enable-compat185 \
+    --enable-shared \
+    --enable-static \
+    --enable-cxx \
+    --enable-dbm \
+    --enable-stl
+  make LIBSO_LIBS=-lpthread
+}
+
+package() {
+  make -C db-${pkgver}/build_unix DESTDIR="${pkgdir}" install
+  install -Dm644 db-${pkgver}/LICENSE 
"${pkgdir}"/usr/share/licenses/${pkgname}/LICENSE
+  rm "${pkgdir}"/usr/lib/libdb.so
+  rm "${pkgdir}"/usr/lib/libdb_cxx.so
+  rm "${pkgdir}"/usr/lib/libdb_stl.so
+  rm -r "${pkgdir}"/usr/docs
+}

Deleted: db-5.3.21-memp_stat-upstream-fix.patch
===================================================================
--- db-5.3.21-memp_stat-upstream-fix.patch      2022-12-14 18:39:35 UTC (rev 
464335)
+++ db-5.3.21-memp_stat-upstream-fix.patch      2022-12-14 18:39:38 UTC (rev 
464336)
@@ -1,183 +0,0 @@
-diff -r -u db-5.3.21_orig/src/mp/mp_stat.c db-5.3.21/src/mp/mp_stat.c
---- db-5.3.21_orig/src/mp/mp_stat.c    2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_stat.c 2015-05-19 15:07:09.000000000 +0800
-@@ -87,6 +87,13 @@
-       u_int32_t i;
-       uintmax_t tmp_wait, tmp_nowait;
- 
-+      /*
-+       * The array holding the lengths related to the buffer allocated for 
*fspp.
-+       * The first element of the array holds the number of entries allocated.
-+       * The second element of the array holds the total number of bytes 
allocated.
-+       */
-+      u_int32_t fsp_len[2];
-+
-       dbmp = env->mp_handle;
-       mp = dbmp->reginfo[0].primary;
- 
-@@ -193,32 +200,53 @@
-       if (fspp != NULL) {
-               *fspp = NULL;
- 
--              /* Count the MPOOLFILE structures. */
--              i = 0;
--              len = 0;
--              if ((ret = __memp_walk_files(env,
--                   mp, __memp_count_files, &len, &i, flags)) != 0)
--                      return (ret);
-+              while (*fspp == NULL) {
-+                      /* Count the MPOOLFILE structures. */
-+                      i = 0;
-+                      /*
-+                       * Allow space for the first __memp_get_files() to 
align the
-+                       * structure array to uintmax_t, DB_MPOOL_STAT's most
-+                       * restrictive field.  [#23150]
-+                       */
-+                      len = sizeof(uintmax_t);
-+                      if ((ret = __memp_walk_files(env,
-+                           mp, __memp_count_files, &len, &i, flags)) != 0)
-+                              return (ret);
-+
-+                      if (i == 0)
-+                              return (0);
-+
-+                      /* 
-+                       * Copy the number of DB_MPOOL_FSTAT entries and the 
number of
-+                       * bytes allocated for them into fsp_len. Do not count 
the space
-+                       * reserved for allignment.
-+                       */
-+                      fsp_len[0] = i;
-+                      fsp_len[1] = len - sizeof(uintmax_t);
- 
--              if (i == 0)
--                      return (0);
--              len += sizeof(DB_MPOOL_FSTAT *);        /* Trailing NULL */
-+                      len += sizeof(DB_MPOOL_FSTAT *);        /* Trailing 
NULL */
- 
--              /* Allocate space */
--              if ((ret = __os_umalloc(env, len, fspp)) != 0)
--                      return (ret);
-+                      /* Allocate space */
-+                      if ((ret = __os_umalloc(env, len, fspp)) != 0)
-+                              return (ret);
- 
--              tfsp = *fspp;
--              *tfsp = NULL;
--
--              /*
--               * Files may have been opened since we counted, don't walk
--               * off the end of the allocated space.
--               */
--              if ((ret = __memp_walk_files(env,
--                  mp, __memp_get_files, &tfsp, &i, flags)) != 0)
--                      return (ret);
-+                      tfsp = *fspp;
-+                      *tfsp = NULL;
- 
-+                      /*
-+                       * Files may have been opened since we counted, if we 
walk off
-+                       * the end of the allocated space specified in fsp_len, 
retry.
-+                       */
-+                      if ((ret = __memp_walk_files(env,
-+                          mp, __memp_get_files, &tfsp, fsp_len, flags)) != 0) 
{
-+                              if (ret == DB_BUFFER_SMALL) {
-+                                      __os_ufree(env, *fspp);
-+                                      *fspp = NULL;
-+                                      tfsp = NULL;
-+                              } else
-+                                      return (ret);
-+                      }
-+              }
-               *++tfsp = NULL;
-       }
- 
-@@ -286,28 +314,35 @@
-  * for the text file names.
-  */
- static int
--__memp_get_files(env, mfp, argp, countp, flags)
-+__memp_get_files(env, mfp, argp, fsp_len, flags)
-       ENV *env;
-       MPOOLFILE *mfp;
-       void *argp;
--      u_int32_t *countp;
-+      u_int32_t fsp_len[];
-       u_int32_t flags;
- {
-       DB_MPOOL *dbmp;
-       DB_MPOOL_FSTAT **tfsp, *tstruct;
-       char *name, *tname;
--      size_t nlen;
-+      size_t nlen, tlen;
- 
--      if (*countp == 0)
--              return (0);
-+      /* We walked through more files than argp was allocated for. */
-+      if (fsp_len[0] == 0)
-+              return DB_BUFFER_SMALL;
- 
-       dbmp = env->mp_handle;
-       tfsp = *(DB_MPOOL_FSTAT ***)argp;
- 
-       if (*tfsp == NULL) {
--              /* Add 1 to count because we need to skip over the NULL. */
--              tstruct = (DB_MPOOL_FSTAT *)(tfsp + *countp + 1);
--              tname = (char *)(tstruct + *countp);
-+              /*
-+               * Add 1 to count because to skip over the NULL end marker.
-+               * Align it further for DB_MPOOL_STAT's most restrictive field
-+               * because uintmax_t might require stricter alignment than
-+               * pointers; e.g., IP32 LL64 SPARC. [#23150]
-+               */
-+              tstruct = (DB_MPOOL_FSTAT *)&tfsp[fsp_len[0] + 1];
-+              tstruct = ALIGNP_INC(tstruct, sizeof(uintmax_t));
-+              tname = (char *)&tstruct[fsp_len[0]];
-               *tfsp = tstruct;
-       } else {
-               tstruct = *tfsp + 1;
-@@ -317,6 +352,15 @@
- 
-       name = __memp_fns(dbmp, mfp);
-       nlen = strlen(name) + 1;
-+
-+      /* The space required for file names is larger than argp was allocated 
for. */
-+      tlen = sizeof(DB_MPOOL_FSTAT *) + sizeof(DB_MPOOL_FSTAT) + nlen;
-+      if (fsp_len[1] < tlen)
-+              return DB_BUFFER_SMALL;
-+      else
-+              /* Count down the number of bytes left in argp. */
-+              fsp_len[1] -= tlen;
-+
-       memcpy(tname, name, nlen);
-       memcpy(tstruct, &mfp->stat, sizeof(mfp->stat));
-       tstruct->file_name = tname;
-@@ -325,7 +369,9 @@
-       tstruct->st_pagesize = mfp->pagesize;
- 
-       *(DB_MPOOL_FSTAT ***)argp = tfsp;
--      (*countp)--;
-+
-+      /* Count down the number of entries left in argp. */
-+      fsp_len[0]--;
- 
-       if (LF_ISSET(DB_STAT_CLEAR))
-               memset(&mfp->stat, 0, sizeof(mfp->stat));
-diff -r -u db-5.3.21_orig/src/mp/mp_sync.c db-5.3.21/src/mp/mp_sync.c
---- db-5.3.21_orig/src/mp/mp_sync.c    2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_sync.c 2015-05-19 15:08:05.000000000 +0800
-@@ -57,11 +57,13 @@
-                       if ((t_ret = func(env,
-                           mfp, arg, countp, flags)) != 0 && ret == 0)
-                               ret = t_ret;
--                      if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
-+                      if (ret != 0 &&
-+                          (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == 
DB_BUFFER_SMALL))
-                               break;
-               }
-               MUTEX_UNLOCK(env, hp->mtx_hash);
--              if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
-+              if (ret != 0 &&
-+                  (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
-                       break;
-       }
-       return (ret);

Copied: db5.3/repos/testing-x86_64/db-5.3.21-memp_stat-upstream-fix.patch (from 
rev 464335, db5.3/trunk/db-5.3.21-memp_stat-upstream-fix.patch)
===================================================================
--- db-5.3.21-memp_stat-upstream-fix.patch                              (rev 0)
+++ db-5.3.21-memp_stat-upstream-fix.patch      2022-12-14 18:39:38 UTC (rev 
464336)
@@ -0,0 +1,183 @@
+diff -r -u db-5.3.21_orig/src/mp/mp_stat.c db-5.3.21/src/mp/mp_stat.c
+--- db-5.3.21_orig/src/mp/mp_stat.c    2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_stat.c 2015-05-19 15:07:09.000000000 +0800
+@@ -87,6 +87,13 @@
+       u_int32_t i;
+       uintmax_t tmp_wait, tmp_nowait;
+ 
++      /*
++       * The array holding the lengths related to the buffer allocated for 
*fspp.
++       * The first element of the array holds the number of entries allocated.
++       * The second element of the array holds the total number of bytes 
allocated.
++       */
++      u_int32_t fsp_len[2];
++
+       dbmp = env->mp_handle;
+       mp = dbmp->reginfo[0].primary;
+ 
+@@ -193,32 +200,53 @@
+       if (fspp != NULL) {
+               *fspp = NULL;
+ 
+-              /* Count the MPOOLFILE structures. */
+-              i = 0;
+-              len = 0;
+-              if ((ret = __memp_walk_files(env,
+-                   mp, __memp_count_files, &len, &i, flags)) != 0)
+-                      return (ret);
++              while (*fspp == NULL) {
++                      /* Count the MPOOLFILE structures. */
++                      i = 0;
++                      /*
++                       * Allow space for the first __memp_get_files() to 
align the
++                       * structure array to uintmax_t, DB_MPOOL_STAT's most
++                       * restrictive field.  [#23150]
++                       */
++                      len = sizeof(uintmax_t);
++                      if ((ret = __memp_walk_files(env,
++                           mp, __memp_count_files, &len, &i, flags)) != 0)
++                              return (ret);
++
++                      if (i == 0)
++                              return (0);
++
++                      /* 
++                       * Copy the number of DB_MPOOL_FSTAT entries and the 
number of
++                       * bytes allocated for them into fsp_len. Do not count 
the space
++                       * reserved for allignment.
++                       */
++                      fsp_len[0] = i;
++                      fsp_len[1] = len - sizeof(uintmax_t);
+ 
+-              if (i == 0)
+-                      return (0);
+-              len += sizeof(DB_MPOOL_FSTAT *);        /* Trailing NULL */
++                      len += sizeof(DB_MPOOL_FSTAT *);        /* Trailing 
NULL */
+ 
+-              /* Allocate space */
+-              if ((ret = __os_umalloc(env, len, fspp)) != 0)
+-                      return (ret);
++                      /* Allocate space */
++                      if ((ret = __os_umalloc(env, len, fspp)) != 0)
++                              return (ret);
+ 
+-              tfsp = *fspp;
+-              *tfsp = NULL;
+-
+-              /*
+-               * Files may have been opened since we counted, don't walk
+-               * off the end of the allocated space.
+-               */
+-              if ((ret = __memp_walk_files(env,
+-                  mp, __memp_get_files, &tfsp, &i, flags)) != 0)
+-                      return (ret);
++                      tfsp = *fspp;
++                      *tfsp = NULL;
+ 
++                      /*
++                       * Files may have been opened since we counted, if we 
walk off
++                       * the end of the allocated space specified in fsp_len, 
retry.
++                       */
++                      if ((ret = __memp_walk_files(env,
++                          mp, __memp_get_files, &tfsp, fsp_len, flags)) != 0) 
{
++                              if (ret == DB_BUFFER_SMALL) {
++                                      __os_ufree(env, *fspp);
++                                      *fspp = NULL;
++                                      tfsp = NULL;
++                              } else
++                                      return (ret);
++                      }
++              }
+               *++tfsp = NULL;
+       }
+ 
+@@ -286,28 +314,35 @@
+  * for the text file names.
+  */
+ static int
+-__memp_get_files(env, mfp, argp, countp, flags)
++__memp_get_files(env, mfp, argp, fsp_len, flags)
+       ENV *env;
+       MPOOLFILE *mfp;
+       void *argp;
+-      u_int32_t *countp;
++      u_int32_t fsp_len[];
+       u_int32_t flags;
+ {
+       DB_MPOOL *dbmp;
+       DB_MPOOL_FSTAT **tfsp, *tstruct;
+       char *name, *tname;
+-      size_t nlen;
++      size_t nlen, tlen;
+ 
+-      if (*countp == 0)
+-              return (0);
++      /* We walked through more files than argp was allocated for. */
++      if (fsp_len[0] == 0)
++              return DB_BUFFER_SMALL;
+ 
+       dbmp = env->mp_handle;
+       tfsp = *(DB_MPOOL_FSTAT ***)argp;
+ 
+       if (*tfsp == NULL) {
+-              /* Add 1 to count because we need to skip over the NULL. */
+-              tstruct = (DB_MPOOL_FSTAT *)(tfsp + *countp + 1);
+-              tname = (char *)(tstruct + *countp);
++              /*
++               * Add 1 to count because to skip over the NULL end marker.
++               * Align it further for DB_MPOOL_STAT's most restrictive field
++               * because uintmax_t might require stricter alignment than
++               * pointers; e.g., IP32 LL64 SPARC. [#23150]
++               */
++              tstruct = (DB_MPOOL_FSTAT *)&tfsp[fsp_len[0] + 1];
++              tstruct = ALIGNP_INC(tstruct, sizeof(uintmax_t));
++              tname = (char *)&tstruct[fsp_len[0]];
+               *tfsp = tstruct;
+       } else {
+               tstruct = *tfsp + 1;
+@@ -317,6 +352,15 @@
+ 
+       name = __memp_fns(dbmp, mfp);
+       nlen = strlen(name) + 1;
++
++      /* The space required for file names is larger than argp was allocated 
for. */
++      tlen = sizeof(DB_MPOOL_FSTAT *) + sizeof(DB_MPOOL_FSTAT) + nlen;
++      if (fsp_len[1] < tlen)
++              return DB_BUFFER_SMALL;
++      else
++              /* Count down the number of bytes left in argp. */
++              fsp_len[1] -= tlen;
++
+       memcpy(tname, name, nlen);
+       memcpy(tstruct, &mfp->stat, sizeof(mfp->stat));
+       tstruct->file_name = tname;
+@@ -325,7 +369,9 @@
+       tstruct->st_pagesize = mfp->pagesize;
+ 
+       *(DB_MPOOL_FSTAT ***)argp = tfsp;
+-      (*countp)--;
++
++      /* Count down the number of entries left in argp. */
++      fsp_len[0]--;
+ 
+       if (LF_ISSET(DB_STAT_CLEAR))
+               memset(&mfp->stat, 0, sizeof(mfp->stat));
+diff -r -u db-5.3.21_orig/src/mp/mp_sync.c db-5.3.21/src/mp/mp_sync.c
+--- db-5.3.21_orig/src/mp/mp_sync.c    2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_sync.c 2015-05-19 15:08:05.000000000 +0800
+@@ -57,11 +57,13 @@
+                       if ((t_ret = func(env,
+                           mfp, arg, countp, flags)) != 0 && ret == 0)
+                               ret = t_ret;
+-                      if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++                      if (ret != 0 &&
++                          (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == 
DB_BUFFER_SMALL))
+                               break;
+               }
+               MUTEX_UNLOCK(env, hp->mtx_hash);
+-              if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++              if (ret != 0 &&
++                  (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
+                       break;
+       }
+       return (ret);

Deleted: db-5.3.21-mutex_leak.patch
===================================================================
--- db-5.3.21-mutex_leak.patch  2022-12-14 18:39:35 UTC (rev 464335)
+++ db-5.3.21-mutex_leak.patch  2022-12-14 18:39:38 UTC (rev 464336)
@@ -1,718 +0,0 @@
-diff -U 5 -r db-5.3.21.old/src/dbinc_auto/int_def.in 
db-5.3.21/src/dbinc_auto/int_def.in
---- db-5.3.21.old/src/dbinc_auto/int_def.in    2012-05-12 01:57:53.000000000 
+0800
-+++ db-5.3.21/src/dbinc_auto/int_def.in        2016-10-25 22:40:58.000000000 
+0800
-@@ -1371,10 +1371,11 @@
- #define       __memp_failchk __memp_failchk@DB_VERSION_UNIQUE_NAME@
- #define       __memp_bhwrite __memp_bhwrite@DB_VERSION_UNIQUE_NAME@
- #define       __memp_pgread __memp_pgread@DB_VERSION_UNIQUE_NAME@
- #define       __memp_pg __memp_pg@DB_VERSION_UNIQUE_NAME@
- #define       __memp_bhfree __memp_bhfree@DB_VERSION_UNIQUE_NAME@
-+#define       __memp_bh_clear_dirty 
__memp_bh_clear_dirty@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fget_pp __memp_fget_pp@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fget __memp_fget@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fcreate_pp __memp_fcreate_pp@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fcreate __memp_fcreate@DB_VERSION_UNIQUE_NAME@
- #define       __memp_set_clear_len 
__memp_set_clear_len@DB_VERSION_UNIQUE_NAME@
-@@ -1395,10 +1396,11 @@
- #define       __memp_fopen __memp_fopen@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fclose_pp __memp_fclose_pp@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fclose __memp_fclose@DB_VERSION_UNIQUE_NAME@
- #define       __memp_mf_discard __memp_mf_discard@DB_VERSION_UNIQUE_NAME@
- #define       __memp_inmemlist __memp_inmemlist@DB_VERSION_UNIQUE_NAME@
-+#define       __memp_mf_mark_dead __memp_mf_mark_dead@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fput_pp __memp_fput_pp@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fput __memp_fput@DB_VERSION_UNIQUE_NAME@
- #define       __memp_unpin_buffers 
__memp_unpin_buffers@DB_VERSION_UNIQUE_NAME@
- #define       __memp_dirty __memp_dirty@DB_VERSION_UNIQUE_NAME@
- #define       __memp_shared __memp_shared@DB_VERSION_UNIQUE_NAME@
-@@ -1453,10 +1455,11 @@
- #define       __memp_fsync_pp __memp_fsync_pp@DB_VERSION_UNIQUE_NAME@
- #define       __memp_fsync __memp_fsync@DB_VERSION_UNIQUE_NAME@
- #define       __mp_xxx_fh __mp_xxx_fh@DB_VERSION_UNIQUE_NAME@
- #define       __memp_sync_int __memp_sync_int@DB_VERSION_UNIQUE_NAME@
- #define       __memp_mf_sync __memp_mf_sync@DB_VERSION_UNIQUE_NAME@
-+#define       __memp_purge_dead_files 
__memp_purge_dead_files@DB_VERSION_UNIQUE_NAME@
- #define       __memp_trickle_pp __memp_trickle_pp@DB_VERSION_UNIQUE_NAME@
- #define       __mutex_alloc __mutex_alloc@DB_VERSION_UNIQUE_NAME@
- #define       __mutex_alloc_int __mutex_alloc_int@DB_VERSION_UNIQUE_NAME@
- #define       __mutex_free __mutex_free@DB_VERSION_UNIQUE_NAME@
- #define       __mutex_free_int __mutex_free_int@DB_VERSION_UNIQUE_NAME@
-diff -U 5 -r db-5.3.21.old/src/dbinc_auto/mp_ext.h 
db-5.3.21/src/dbinc_auto/mp_ext.h
---- db-5.3.21.old/src/dbinc_auto/mp_ext.h      2012-05-12 01:57:53.000000000 
+0800
-+++ db-5.3.21/src/dbinc_auto/mp_ext.h  2016-10-25 22:40:58.000000000 +0800
-@@ -14,10 +14,11 @@
- int __memp_failchk __P((ENV *));
- int __memp_bhwrite __P((DB_MPOOL *, DB_MPOOL_HASH *, MPOOLFILE *, BH *, int));
- int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
- int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int));
- int __memp_bhfree __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, DB_MPOOL_HASH *, 
BH *, u_int32_t));
-+void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
- int __memp_fget_pp __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, 
void *));
- int __memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, DB_THREAD_INFO *, DB_TXN *, 
u_int32_t, void *));
- int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
- int __memp_fcreate __P((ENV *, DB_MPOOLFILE **));
- int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t));
-@@ -38,10 +39,11 @@
- int __memp_fopen __P((DB_MPOOLFILE *, MPOOLFILE *, const char *, const char 
**, u_int32_t, int, size_t));
- int __memp_fclose_pp __P((DB_MPOOLFILE *, u_int32_t));
- int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t));
- int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *, int));
- int __memp_inmemlist __P((ENV *, char ***, int *));
-+void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
- int __memp_fput_pp __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, 
u_int32_t));
- int __memp_fput __P((DB_MPOOLFILE *, DB_THREAD_INFO *, void *, 
DB_CACHE_PRIORITY));
- int __memp_unpin_buffers __P((ENV *, DB_THREAD_INFO *));
- int __memp_dirty __P((DB_MPOOLFILE *, void *, DB_THREAD_INFO *, DB_TXN *, 
DB_CACHE_PRIORITY, u_int32_t));
- int __memp_shared __P((DB_MPOOLFILE *, void *));
-@@ -96,10 +98,11 @@
- int __memp_fsync_pp __P((DB_MPOOLFILE *));
- int __memp_fsync __P((DB_MPOOLFILE *));
- int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
- int __memp_sync_int __P((ENV *, DB_MPOOLFILE *, u_int32_t, u_int32_t, 
u_int32_t *, int *));
- int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int));
-+int __memp_purge_dead_files __P((ENV *));
- int __memp_trickle_pp __P((DB_ENV *, int, int *));
- 
- #if defined(__cplusplus)
- }
- #endif
-diff -U 5 -r db-5.3.21.old/src/mp/mp_bh.c db-5.3.21/src/mp/mp_bh.c
---- db-5.3.21.old/src/mp/mp_bh.c       2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_bh.c   2016-10-25 17:09:35.000000000 +0800
-@@ -472,15 +472,12 @@
-        * a shared latch.
-        */
-       if (F_ISSET(bhp, BH_DIRTY | BH_TRASH)) {
-               MUTEX_LOCK(env, hp->mtx_hash);
-               DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
--              if (ret == 0 && F_ISSET(bhp, BH_DIRTY)) {
--                      F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
--                      DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
--                      atomic_dec(env, &hp->hash_page_dirty);
--              }
-+              if (ret == 0)
-+                      __memp_bh_clear_dirty(env, hp, bhp);
- 
-               /* put the page back if necessary. */
-               if ((ret != 0 || BH_REFCOUNT(bhp) > 1) &&
-                   F_ISSET(bhp, BH_TRASH)) {
-                       ret = __memp_pg(dbmfp, bhp->pgno, bhp->buf, 1);
-@@ -686,5 +683,31 @@
-       } else
-               MUTEX_UNLOCK(env, mfp->mutex);
- 
-       return (ret);
- }
-+
-+/*
-+ * __memp_bh_clear_dirty --
-+ *    Clear the dirty flag of of a buffer. Calls on the same buffer must be
-+ *    serialized to get the accounting correct. This can be achieved by
-+ *    acquiring an exclusive lock on the buffer, a shared lock on the
-+ *    buffer plus an exclusive lock on the hash bucket, or some other
-+ *    mechanism that guarantees single-thread access to the entire region
-+ *    (e.g. during __memp_region_bhfree()).
-+ *
-+ * PUBLIC: void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
-+ */
-+void
-+__memp_bh_clear_dirty(env, hp, bhp)
-+      ENV *env;
-+      DB_MPOOL_HASH *hp;
-+      BH *bhp;
-+{
-+      COMPQUIET(env, env);
-+      if (F_ISSET(bhp, BH_DIRTY)) {
-+              F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
-+              DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
-+              (void)atomic_dec(env, &hp->hash_page_dirty);
-+      }
-+}
-+
-diff -U 5 -r db-5.3.21.old/src/mp/mp_fget.c db-5.3.21/src/mp/mp_fget.c
---- db-5.3.21.old/src/mp/mp_fget.c     2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_fget.c 2016-10-25 17:11:08.000000000 +0800
-@@ -437,16 +437,11 @@
-                * complain and get out.
-                */
-               if (flags == DB_MPOOL_FREE) {
- freebuf:              MUTEX_LOCK(env, hp->mtx_hash);
-                       h_locked = 1;
--                      if (F_ISSET(bhp, BH_DIRTY)) {
--                              F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
--                              DB_ASSERT(env,
--                                 atomic_read(&hp->hash_page_dirty) > 0);
--                              atomic_dec(env, &hp->hash_page_dirty);
--                      }
-+                      __memp_bh_clear_dirty(env, hp, bhp);
- 
-                       /*
-                        * If the buffer we found is already freed, we're done.
-                        * If the ref count is not 1 then someone may be
-                        * peeking at the buffer.  We cannot free it until they
-diff -U 5 -r db-5.3.21.old/src/mp/mp_fopen.c db-5.3.21/src/mp/mp_fopen.c
---- db-5.3.21.old/src/mp/mp_fopen.c    2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_fopen.c        2016-10-25 22:31:05.000000000 +0800
-@@ -12,10 +12,11 @@
- #include "dbinc/log.h"
- #include "dbinc/mp.h"
- #include "dbinc/db_page.h"
- #include "dbinc/hash.h"
- 
-+static int __memp_count_dead_mutex __P((DB_MPOOL *, u_int32_t *));
- static int __memp_mpf_alloc __P((DB_MPOOL *,
-     DB_MPOOLFILE *, const char *, u_int32_t, u_int32_t, MPOOLFILE **));
- static int __memp_mpf_find __P((ENV *,
-     DB_MPOOLFILE *, DB_MPOOL_HASH *, const char *, u_int32_t, MPOOLFILE **));
- 
-@@ -709,11 +710,15 @@
-                * We should be able to set mfp to NULL and break out of the
-                * loop, but I like the idea of checking all the entries.
-                */
-               if (LF_ISSET(DB_TRUNCATE)) {
-                       MUTEX_LOCK(env, mfp->mutex);
--                      mfp->deadfile = 1;
-+                      /*
-+                       * We cannot purge dead files here, because the caller
-+                       * is holding the mutex of the hash bucket of mfp.
-+                       */
-+                      __memp_mf_mark_dead(dbmp, mfp, NULL);
-                       MUTEX_UNLOCK(env, mfp->mutex);
-                       continue;
-               }
- 
-               /*
-@@ -907,14 +912,15 @@
-       DB_MPOOL *dbmp;
-       ENV *env;
-       MPOOLFILE *mfp;
-       char *rpath;
-       u_int32_t ref;
--      int deleted, ret, t_ret;
-+      int deleted, purge_dead, ret, t_ret;
- 
-       env = dbmfp->env;
-       dbmp = env->mp_handle;
-+      purge_dead = 0;
-       ret = 0;
- 
-       /*
-        * Remove the DB_MPOOLFILE from the process' list.
-        *
-@@ -1004,11 +1010,11 @@
-       }
-       DB_ASSERT(env, mfp->neutral_cnt < mfp->mpf_cnt);
-       if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
-               if (LF_ISSET(DB_MPOOL_DISCARD) ||
-                   F_ISSET(mfp, MP_TEMP) || mfp->unlink_on_close) {
--                      mfp->deadfile = 1;
-+                      __memp_mf_mark_dead(dbmp, mfp, &purge_dead);
-               }
-               if (mfp->unlink_on_close) {
-                       if ((t_ret = __db_appname(dbmp->env, DB_APP_DATA,
-                           R_ADDR(dbmp->reginfo, mfp->path_off), NULL,
-                           &rpath)) != 0 && ret == 0)
-@@ -1037,10 +1043,12 @@
-                       deleted = 1;
-               }
-       }
-       if (!deleted && !LF_ISSET(DB_MPOOL_NOLOCK))
-               MUTEX_UNLOCK(env, mfp->mutex);
-+      if (purge_dead)
-+              (void)__memp_purge_dead_files(env);
- 
- done: /* Discard the DB_MPOOLFILE structure. */
-       if (dbmfp->pgcookie != NULL) {
-               __os_free(env, dbmfp->pgcookie->data);
-               __os_free(env, dbmfp->pgcookie);
-@@ -1091,11 +1099,11 @@
-       /*
-        * We have to release the MPOOLFILE mutex before acquiring the region
-        * mutex so we don't deadlock.  Make sure nobody ever looks at this
-        * structure again.
-        */
--      mfp->deadfile = 1;
-+      __memp_mf_mark_dead(dbmp, mfp, NULL);
- 
-       /* Discard the mutex we're holding and return it too the pool. */
-       MUTEX_UNLOCK(env, mfp->mutex);
-       if ((t_ret = __mutex_free(env, &mfp->mutex)) != 0 && ret == 0)
-               ret = t_ret;
-@@ -1216,5 +1224,106 @@
-       /* Make sure we don't return any garbage. */
-       *cntp = 0;
-       *namesp = NULL;
-       return (ret);
- }
-+
-+/*
-+ * __memp_mf_mark_dead --
-+ *    Mark an MPOOLFILE as dead because its contents are no longer necessary.
-+ *    This happens when removing, truncation, or closing an unnamed in-memory
-+ *    database. Return, in the purgep parameter, whether the caller should
-+ *    call __memp_purge_dead_files() after the lock on mfp is released. The
-+ *    caller must hold an exclusive lock on the mfp handle.
-+ *
-+ * PUBLIC: void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
-+ */
-+void
-+__memp_mf_mark_dead(dbmp, mfp, purgep)
-+      DB_MPOOL *dbmp; 
-+      MPOOLFILE *mfp;
-+      int *purgep;
-+{
-+      ENV *env;
-+#ifdef HAVE_MUTEX_SUPPORT
-+      REGINFO *infop;
-+      DB_MUTEXREGION *mtxregion;
-+      u_int32_t mutex_max, mutex_inuse, dead_mutex;
-+#endif
-+
-+      if (purgep != NULL)
-+              *purgep = 0;
-+
-+      env = dbmp->env;
-+
-+#ifdef HAVE_MUTEX_SUPPORT
-+      MUTEX_REQUIRED(env, mfp->mutex);
-+
-+      if (MUTEX_ON(env) && mfp->deadfile == 0) {
-+              infop = &env->mutex_handle->reginfo;
-+              mtxregion = infop->primary;
-+
-+              mutex_inuse = mtxregion->stat.st_mutex_inuse;
-+              if ((mutex_max = env->dbenv->mutex_max) == 0)
-+                      mutex_max = infop->rp->max / mtxregion->mutex_size;
-+
-+              /*
-+               * Purging dead pages requires a full scan of the entire cache
-+               * buffer, so it is a slow operation. We only want to do it
-+               * when it is necessary and provides enough benefits. Below is
-+               * a simple heuristic that determines when to purge all dead
-+               * pages.
-+               */
-+              if (purgep != NULL && mutex_inuse > mutex_max - 200) {
-+                      /*
-+                       * If the mutex region is almost full and there are
-+                       * many mutexes held by dead files, purge dead files.
-+                       */
-+                      (void)__memp_count_dead_mutex(dbmp, &dead_mutex);
-+                      dead_mutex += mfp->block_cnt + 1;
-+
-+                      if (dead_mutex > mutex_inuse / 20)
-+                              *purgep = 1;
-+              }
-+      }
-+#endif
-+
-+      mfp->deadfile = 1;
-+}
-+
-+/*
-+ * __memp_count_dead_mutex --
-+ *    Estimate the number of mutexes held by dead files.
-+ */
-+static int
-+__memp_count_dead_mutex(dbmp, dead_mutex)
-+      DB_MPOOL *dbmp;
-+      u_int32_t *dead_mutex;
-+{
-+      ENV *env;
-+      DB_MPOOL_HASH *hp;
-+      MPOOL *mp;
-+      MPOOLFILE *mfp;
-+      u_int32_t mutex_per_file;
-+      int busy, i;
-+
-+      env = dbmp->env;
-+      *dead_mutex = 0;
-+      mutex_per_file = 1;
-+#ifndef HAVE_ATOMICFILEREAD
-+      mutex_per_file = 2;
-+#endif
-+      mp = dbmp->reginfo[0].primary;
-+      hp = R_ADDR(dbmp->reginfo, mp->ftab);
-+      for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
-+              busy = MUTEX_TRYLOCK(env, hp->mtx_hash);
-+              if (busy)
-+                      continue;
-+              SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
-+                      if (mfp->deadfile)
-+                              *dead_mutex += mfp->block_cnt + mutex_per_file;
-+              }
-+              MUTEX_UNLOCK(env, hp->mtx_hash);
-+      }
-+
-+      return (0);
-+}
-diff -U 5 -r db-5.3.21.old/src/mp/mp_method.c db-5.3.21/src/mp/mp_method.c
---- db-5.3.21.old/src/mp/mp_method.c   2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_method.c       2016-10-25 17:22:23.000000000 +0800
-@@ -638,11 +638,11 @@
-       DB_MPOOL_HASH *hp, *nhp;
-       MPOOL *mp;
-       MPOOLFILE *mfp;
-       roff_t newname_off;
-       u_int32_t bucket;
--      int locked, ret;
-+      int locked, purge_dead, ret;
-       size_t nlen;
-       void *p;
- 
- #undef        op_is_remove
- #define       op_is_remove    (newname == NULL)
-@@ -655,10 +655,11 @@
-       dbmp = NULL;
-       mfp = NULL;
-       nhp = NULL;
-       p = NULL;
-       locked = ret = 0;
-+      purge_dead = 0;
- 
-       if (!MPOOL_ON(env))
-               goto fsop;
- 
-       dbmp = env->mp_handle;
-@@ -747,11 +748,11 @@
-                * they do not get reclaimed as long as they exist.  Since we
-                * are now deleting the database, we need to dec that count.
-                */
-               if (mfp->no_backing_file)
-                       mfp->mpf_cnt--;
--              mfp->deadfile = 1;
-+              __memp_mf_mark_dead(dbmp, mfp, &purge_dead);
-               MUTEX_UNLOCK(env, mfp->mutex);
-       } else {
-               /*
-                * Else, it's a rename.  We've allocated memory for the new
-                * name.  Swap it with the old one.  If it's in memory we
-@@ -806,10 +807,16 @@
-       if (locked == 1) {
-               MUTEX_UNLOCK(env, hp->mtx_hash);
-               if (nhp != NULL && nhp != hp)
-                       MUTEX_UNLOCK(env, nhp->mtx_hash);
-       }
-+      /* 
-+       * __memp_purge_dead_files() must be called when the hash bucket is
-+       * unlocked.
-+       */
-+      if (purge_dead)
-+              (void)__memp_purge_dead_files(env);
-       return (ret);
- }
- 
- /*
-  * __memp_ftruncate __
-diff -U 5 -r db-5.3.21.old/src/mp/mp_sync.c db-5.3.21/src/mp/mp_sync.c
---- db-5.3.21.old/src/mp/mp_sync.c     2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_sync.c 2016-10-25 17:26:58.000000000 +0800
-@@ -24,10 +24,11 @@
- static int __bhcmp __P((const void *, const void *));
- static int __memp_close_flush_files __P((ENV *, int));
- static int __memp_sync_files __P((ENV *));
- static int __memp_sync_file __P((ENV *,
-               MPOOLFILE *, void *, u_int32_t *, u_int32_t));
-+static inline void __update_err_ret(int, int*);
- 
- /*
-  * __memp_walk_files --
-  * PUBLIC: int __memp_walk_files __P((ENV *, MPOOL *,
-  * PUBLIC:    int (*) __P((ENV *, MPOOLFILE *, void *,
-@@ -961,5 +962,125 @@
-               return (-1);
-       if (bhp1->track_pgno > bhp2->track_pgno)
-               return (1);
-       return (0);
- }
-+
-+/*
-+ * __memp_purge_dead_files --
-+ *    Remove all dead files and their buffers from the mpool. The caller
-+ *    cannot hold any lock on the dead MPOOLFILE handles, their buffers
-+ *    or their hash buckets.
-+ *
-+ * PUBLIC: int __memp_purge_dead_files __P((ENV *));
-+ */
-+int
-+__memp_purge_dead_files(env)
-+      ENV *env;
-+{
-+      BH *bhp;
-+      DB_MPOOL *dbmp;
-+      DB_MPOOL_HASH *hp, *hp_end;
-+      REGINFO *infop;
-+      MPOOL *c_mp, *mp;
-+      MPOOLFILE *mfp;
-+      u_int32_t i_cache;
-+      int ret, t_ret, h_lock;
-+
-+      if (!MPOOL_ON(env))
-+              return (0);
-+
-+      dbmp = env->mp_handle;
-+      mp = dbmp->reginfo[0].primary;
-+      ret = t_ret = h_lock = 0;
-+
-+      /*
-+       * Walk each cache's list of buffers and free all buffers whose
-+       * MPOOLFILE is marked as dead.
-+       */
-+      for (i_cache = 0; i_cache < mp->nreg; i_cache++) {
-+              infop = &dbmp->reginfo[i_cache]; 
-+              c_mp = infop->primary;
-+
-+              hp = R_ADDR(infop, c_mp->htab);
-+              hp_end = &hp[c_mp->htab_buckets];
-+              for (; hp < hp_end; hp++) {
-+                      /* Skip empty buckets. */
-+                      if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL)
-+                              continue;
-+
-+                      /* 
-+                       * Search for a dead buffer. Other places that call
-+                       * __memp_bhfree() acquire the buffer lock before the
-+                       * hash bucket lock. Even though we acquire the two
-+                       * locks in reverse order, we cannot deadlock here
-+                       * because we don't block waiting for the locks.
-+                       */
-+                      t_ret = MUTEX_TRYLOCK(env, hp->mtx_hash);
-+                      if (t_ret != 0) {
-+                              __update_err_ret(t_ret, &ret);
-+                              continue;
-+                      }
-+                      h_lock = 1;
-+                      SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh) {
-+                              /* Skip buffers that are being used. */
-+                              if (BH_REFCOUNT(bhp) > 0)
-+                                      continue;
-+
-+                              mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
-+                              if (!mfp->deadfile)
-+                                      continue;
-+
-+                              /* Found a dead buffer. Prepare to free it. */
-+                              t_ret = MUTEX_TRYLOCK(env, bhp->mtx_buf);
-+                              if (t_ret != 0) {
-+                                      __update_err_ret(t_ret, &ret);
-+                                      continue;
-+                              }
-+
-+                              DB_ASSERT(env, (!F_ISSET(bhp, BH_EXCLUSIVE) &&
-+                                  BH_REFCOUNT(bhp) == 0));
-+                              F_SET(bhp, BH_EXCLUSIVE);
-+                              (void)atomic_inc(env, &bhp->ref);
-+
-+                              __memp_bh_clear_dirty(env, hp, bhp);
-+
-+                              /*
-+                               * Free the buffer. The buffer and hash bucket
-+                               * are unlocked by __memp_bhfree.
-+                               */
-+                              if ((t_ret = __memp_bhfree(dbmp, infop, mfp,
-+                                  hp, bhp, BH_FREE_FREEMEM)) == 0)
-+                                      /*
-+                                       * Decrement hp, so the next turn will
-+                                       * search the same bucket again.
-+                                       */
-+                                      hp--;
-+                              else
-+                                      __update_err_ret(t_ret, &ret);
-+
-+                              /*
-+                               * The hash bucket is unlocked, we need to
-+                               * start over again.
-+                               */
-+                              h_lock = 0;
-+                              break;
-+                      }
-+
-+                      if (h_lock) {
-+                              MUTEX_UNLOCK(env, hp->mtx_hash);
-+                              h_lock = 0;
-+                      }
-+              }
-+      }
-+
-+      return (ret);
-+}
-+
-+static inline void
-+__update_err_ret(t_ret, retp)
-+      int t_ret;
-+      int *retp;
-+{
-+      if (t_ret != 0 && t_ret != DB_LOCK_NOTGRANTED && *retp == 0)
-+              *retp = t_ret;
-+}
-diff -U 5 -r db-5.3.21.old/src/mp/mp_trickle.c db-5.3.21/src/mp/mp_trickle.c
---- db-5.3.21.old/src/mp/mp_trickle.c  2012-05-12 01:57:53.000000000 +0800
-+++ db-5.3.21/src/mp/mp_trickle.c      2016-10-25 17:27:57.000000000 +0800
-@@ -65,10 +65,14 @@
-           "DB_ENV->memp_trickle: %d: percent must be between 1 and 100",
-                   "%d"), pct);
-               return (EINVAL);
-       }
- 
-+      /* First we purge all dead files and their buffers. */
-+      if ((ret = __memp_purge_dead_files(env)) != 0)
-+              return (ret);
-+
-       /*
-        * Loop through the caches counting total/dirty buffers.
-        *
-        * XXX
-        * Using hash_page_dirty is our only choice at the moment, but it's not
-diff -U 5 -r db-5.3.21.old/src/mutex/mut_region.c 
db-5.3.21/src/mutex/mut_region.c
---- db-5.3.21.old/src/mutex/mut_region.c       2012-05-12 01:57:54.000000000 
+0800
-+++ db-5.3.21/src/mutex/mut_region.c   2016-10-25 17:34:22.000000000 +0800
-@@ -15,11 +15,11 @@
- #include "dbinc/txn.h"
- 
- static db_size_t __mutex_align_size __P((ENV *));
- static int __mutex_region_init __P((ENV *, DB_MUTEXMGR *));
- static size_t __mutex_region_size __P((ENV *));
--static size_t __mutex_region_max __P((ENV *));
-+static size_t __mutex_region_max __P((ENV *, u_int32_t));
- 
- /*
-  * __mutex_open --
-  *    Open a mutex region.
-  *
-@@ -32,11 +32,11 @@
- {
-       DB_ENV *dbenv;
-       DB_MUTEXMGR *mtxmgr;
-       DB_MUTEXREGION *mtxregion;
-       size_t size;
--      u_int32_t cpu_count;
-+      u_int32_t cpu_count, mutex_needed;
-       int ret;
- #ifndef HAVE_ATOMIC_SUPPORT
-       u_int i;
- #endif
- 
-@@ -59,23 +59,24 @@
-                   cpu_count : cpu_count * MUTEX_SPINS_PER_PROCESSOR)) != 0)
-                       return (ret);
-       }
- 
-       /*
--       * If the user didn't set an absolute value on the number of mutexes
--       * we'll need, figure it out.  We're conservative in our allocation,
--       * we need mutexes for DB handles, group-commit queues and other things
--       * applications allocate at run-time.  The application may have kicked
--       * up our count to allocate its own mutexes, add that in.
-+       * Figure out the number of mutexes we'll need.  We're conservative in
-+       * our allocation, we need mutexes for DB handles, group-commit queues
-+       * and other things applications allocate at run-time.  The application
-+       * may have kicked up our count to allocate its own mutexes, add that
-+       * in.
-        */
-+      mutex_needed =
-+          __lock_region_mutex_count(env) +
-+          __log_region_mutex_count(env) +
-+          __memp_region_mutex_count(env) +
-+          __txn_region_mutex_count(env);
-       if (dbenv->mutex_cnt == 0 &&
-           F_ISSET(env, ENV_PRIVATE | ENV_THREAD) != ENV_PRIVATE)
--              dbenv->mutex_cnt =
--                  __lock_region_mutex_count(env) +
--                  __log_region_mutex_count(env) +
--                  __memp_region_mutex_count(env) +
--                  __txn_region_mutex_count(env);
-+              dbenv->mutex_cnt = mutex_needed;
- 
-       if (dbenv->mutex_max != 0 && dbenv->mutex_cnt > dbenv->mutex_max)
-               dbenv->mutex_cnt = dbenv->mutex_max;
- 
-       /* Create/initialize the mutex manager structure. */
-@@ -88,12 +89,12 @@
-       mtxmgr->reginfo.id = INVALID_REGION_ID;
-       mtxmgr->reginfo.flags = REGION_JOIN_OK;
-       size = __mutex_region_size(env);
-       if (create_ok)
-               F_SET(&mtxmgr->reginfo, REGION_CREATE_OK);
--      if ((ret = __env_region_attach(env,
--          &mtxmgr->reginfo, size, size + __mutex_region_max(env))) != 0)
-+      if ((ret = __env_region_attach(env, &mtxmgr->reginfo,
-+          size, size + __mutex_region_max(env, mutex_needed))) != 0)
-               goto err;
- 
-       /* If we created the region, initialize it. */
-       if (F_ISSET(&mtxmgr->reginfo, REGION_CREATE))
-               if ((ret = __mutex_region_init(env, mtxmgr)) != 0)
-@@ -350,44 +351,62 @@
- 
-       dbenv = env->dbenv;
- 
-       s = sizeof(DB_MUTEXMGR) + 1024;
- 
--      /* We discard one mutex for the OOB slot. */
-+      /* 
-+       * We discard one mutex for the OOB slot. Make sure mutex_cnt doesn't
-+       * overflow.
-+       */
-       s += __env_alloc_size(
--          (dbenv->mutex_cnt + 1) *__mutex_align_size(env));
-+          (dbenv->mutex_cnt + (dbenv->mutex_cnt == UINT32_MAX ? 0 : 1)) *
-+          __mutex_align_size(env));
- 
-       return (s);
- }
- 
- /*
-  * __mutex_region_max --
-  *     Return the amount of space needed to reach the maximum size.
-  */
- static size_t
--__mutex_region_max(env)
-+__mutex_region_max(env, mutex_needed)
-       ENV *env;
-+      u_int32_t mutex_needed;
- {
-       DB_ENV *dbenv;
--      u_int32_t max;
-+      u_int32_t max, mutex_cnt;
- 
-       dbenv = env->dbenv;
-+      mutex_cnt = dbenv->mutex_cnt;
- 
--      if ((max = dbenv->mutex_max) == 0) {
-+      /*
-+       * We want to limit the region size to accommodate at most UINT32_MAX
-+       * mutexes. If mutex_cnt is UINT32_MAX, no more space is allowed.
-+       */
-+      if ((max = dbenv->mutex_max) == 0 && mutex_cnt != UINT32_MAX)
-               if (F_ISSET(env, ENV_PRIVATE | ENV_THREAD) == ENV_PRIVATE)
--                      max = dbenv->mutex_inc + 1;
--              else
-+                      if (dbenv->mutex_inc + 1 < UINT32_MAX - mutex_cnt)
-+                              max = dbenv->mutex_inc + 1 + mutex_cnt;
-+                      else
-+                              max = UINT32_MAX;
-+              else {
-                       max = __lock_region_mutex_max(env) +
-                           __txn_region_mutex_max(env) +
-                           __log_region_mutex_max(env) +
-                           dbenv->mutex_inc + 100;
--      } else if (max <= dbenv->mutex_cnt)
-+                      if (max < UINT32_MAX - mutex_needed)
-+                              max += mutex_needed;
-+                      else
-+                              max = UINT32_MAX;
-+              }
-+
-+      if (max <= mutex_cnt)
-               return (0);
-       else
--              max -= dbenv->mutex_cnt;
--
--      return ( __env_alloc_size(max * __mutex_align_size(env)));
-+              return (__env_alloc_size(
-+                  (max - mutex_cnt) * __mutex_align_size(env)));
- }
- 
- #ifdef        HAVE_MUTEX_SYSTEM_RESOURCES
- /*
-  * __mutex_resource_return
-

Copied: db5.3/repos/testing-x86_64/db-5.3.21-mutex_leak.patch (from rev 464335, 
db5.3/trunk/db-5.3.21-mutex_leak.patch)
===================================================================
--- db-5.3.21-mutex_leak.patch                          (rev 0)
+++ db-5.3.21-mutex_leak.patch  2022-12-14 18:39:38 UTC (rev 464336)
@@ -0,0 +1,718 @@
+diff -U 5 -r db-5.3.21.old/src/dbinc_auto/int_def.in 
db-5.3.21/src/dbinc_auto/int_def.in
+--- db-5.3.21.old/src/dbinc_auto/int_def.in    2012-05-12 01:57:53.000000000 
+0800
++++ db-5.3.21/src/dbinc_auto/int_def.in        2016-10-25 22:40:58.000000000 
+0800
+@@ -1371,10 +1371,11 @@
+ #define       __memp_failchk __memp_failchk@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_bhwrite __memp_bhwrite@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_pgread __memp_pgread@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_pg __memp_pg@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_bhfree __memp_bhfree@DB_VERSION_UNIQUE_NAME@
++#define       __memp_bh_clear_dirty 
__memp_bh_clear_dirty@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fget_pp __memp_fget_pp@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fget __memp_fget@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fcreate_pp __memp_fcreate_pp@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fcreate __memp_fcreate@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_set_clear_len 
__memp_set_clear_len@DB_VERSION_UNIQUE_NAME@
+@@ -1395,10 +1396,11 @@
+ #define       __memp_fopen __memp_fopen@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fclose_pp __memp_fclose_pp@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fclose __memp_fclose@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_mf_discard __memp_mf_discard@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_inmemlist __memp_inmemlist@DB_VERSION_UNIQUE_NAME@
++#define       __memp_mf_mark_dead __memp_mf_mark_dead@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fput_pp __memp_fput_pp@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fput __memp_fput@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_unpin_buffers 
__memp_unpin_buffers@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_dirty __memp_dirty@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_shared __memp_shared@DB_VERSION_UNIQUE_NAME@
+@@ -1453,10 +1455,11 @@
+ #define       __memp_fsync_pp __memp_fsync_pp@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_fsync __memp_fsync@DB_VERSION_UNIQUE_NAME@
+ #define       __mp_xxx_fh __mp_xxx_fh@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_sync_int __memp_sync_int@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_mf_sync __memp_mf_sync@DB_VERSION_UNIQUE_NAME@
++#define       __memp_purge_dead_files 
__memp_purge_dead_files@DB_VERSION_UNIQUE_NAME@
+ #define       __memp_trickle_pp __memp_trickle_pp@DB_VERSION_UNIQUE_NAME@
+ #define       __mutex_alloc __mutex_alloc@DB_VERSION_UNIQUE_NAME@
+ #define       __mutex_alloc_int __mutex_alloc_int@DB_VERSION_UNIQUE_NAME@
+ #define       __mutex_free __mutex_free@DB_VERSION_UNIQUE_NAME@
+ #define       __mutex_free_int __mutex_free_int@DB_VERSION_UNIQUE_NAME@
+diff -U 5 -r db-5.3.21.old/src/dbinc_auto/mp_ext.h 
db-5.3.21/src/dbinc_auto/mp_ext.h
+--- db-5.3.21.old/src/dbinc_auto/mp_ext.h      2012-05-12 01:57:53.000000000 
+0800
++++ db-5.3.21/src/dbinc_auto/mp_ext.h  2016-10-25 22:40:58.000000000 +0800
+@@ -14,10 +14,11 @@
+ int __memp_failchk __P((ENV *));
+ int __memp_bhwrite __P((DB_MPOOL *, DB_MPOOL_HASH *, MPOOLFILE *, BH *, int));
+ int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
+ int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int));
+ int __memp_bhfree __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, DB_MPOOL_HASH *, 
BH *, u_int32_t));
++void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
+ int __memp_fget_pp __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, 
void *));
+ int __memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, DB_THREAD_INFO *, DB_TXN *, 
u_int32_t, void *));
+ int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
+ int __memp_fcreate __P((ENV *, DB_MPOOLFILE **));
+ int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t));
+@@ -38,10 +39,11 @@
+ int __memp_fopen __P((DB_MPOOLFILE *, MPOOLFILE *, const char *, const char 
**, u_int32_t, int, size_t));
+ int __memp_fclose_pp __P((DB_MPOOLFILE *, u_int32_t));
+ int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t));
+ int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *, int));
+ int __memp_inmemlist __P((ENV *, char ***, int *));
++void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
+ int __memp_fput_pp __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, 
u_int32_t));
+ int __memp_fput __P((DB_MPOOLFILE *, DB_THREAD_INFO *, void *, 
DB_CACHE_PRIORITY));
+ int __memp_unpin_buffers __P((ENV *, DB_THREAD_INFO *));
+ int __memp_dirty __P((DB_MPOOLFILE *, void *, DB_THREAD_INFO *, DB_TXN *, 
DB_CACHE_PRIORITY, u_int32_t));
+ int __memp_shared __P((DB_MPOOLFILE *, void *));
+@@ -96,10 +98,11 @@
+ int __memp_fsync_pp __P((DB_MPOOLFILE *));
+ int __memp_fsync __P((DB_MPOOLFILE *));
+ int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
+ int __memp_sync_int __P((ENV *, DB_MPOOLFILE *, u_int32_t, u_int32_t, 
u_int32_t *, int *));
+ int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int));
++int __memp_purge_dead_files __P((ENV *));
+ int __memp_trickle_pp __P((DB_ENV *, int, int *));
+ 
+ #if defined(__cplusplus)
+ }
+ #endif
+diff -U 5 -r db-5.3.21.old/src/mp/mp_bh.c db-5.3.21/src/mp/mp_bh.c
+--- db-5.3.21.old/src/mp/mp_bh.c       2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_bh.c   2016-10-25 17:09:35.000000000 +0800
+@@ -472,15 +472,12 @@
+        * a shared latch.
+        */
+       if (F_ISSET(bhp, BH_DIRTY | BH_TRASH)) {
+               MUTEX_LOCK(env, hp->mtx_hash);
+               DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
+-              if (ret == 0 && F_ISSET(bhp, BH_DIRTY)) {
+-                      F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+-                      DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
+-                      atomic_dec(env, &hp->hash_page_dirty);
+-              }
++              if (ret == 0)
++                      __memp_bh_clear_dirty(env, hp, bhp);
+ 
+               /* put the page back if necessary. */
+               if ((ret != 0 || BH_REFCOUNT(bhp) > 1) &&
+                   F_ISSET(bhp, BH_TRASH)) {
+                       ret = __memp_pg(dbmfp, bhp->pgno, bhp->buf, 1);
+@@ -686,5 +683,31 @@
+       } else
+               MUTEX_UNLOCK(env, mfp->mutex);
+ 
+       return (ret);
+ }
++
++/*
++ * __memp_bh_clear_dirty --
++ *    Clear the dirty flag of of a buffer. Calls on the same buffer must be
++ *    serialized to get the accounting correct. This can be achieved by
++ *    acquiring an exclusive lock on the buffer, a shared lock on the
++ *    buffer plus an exclusive lock on the hash bucket, or some other
++ *    mechanism that guarantees single-thread access to the entire region
++ *    (e.g. during __memp_region_bhfree()).
++ *
++ * PUBLIC: void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
++ */
++void
++__memp_bh_clear_dirty(env, hp, bhp)
++      ENV *env;
++      DB_MPOOL_HASH *hp;
++      BH *bhp;
++{
++      COMPQUIET(env, env);
++      if (F_ISSET(bhp, BH_DIRTY)) {
++              F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
++              DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
++              (void)atomic_dec(env, &hp->hash_page_dirty);
++      }
++}
++
+diff -U 5 -r db-5.3.21.old/src/mp/mp_fget.c db-5.3.21/src/mp/mp_fget.c
+--- db-5.3.21.old/src/mp/mp_fget.c     2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_fget.c 2016-10-25 17:11:08.000000000 +0800
+@@ -437,16 +437,11 @@
+                * complain and get out.
+                */
+               if (flags == DB_MPOOL_FREE) {
+ freebuf:              MUTEX_LOCK(env, hp->mtx_hash);
+                       h_locked = 1;
+-                      if (F_ISSET(bhp, BH_DIRTY)) {
+-                              F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+-                              DB_ASSERT(env,
+-                                 atomic_read(&hp->hash_page_dirty) > 0);
+-                              atomic_dec(env, &hp->hash_page_dirty);
+-                      }
++                      __memp_bh_clear_dirty(env, hp, bhp);
+ 
+                       /*
+                        * If the buffer we found is already freed, we're done.
+                        * If the ref count is not 1 then someone may be
+                        * peeking at the buffer.  We cannot free it until they
+diff -U 5 -r db-5.3.21.old/src/mp/mp_fopen.c db-5.3.21/src/mp/mp_fopen.c
+--- db-5.3.21.old/src/mp/mp_fopen.c    2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_fopen.c        2016-10-25 22:31:05.000000000 +0800
+@@ -12,10 +12,11 @@
+ #include "dbinc/log.h"
+ #include "dbinc/mp.h"
+ #include "dbinc/db_page.h"
+ #include "dbinc/hash.h"
+ 
++static int __memp_count_dead_mutex __P((DB_MPOOL *, u_int32_t *));
+ static int __memp_mpf_alloc __P((DB_MPOOL *,
+     DB_MPOOLFILE *, const char *, u_int32_t, u_int32_t, MPOOLFILE **));
+ static int __memp_mpf_find __P((ENV *,
+     DB_MPOOLFILE *, DB_MPOOL_HASH *, const char *, u_int32_t, MPOOLFILE **));
+ 
+@@ -709,11 +710,15 @@
+                * We should be able to set mfp to NULL and break out of the
+                * loop, but I like the idea of checking all the entries.
+                */
+               if (LF_ISSET(DB_TRUNCATE)) {
+                       MUTEX_LOCK(env, mfp->mutex);
+-                      mfp->deadfile = 1;
++                      /*
++                       * We cannot purge dead files here, because the caller
++                       * is holding the mutex of the hash bucket of mfp.
++                       */
++                      __memp_mf_mark_dead(dbmp, mfp, NULL);
+                       MUTEX_UNLOCK(env, mfp->mutex);
+                       continue;
+               }
+ 
+               /*
+@@ -907,14 +912,15 @@
+       DB_MPOOL *dbmp;
+       ENV *env;
+       MPOOLFILE *mfp;
+       char *rpath;
+       u_int32_t ref;
+-      int deleted, ret, t_ret;
++      int deleted, purge_dead, ret, t_ret;
+ 
+       env = dbmfp->env;
+       dbmp = env->mp_handle;
++      purge_dead = 0;
+       ret = 0;
+ 
+       /*
+        * Remove the DB_MPOOLFILE from the process' list.
+        *
+@@ -1004,11 +1010,11 @@
+       }
+       DB_ASSERT(env, mfp->neutral_cnt < mfp->mpf_cnt);
+       if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
+               if (LF_ISSET(DB_MPOOL_DISCARD) ||
+                   F_ISSET(mfp, MP_TEMP) || mfp->unlink_on_close) {
+-                      mfp->deadfile = 1;
++                      __memp_mf_mark_dead(dbmp, mfp, &purge_dead);
+               }
+               if (mfp->unlink_on_close) {
+                       if ((t_ret = __db_appname(dbmp->env, DB_APP_DATA,
+                           R_ADDR(dbmp->reginfo, mfp->path_off), NULL,
+                           &rpath)) != 0 && ret == 0)
+@@ -1037,10 +1043,12 @@
+                       deleted = 1;
+               }
+       }
+       if (!deleted && !LF_ISSET(DB_MPOOL_NOLOCK))
+               MUTEX_UNLOCK(env, mfp->mutex);
++      if (purge_dead)
++              (void)__memp_purge_dead_files(env);
+ 
+ done: /* Discard the DB_MPOOLFILE structure. */
+       if (dbmfp->pgcookie != NULL) {
+               __os_free(env, dbmfp->pgcookie->data);
+               __os_free(env, dbmfp->pgcookie);
+@@ -1091,11 +1099,11 @@
+       /*
+        * We have to release the MPOOLFILE mutex before acquiring the region
+        * mutex so we don't deadlock.  Make sure nobody ever looks at this
+        * structure again.
+        */
+-      mfp->deadfile = 1;
++      __memp_mf_mark_dead(dbmp, mfp, NULL);
+ 
+       /* Discard the mutex we're holding and return it too the pool. */
+       MUTEX_UNLOCK(env, mfp->mutex);
+       if ((t_ret = __mutex_free(env, &mfp->mutex)) != 0 && ret == 0)
+               ret = t_ret;
+@@ -1216,5 +1224,106 @@
+       /* Make sure we don't return any garbage. */
+       *cntp = 0;
+       *namesp = NULL;
+       return (ret);
+ }
++
++/*
++ * __memp_mf_mark_dead --
++ *    Mark an MPOOLFILE as dead because its contents are no longer necessary.
++ *    This happens when removing, truncation, or closing an unnamed in-memory
++ *    database. Return, in the purgep parameter, whether the caller should
++ *    call __memp_purge_dead_files() after the lock on mfp is released. The
++ *    caller must hold an exclusive lock on the mfp handle.
++ *
++ * PUBLIC: void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
++ */
++void
++__memp_mf_mark_dead(dbmp, mfp, purgep)
++      DB_MPOOL *dbmp; 
++      MPOOLFILE *mfp;
++      int *purgep;
++{
++      ENV *env;
++#ifdef HAVE_MUTEX_SUPPORT
++      REGINFO *infop;
++      DB_MUTEXREGION *mtxregion;
++      u_int32_t mutex_max, mutex_inuse, dead_mutex;
++#endif
++
++      if (purgep != NULL)
++              *purgep = 0;
++
++      env = dbmp->env;
++
++#ifdef HAVE_MUTEX_SUPPORT
++      MUTEX_REQUIRED(env, mfp->mutex);
++
++      if (MUTEX_ON(env) && mfp->deadfile == 0) {
++              infop = &env->mutex_handle->reginfo;
++              mtxregion = infop->primary;
++
++              mutex_inuse = mtxregion->stat.st_mutex_inuse;
++              if ((mutex_max = env->dbenv->mutex_max) == 0)
++                      mutex_max = infop->rp->max / mtxregion->mutex_size;
++
++              /*
++               * Purging dead pages requires a full scan of the entire cache
++               * buffer, so it is a slow operation. We only want to do it
++               * when it is necessary and provides enough benefits. Below is
++               * a simple heuristic that determines when to purge all dead
++               * pages.
++               */
++              if (purgep != NULL && mutex_inuse > mutex_max - 200) {
++                      /*
++                       * If the mutex region is almost full and there are
++                       * many mutexes held by dead files, purge dead files.
++                       */
++                      (void)__memp_count_dead_mutex(dbmp, &dead_mutex);
++                      dead_mutex += mfp->block_cnt + 1;
++
++                      if (dead_mutex > mutex_inuse / 20)
++                              *purgep = 1;
++              }
++      }
++#endif
++
++      mfp->deadfile = 1;
++}
++
++/*
++ * __memp_count_dead_mutex --
++ *    Estimate the number of mutexes held by dead files.
++ */
++static int
++__memp_count_dead_mutex(dbmp, dead_mutex)
++      DB_MPOOL *dbmp;
++      u_int32_t *dead_mutex;
++{
++      ENV *env;
++      DB_MPOOL_HASH *hp;
++      MPOOL *mp;
++      MPOOLFILE *mfp;
++      u_int32_t mutex_per_file;
++      int busy, i;
++
++      env = dbmp->env;
++      *dead_mutex = 0;
++      mutex_per_file = 1;
++#ifndef HAVE_ATOMICFILEREAD
++      mutex_per_file = 2;
++#endif
++      mp = dbmp->reginfo[0].primary;
++      hp = R_ADDR(dbmp->reginfo, mp->ftab);
++      for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
++              busy = MUTEX_TRYLOCK(env, hp->mtx_hash);
++              if (busy)
++                      continue;
++              SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
++                      if (mfp->deadfile)
++                              *dead_mutex += mfp->block_cnt + mutex_per_file;
++              }
++              MUTEX_UNLOCK(env, hp->mtx_hash);
++      }
++
++      return (0);
++}
+diff -U 5 -r db-5.3.21.old/src/mp/mp_method.c db-5.3.21/src/mp/mp_method.c
+--- db-5.3.21.old/src/mp/mp_method.c   2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_method.c       2016-10-25 17:22:23.000000000 +0800
+@@ -638,11 +638,11 @@
+       DB_MPOOL_HASH *hp, *nhp;
+       MPOOL *mp;
+       MPOOLFILE *mfp;
+       roff_t newname_off;
+       u_int32_t bucket;
+-      int locked, ret;
++      int locked, purge_dead, ret;
+       size_t nlen;
+       void *p;
+ 
+ #undef        op_is_remove
+ #define       op_is_remove    (newname == NULL)
+@@ -655,10 +655,11 @@
+       dbmp = NULL;
+       mfp = NULL;
+       nhp = NULL;
+       p = NULL;
+       locked = ret = 0;
++      purge_dead = 0;
+ 
+       if (!MPOOL_ON(env))
+               goto fsop;
+ 
+       dbmp = env->mp_handle;
+@@ -747,11 +748,11 @@
+                * they do not get reclaimed as long as they exist.  Since we
+                * are now deleting the database, we need to dec that count.
+                */
+               if (mfp->no_backing_file)
+                       mfp->mpf_cnt--;
+-              mfp->deadfile = 1;
++              __memp_mf_mark_dead(dbmp, mfp, &purge_dead);
+               MUTEX_UNLOCK(env, mfp->mutex);
+       } else {
+               /*
+                * Else, it's a rename.  We've allocated memory for the new
+                * name.  Swap it with the old one.  If it's in memory we
+@@ -806,10 +807,16 @@
+       if (locked == 1) {
+               MUTEX_UNLOCK(env, hp->mtx_hash);
+               if (nhp != NULL && nhp != hp)
+                       MUTEX_UNLOCK(env, nhp->mtx_hash);
+       }
++      /* 
++       * __memp_purge_dead_files() must be called when the hash bucket is
++       * unlocked.
++       */
++      if (purge_dead)
++              (void)__memp_purge_dead_files(env);
+       return (ret);
+ }
+ 
+ /*
+  * __memp_ftruncate __
+diff -U 5 -r db-5.3.21.old/src/mp/mp_sync.c db-5.3.21/src/mp/mp_sync.c
+--- db-5.3.21.old/src/mp/mp_sync.c     2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_sync.c 2016-10-25 17:26:58.000000000 +0800
+@@ -24,10 +24,11 @@
+ static int __bhcmp __P((const void *, const void *));
+ static int __memp_close_flush_files __P((ENV *, int));
+ static int __memp_sync_files __P((ENV *));
+ static int __memp_sync_file __P((ENV *,
+               MPOOLFILE *, void *, u_int32_t *, u_int32_t));
++static inline void __update_err_ret(int, int*);
+ 
+ /*
+  * __memp_walk_files --
+  * PUBLIC: int __memp_walk_files __P((ENV *, MPOOL *,
+  * PUBLIC:    int (*) __P((ENV *, MPOOLFILE *, void *,
+@@ -961,5 +962,125 @@
+               return (-1);
+       if (bhp1->track_pgno > bhp2->track_pgno)
+               return (1);
+       return (0);
+ }
++
++/*
++ * __memp_purge_dead_files --
++ *    Remove all dead files and their buffers from the mpool. The caller
++ *    cannot hold any lock on the dead MPOOLFILE handles, their buffers
++ *    or their hash buckets.
++ *
++ * PUBLIC: int __memp_purge_dead_files __P((ENV *));
++ */
++int
++__memp_purge_dead_files(env)
++      ENV *env;
++{
++      BH *bhp;
++      DB_MPOOL *dbmp;
++      DB_MPOOL_HASH *hp, *hp_end;
++      REGINFO *infop;
++      MPOOL *c_mp, *mp;
++      MPOOLFILE *mfp;
++      u_int32_t i_cache;
++      int ret, t_ret, h_lock;
++
++      if (!MPOOL_ON(env))
++              return (0);
++
++      dbmp = env->mp_handle;
++      mp = dbmp->reginfo[0].primary;
++      ret = t_ret = h_lock = 0;
++
++      /*
++       * Walk each cache's list of buffers and free all buffers whose
++       * MPOOLFILE is marked as dead.
++       */
++      for (i_cache = 0; i_cache < mp->nreg; i_cache++) {
++              infop = &dbmp->reginfo[i_cache]; 
++              c_mp = infop->primary;
++
++              hp = R_ADDR(infop, c_mp->htab);
++              hp_end = &hp[c_mp->htab_buckets];
++              for (; hp < hp_end; hp++) {
++                      /* Skip empty buckets. */
++                      if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL)
++                              continue;
++
++                      /* 
++                       * Search for a dead buffer. Other places that call
++                       * __memp_bhfree() acquire the buffer lock before the
++                       * hash bucket lock. Even though we acquire the two
++                       * locks in reverse order, we cannot deadlock here
++                       * because we don't block waiting for the locks.
++                       */
++                      t_ret = MUTEX_TRYLOCK(env, hp->mtx_hash);
++                      if (t_ret != 0) {
++                              __update_err_ret(t_ret, &ret);
++                              continue;
++                      }
++                      h_lock = 1;
++                      SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh) {
++                              /* Skip buffers that are being used. */
++                              if (BH_REFCOUNT(bhp) > 0)
++                                      continue;
++
++                              mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
++                              if (!mfp->deadfile)
++                                      continue;
++
++                              /* Found a dead buffer. Prepare to free it. */
++                              t_ret = MUTEX_TRYLOCK(env, bhp->mtx_buf);
++                              if (t_ret != 0) {
++                                      __update_err_ret(t_ret, &ret);
++                                      continue;
++                              }
++
++                              DB_ASSERT(env, (!F_ISSET(bhp, BH_EXCLUSIVE) &&
++                                  BH_REFCOUNT(bhp) == 0));
++                              F_SET(bhp, BH_EXCLUSIVE);
++                              (void)atomic_inc(env, &bhp->ref);
++
++                              __memp_bh_clear_dirty(env, hp, bhp);
++
++                              /*
++                               * Free the buffer. The buffer and hash bucket
++                               * are unlocked by __memp_bhfree.
++                               */
++                              if ((t_ret = __memp_bhfree(dbmp, infop, mfp,
++                                  hp, bhp, BH_FREE_FREEMEM)) == 0)
++                                      /*
++                                       * Decrement hp, so the next turn will
++                                       * search the same bucket again.
++                                       */
++                                      hp--;
++                              else
++                                      __update_err_ret(t_ret, &ret);
++
++                              /*
++                               * The hash bucket is unlocked, we need to
++                               * start over again.
++                               */
++                              h_lock = 0;
++                              break;
++                      }
++
++                      if (h_lock) {
++                              MUTEX_UNLOCK(env, hp->mtx_hash);
++                              h_lock = 0;
++                      }
++              }
++      }
++
++      return (ret);
++}
++
++static inline void
++__update_err_ret(t_ret, retp)
++      int t_ret;
++      int *retp;
++{
++      if (t_ret != 0 && t_ret != DB_LOCK_NOTGRANTED && *retp == 0)
++              *retp = t_ret;
++}
+diff -U 5 -r db-5.3.21.old/src/mp/mp_trickle.c db-5.3.21/src/mp/mp_trickle.c
+--- db-5.3.21.old/src/mp/mp_trickle.c  2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_trickle.c      2016-10-25 17:27:57.000000000 +0800
+@@ -65,10 +65,14 @@
+           "DB_ENV->memp_trickle: %d: percent must be between 1 and 100",
+                   "%d"), pct);
+               return (EINVAL);
+       }
+ 
++      /* First we purge all dead files and their buffers. */
++      if ((ret = __memp_purge_dead_files(env)) != 0)
++              return (ret);
++
+       /*
+        * Loop through the caches counting total/dirty buffers.
+        *
+        * XXX
+        * Using hash_page_dirty is our only choice at the moment, but it's not
+diff -U 5 -r db-5.3.21.old/src/mutex/mut_region.c 
db-5.3.21/src/mutex/mut_region.c
+--- db-5.3.21.old/src/mutex/mut_region.c       2012-05-12 01:57:54.000000000 
+0800
++++ db-5.3.21/src/mutex/mut_region.c   2016-10-25 17:34:22.000000000 +0800
+@@ -15,11 +15,11 @@
+ #include "dbinc/txn.h"
+ 
+ static db_size_t __mutex_align_size __P((ENV *));
+ static int __mutex_region_init __P((ENV *, DB_MUTEXMGR *));
+ static size_t __mutex_region_size __P((ENV *));
+-static size_t __mutex_region_max __P((ENV *));
++static size_t __mutex_region_max __P((ENV *, u_int32_t));
+ 
+ /*
+  * __mutex_open --
+  *    Open a mutex region.
+  *
+@@ -32,11 +32,11 @@
+ {
+       DB_ENV *dbenv;
+       DB_MUTEXMGR *mtxmgr;
+       DB_MUTEXREGION *mtxregion;
+       size_t size;
+-      u_int32_t cpu_count;
++      u_int32_t cpu_count, mutex_needed;
+       int ret;
+ #ifndef HAVE_ATOMIC_SUPPORT
+       u_int i;
+ #endif
+ 
+@@ -59,23 +59,24 @@
+                   cpu_count : cpu_count * MUTEX_SPINS_PER_PROCESSOR)) != 0)
+                       return (ret);
+       }
+ 
+       /*
+-       * If the user didn't set an absolute value on the number of mutexes
+-       * we'll need, figure it out.  We're conservative in our allocation,
+-       * we need mutexes for DB handles, group-commit queues and other things
+-       * applications allocate at run-time.  The application may have kicked
+-       * up our count to allocate its own mutexes, add that in.
++       * Figure out the number of mutexes we'll need.  We're conservative in
++       * our allocation, we need mutexes for DB handles, group-commit queues
++       * and other things applications allocate at run-time.  The application
++       * may have kicked up our count to allocate its own mutexes, add that
++       * in.
+        */
++      mutex_needed =
++          __lock_region_mutex_count(env) +
++          __log_region_mutex_count(env) +
++          __memp_region_mutex_count(env) +
++          __txn_region_mutex_count(env);
+       if (dbenv->mutex_cnt == 0 &&
+           F_ISSET(env, ENV_PRIVATE | ENV_THREAD) != ENV_PRIVATE)
+-              dbenv->mutex_cnt =
+-                  __lock_region_mutex_count(env) +
+-                  __log_region_mutex_count(env) +
+-                  __memp_region_mutex_count(env) +
+-                  __txn_region_mutex_count(env);
++              dbenv->mutex_cnt = mutex_needed;
+ 
+       if (dbenv->mutex_max != 0 && dbenv->mutex_cnt > dbenv->mutex_max)
+               dbenv->mutex_cnt = dbenv->mutex_max;
+ 
+       /* Create/initialize the mutex manager structure. */
+@@ -88,12 +89,12 @@
+       mtxmgr->reginfo.id = INVALID_REGION_ID;
+       mtxmgr->reginfo.flags = REGION_JOIN_OK;
+       size = __mutex_region_size(env);
+       if (create_ok)
+               F_SET(&mtxmgr->reginfo, REGION_CREATE_OK);
+-      if ((ret = __env_region_attach(env,
+-          &mtxmgr->reginfo, size, size + __mutex_region_max(env))) != 0)
++      if ((ret = __env_region_attach(env, &mtxmgr->reginfo,
++          size, size + __mutex_region_max(env, mutex_needed))) != 0)
+               goto err;
+ 
+       /* If we created the region, initialize it. */
+       if (F_ISSET(&mtxmgr->reginfo, REGION_CREATE))
+               if ((ret = __mutex_region_init(env, mtxmgr)) != 0)
+@@ -350,44 +351,62 @@
+ 
+       dbenv = env->dbenv;
+ 
+       s = sizeof(DB_MUTEXMGR) + 1024;
+ 
+-      /* We discard one mutex for the OOB slot. */
++      /* 
++       * We discard one mutex for the OOB slot. Make sure mutex_cnt doesn't
++       * overflow.
++       */
+       s += __env_alloc_size(
+-          (dbenv->mutex_cnt + 1) *__mutex_align_size(env));
++          (dbenv->mutex_cnt + (dbenv->mutex_cnt == UINT32_MAX ? 0 : 1)) *
++          __mutex_align_size(env));
+ 
+       return (s);
+ }
+ 
+ /*
+  * __mutex_region_max --
+  *     Return the amount of space needed to reach the maximum size.
+  */
+ static size_t
+-__mutex_region_max(env)
++__mutex_region_max(env, mutex_needed)
+       ENV *env;
++      u_int32_t mutex_needed;
+ {
+       DB_ENV *dbenv;
+-      u_int32_t max;
++      u_int32_t max, mutex_cnt;
+ 
+       dbenv = env->dbenv;
++      mutex_cnt = dbenv->mutex_cnt;
+ 
+-      if ((max = dbenv->mutex_max) == 0) {
++      /*
++       * We want to limit the region size to accommodate at most UINT32_MAX
++       * mutexes. If mutex_cnt is UINT32_MAX, no more space is allowed.
++       */
++      if ((max = dbenv->mutex_max) == 0 && mutex_cnt != UINT32_MAX)
+               if (F_ISSET(env, ENV_PRIVATE | ENV_THREAD) == ENV_PRIVATE)
+-                      max = dbenv->mutex_inc + 1;
+-              else
++                      if (dbenv->mutex_inc + 1 < UINT32_MAX - mutex_cnt)
++                              max = dbenv->mutex_inc + 1 + mutex_cnt;
++                      else
++                              max = UINT32_MAX;
++              else {
+                       max = __lock_region_mutex_max(env) +
+                           __txn_region_mutex_max(env) +
+                           __log_region_mutex_max(env) +
+                           dbenv->mutex_inc + 100;
+-      } else if (max <= dbenv->mutex_cnt)
++                      if (max < UINT32_MAX - mutex_needed)
++                              max += mutex_needed;
++                      else
++                              max = UINT32_MAX;
++              }
++
++      if (max <= mutex_cnt)
+               return (0);
+       else
+-              max -= dbenv->mutex_cnt;
+-
+-      return ( __env_alloc_size(max * __mutex_align_size(env)));
++              return (__env_alloc_size(
++                  (max - mutex_cnt) * __mutex_align_size(env)));
+ }
+ 
+ #ifdef        HAVE_MUTEX_SYSTEM_RESOURCES
+ /*
+  * __mutex_resource_return
+

Deleted: db-5.3.28-atomic_compare_exchange.patch
===================================================================
--- db-5.3.28-atomic_compare_exchange.patch     2022-12-14 18:39:35 UTC (rev 
464335)
+++ db-5.3.28-atomic_compare_exchange.patch     2022-12-14 18:39:38 UTC (rev 
464336)
@@ -1,20 +0,0 @@
---- db-5.3.28/src/dbinc/atomic.h.old   2018-05-23 09:20:04.216914922 +0200
-+++ db-5.3.28/src/dbinc/atomic.h       2018-05-23 09:20:49.510057897 +0200
-@@ -144,7 +144,7 @@
- #define       atomic_inc(env, p)      __atomic_inc(p)
- #define       atomic_dec(env, p)      __atomic_dec(p)
- #define       atomic_compare_exchange(env, p, o, n)   \
--      __atomic_compare_exchange((p), (o), (n))
-+      __db_atomic_compare_exchange((p), (o), (n))
- static inline int __atomic_inc(db_atomic_t *p)
- {
-       int     temp;
-@@ -176,7 +176,7 @@
-  * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
-  * which configure could be changed to use.
-  */
--static inline int __atomic_compare_exchange(
-+static inline int __db_atomic_compare_exchange(
-       db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval)
- {
-       atomic_value_t was;

Copied: db5.3/repos/testing-x86_64/db-5.3.28-atomic_compare_exchange.patch 
(from rev 464335, db5.3/trunk/db-5.3.28-atomic_compare_exchange.patch)
===================================================================
--- db-5.3.28-atomic_compare_exchange.patch                             (rev 0)
+++ db-5.3.28-atomic_compare_exchange.patch     2022-12-14 18:39:38 UTC (rev 
464336)
@@ -0,0 +1,20 @@
+--- db-5.3.28/src/dbinc/atomic.h.old   2018-05-23 09:20:04.216914922 +0200
++++ db-5.3.28/src/dbinc/atomic.h       2018-05-23 09:20:49.510057897 +0200
+@@ -144,7 +144,7 @@
+ #define       atomic_inc(env, p)      __atomic_inc(p)
+ #define       atomic_dec(env, p)      __atomic_dec(p)
+ #define       atomic_compare_exchange(env, p, o, n)   \
+-      __atomic_compare_exchange((p), (o), (n))
++      __db_atomic_compare_exchange((p), (o), (n))
+ static inline int __atomic_inc(db_atomic_t *p)
+ {
+       int     temp;
+@@ -176,7 +176,7 @@
+  * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
+  * which configure could be changed to use.
+  */
+-static inline int __atomic_compare_exchange(
++static inline int __db_atomic_compare_exchange(
+       db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval)
+ {
+       atomic_value_t was;

Deleted: db-5.3.28-lemon_hash.patch
===================================================================
--- db-5.3.28-lemon_hash.patch  2022-12-14 18:39:35 UTC (rev 464335)
+++ db-5.3.28-lemon_hash.patch  2022-12-14 18:39:38 UTC (rev 464336)
@@ -1,20 +0,0 @@
---- db-5.3.28/lang/sql/sqlite/tool/lemon.c.lemon_hash  2013-09-09 
17:35:07.000000000 +0200
-+++ db-5.3.28/lang/sql/sqlite/tool/lemon.c     2017-02-22 13:12:08.564106051 
+0100
-@@ -3428,7 +3428,7 @@
-   int maxdtlength;          /* Maximum length of any ".datatype" field. */
-   char *stddt;              /* Standardized name for a datatype */
-   int i,j;                  /* Loop counters */
--  int hash;                 /* For hashing the name of a type */
-+  unsigned hash;            /* For hashing the name of a type */
-   const char *name;         /* Name of the parser */
- 
-   /* Allocate and initialize types[] and allocate stddt[] */
-@@ -3491,7 +3491,7 @@
-         break;
-       }
-       hash++;
--      if( hash>=arraysize ) hash = 0;
-+      if( hash>=(unsigned)arraysize ) hash = 0;
-     }
-     if( types[hash]==0 ){
-       sp->dtnum = hash + 1;

Copied: db5.3/repos/testing-x86_64/db-5.3.28-lemon_hash.patch (from rev 464335, 
db5.3/trunk/db-5.3.28-lemon_hash.patch)
===================================================================
--- db-5.3.28-lemon_hash.patch                          (rev 0)
+++ db-5.3.28-lemon_hash.patch  2022-12-14 18:39:38 UTC (rev 464336)
@@ -0,0 +1,20 @@
+--- db-5.3.28/lang/sql/sqlite/tool/lemon.c.lemon_hash  2013-09-09 
17:35:07.000000000 +0200
++++ db-5.3.28/lang/sql/sqlite/tool/lemon.c     2017-02-22 13:12:08.564106051 
+0100
+@@ -3428,7 +3428,7 @@
+   int maxdtlength;          /* Maximum length of any ".datatype" field. */
+   char *stddt;              /* Standardized name for a datatype */
+   int i,j;                  /* Loop counters */
+-  int hash;                 /* For hashing the name of a type */
++  unsigned hash;            /* For hashing the name of a type */
+   const char *name;         /* Name of the parser */
+ 
+   /* Allocate and initialize types[] and allocate stddt[] */
+@@ -3491,7 +3491,7 @@
+         break;
+       }
+       hash++;
+-      if( hash>=arraysize ) hash = 0;
++      if( hash>=(unsigned)arraysize ) hash = 0;
+     }
+     if( types[hash]==0 ){
+       sp->dtnum = hash + 1;

Deleted: db-5.3.28-mmap-high-cpu-usage.patch
===================================================================
--- db-5.3.28-mmap-high-cpu-usage.patch 2022-12-14 18:39:35 UTC (rev 464335)
+++ db-5.3.28-mmap-high-cpu-usage.patch 2022-12-14 18:39:38 UTC (rev 464336)
@@ -1,19 +0,0 @@
-Author: Filip Januš <[email protected]>
-Date: 6 Sep 2021
-Related: https://bugzilla.redhat.com/show_bug.cgi?id=1992402
-Patch was created based on the discussion in the previous link
-diff -ur db-5.3.28/src/os/os_map.c db_patch/src/os/os_map.c
---- db-5.3.28/src/os/os_map.c  2013-09-09 17:35:09.000000000 +0200
-+++ db_patch/src/os/os_map.c   2021-09-09 07:33:12.027328265 +0200
-@@ -213,7 +213,10 @@
-       if (rp->max < rp->size)
-               rp->max = rp->size;
-       if (ret == 0 && F_ISSET(infop, REGION_CREATE)) {
--              if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
-+
-+              rp->size = rp->max;
-+
-+        if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
-                       ret = __db_file_write(env, infop->fhp,
-                           rp->size / MEGABYTE, rp->size % MEGABYTE, 0x00);
-               else

Copied: db5.3/repos/testing-x86_64/db-5.3.28-mmap-high-cpu-usage.patch (from 
rev 464335, db5.3/trunk/db-5.3.28-mmap-high-cpu-usage.patch)
===================================================================
--- db-5.3.28-mmap-high-cpu-usage.patch                         (rev 0)
+++ db-5.3.28-mmap-high-cpu-usage.patch 2022-12-14 18:39:38 UTC (rev 464336)
@@ -0,0 +1,19 @@
+Author: Filip Januš <[email protected]>
+Date: 6 Sep 2021
+Related: https://bugzilla.redhat.com/show_bug.cgi?id=1992402
+Patch was created based on the discussion in the previous link
+diff -ur db-5.3.28/src/os/os_map.c db_patch/src/os/os_map.c
+--- db-5.3.28/src/os/os_map.c  2013-09-09 17:35:09.000000000 +0200
++++ db_patch/src/os/os_map.c   2021-09-09 07:33:12.027328265 +0200
+@@ -213,7 +213,10 @@
+       if (rp->max < rp->size)
+               rp->max = rp->size;
+       if (ret == 0 && F_ISSET(infop, REGION_CREATE)) {
+-              if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
++
++              rp->size = rp->max;
++
++        if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
+                       ret = __db_file_write(env, infop->fhp,
+                           rp->size / MEGABYTE, rp->size % MEGABYTE, 0x00);
+               else

Deleted: db-5.3.28_cve-2019-2708.patch
===================================================================
--- db-5.3.28_cve-2019-2708.patch       2022-12-14 18:39:35 UTC (rev 464335)
+++ db-5.3.28_cve-2019-2708.patch       2022-12-14 18:39:38 UTC (rev 464336)
@@ -1,694 +0,0 @@
---- db-18.1.32/src/btree/bt_cursor.c   2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/btree/bt_cursor.c   2020-05-29 23:28:22.000000000 +0530
-@@ -282,6 +282,8 @@
-        *
-        * Recno uses the btree bt_ovflsize value -- it's close enough.
-        */
-+      if (t->bt_minkey == 0)
-+              return (DB_RECOVER);
-       cp->ovflsize = B_MINKEY_TO_OVFLSIZE(
-           dbp,  F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize);
- 
---- db-18.1.32/src/btree/bt_verify.c   2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/btree/bt_verify.c   2020-05-29 23:28:22.000000000 +0530
-@@ -700,7 +700,11 @@
-                       isbad = 1;
-                       goto err;
-               default:
-+                      if (ret == 0) {
-+                              isbad = 1;
-+                              ret = DB_VERIFY_FATAL;
-+                              goto err;
-+                      }
--                      DB_ASSERT(env, ret != 0);
-                       break;
-               }
- 
-@@ -1074,7 +1078,7 @@
-       DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp;
-       ENV *env;
-       PAGE *child;
-+      db_pgno_t cpgno, grandparent;
--      db_pgno_t cpgno;
-       VRFY_PAGEINFO *pip;
-       db_indx_t i, *inp;
-       int adj, cmp, freedup_1, freedup_2, isbad, ret, t_ret;
-@@ -1106,7 +1110,8 @@
- 
-       buf1 = buf2 = NULL;
- 
-+      if (LF_ISSET(DB_NOORDERCHK))
-+              return (EINVAL);
--      DB_ASSERT(env, !LF_ISSET(DB_NOORDERCHK));
- 
-       dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare;
-       if (TYPE(h) == P_LDUP)
-@@ -1115,6 +1120,7 @@
-               func = __bam_defcmp;
-               if (dbp->bt_internal != NULL) {
-                       bt = (BTREE *)dbp->bt_internal;
-+                      grandparent = bt->bt_root;
-                       if (TYPE(h) == P_IBTREE && (bt->bt_compare != NULL ||
-                           dupfunc != __bam_defcmp)) {
-                               /*
-@@ -974,8 +980,24 @@
-                                */
-                               mpf = dbp->mpf;
-                               child = h;
-+                              cpgno = pgno;
-                               while (TYPE(child) == P_IBTREE) {
-+                                      if (NUM_ENT(child) == 0) {
-+                                              EPRINT((env, DB_STR_A("1088",
-+                  "Page %lu: internal page is empty and should not be",
-+                                          "%lu"), (u_long)cpgno));
-+                                              ret = DB_VERIFY_BAD;
-+                                              goto err;
-+                                      }
-                                       bi = GET_BINTERNAL(dbp, child, 0);
-+                                      if (grandparent == bi->pgno) {
-+                                              EPRINT((env, DB_STR_A("5552",
-+                                            "Page %lu: found twice in the 
btree",
-+                                        "%lu"), (u_long)grandparent));
-+                                              ret = DB_VERIFY_FATAL;
-+                                              goto err;
-+                                      } else
-+                                              grandparent = cpgno;
-                                       cpgno = bi->pgno;
-                                       if (child != h &&
-                                           (ret = __memp_fput(mpf,
-@@ -1402,7 +1416,10 @@
-                                        */
-                                       if (dup_1.data == NULL ||
-                                           dup_2.data == NULL) {
-+                                              if (ovflok) {
-+                                                      isbad = 1;
-+                                                      goto err;
-+                                              }
--                                              DB_ASSERT(env, !ovflok);
-                                               if (pip != NULL)
-                                                       F_SET(pip,
-                                                           VRFY_INCOMPLETE);
-@@ -1747,9 +1764,10 @@
-                           (ret = __db_vrfy_ovfl_structure(dbp, vdp,
-                           child->pgno, child->tlen,
-                           flags | DB_ST_OVFL_LEAF)) != 0) {
-+                              if (ret == DB_VERIFY_BAD) {
--                              if (ret == DB_VERIFY_BAD)
-                                       isbad = 1;
-+                                      break;
-+                              } else
--                              else
-                                       goto done;
-                       }
- 
-@@ -1823,9 +1841,10 @@
-                                                   stflags | DB_ST_TOPLEVEL,
-                                                   NULL, NULL, NULL)) != 0) {
-                                                       if (ret ==
-+                                                          DB_VERIFY_BAD) {
--                                                          DB_VERIFY_BAD)
-                                                               isbad = 1;
-+                                                              break;
-+                                                      } else
--                                                      else
-                                                               goto err;
-                                               }
-                                       }
-@@ -1969,7 +1988,10 @@
-                        */
- 
-                       /* Otherwise, __db_vrfy_childput would be broken. */
-+                      if (child->refcnt < 1) {
-+                              isbad = 1;
-+                              goto err;
-+                      }
--                      DB_ASSERT(env, child->refcnt >= 1);
- 
-                       /*
-                        * An overflow referenced more than twice here
-@@ -1986,9 +2008,10 @@
-                                       if ((ret = __db_vrfy_ovfl_structure(dbp,
-                                           vdp, child->pgno, child->tlen,
-                                           flags)) != 0) {
-+                                              if (ret == DB_VERIFY_BAD) {
--                                              if (ret == DB_VERIFY_BAD)
-                                                       isbad = 1;
-+                                                      break;
-+                                              } else
--                                              else
-                                                       goto done;
-                                       }
-               }
-@@ -2026,9 +2049,10 @@
-               if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno,
-                   i == 0 ? NULL : li, ri, flags, &child_level,
-                   &child_nrecs, NULL)) != 0) {
-+                      if (ret == DB_VERIFY_BAD) {
--                      if (ret == DB_VERIFY_BAD)
-                               isbad = 1;
-+                              break;
-+                      } else
--                      else
-                               goto done;
-               }
- 
-@@ -2929,7 +2953,11 @@
-       db_pgno_t current, p;
-       int err_ret, ret;
- 
-+      if (pgset == NULL) {
-+              EPRINT((dbp->env, DB_STR("5542",
-+                      "Error, database contains no visible pages.")));
-+              return (DB_RUNRECOVERY);
-+      }
--      DB_ASSERT(dbp->env, pgset != NULL);
- 
-       mpf = dbp->mpf;
-       h = NULL;
---- db-18.1.32/src/db/db_conv.c        2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/db/db_conv.c        2020-05-29 23:28:22.000000000 +0530
-@@ -493,8 +493,11 @@
-       db_indx_t i, *inp, len, tmp;
-       u_int8_t *end, *p, *pgend;
- 
--      if (pagesize == 0)
--              return (0);
-+      /* This function is also used to byteswap logs, so
-+       * the pagesize might not be an actual page size.
-+       */
-+      if (!(pagesize >= 24 && pagesize <= DB_MAX_PGSIZE))
-+              return (EINVAL);
- 
-       if (pgin) {
-               M_32_SWAP(h->lsn.file);
-@@ -513,26 +516,41 @@
-       pgend = (u_int8_t *)h + pagesize;
- 
-       inp = P_INP(dbp, h);
--      if ((u_int8_t *)inp >= pgend)
--              goto out;
-+      if ((u_int8_t *)inp > pgend)
-+              return (__db_pgfmt(env, pg));
- 
-       switch (TYPE(h)) {
-       case P_HASH_UNSORTED:
-       case P_HASH:
-               for (i = 0; i < NUM_ENT(h); i++) {
-+                      if ((u_int8_t*)(inp + i) >= pgend)
-+                              return (__db_pgfmt(env, pg));
-+                      if (inp[i] == 0)
-+                              continue;
-                       if (pgin)
-                               M_16_SWAP(inp[i]);
-+                      if (inp[i] >= pagesize)
-+                              return (__db_pgfmt(env, pg));
- 
--                      if (P_ENTRY(dbp, h, i) >= pgend)
--                              continue;
-+                      if (P_ENTRY(dbp, h, i) >= pgend)
-+                              return (__db_pgfmt(env, pg));
- 
-                       switch (HPAGE_TYPE(dbp, h, i)) {
-                       case H_KEYDATA:
-                               break;
-                       case H_DUPLICATE:
-+                              if (LEN_HITEM(dbp, h, pagesize, i) < 
-+                                  HKEYDATA_SIZE(0))
-+                                      return (__db_pgfmt(env, pg));
-+
-                               len = LEN_HKEYDATA(dbp, h, pagesize, i);
-                               p = HKEYDATA_DATA(P_ENTRY(dbp, h, i));
--                              for (end = p + len; p < end;) {
-+
-+                              end = p + len;
-+                              if (end > pgend)
-+                                      return (__db_pgfmt(env, pg));
-+
-+                              while (p < end) {
-                                       if (pgin) {
-                                               P_16_SWAP(p);
-                                               memcpy(&tmp,
-@@ -544,14 +562,20 @@
-                                               SWAP16(p);
-                                       }
-                                       p += tmp;
-+                                      if (p >= end)
-+                                              return (__db_pgfmt(env, pg));
-                                       SWAP16(p);
-                               }
-                               break;
-                       case H_OFFDUP:
-+                              if ((inp[i] + HOFFDUP_SIZE) > pagesize)
-+                                      return (__db_pgfmt(env, pg));
-                               p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
-                               SWAP32(p);                      /* pgno */
-                               break;
-                       case H_OFFPAGE:
-+                              if ((inp[i] + HOFFPAGE_SIZE) > pagesize)
-+                                      return (__db_pgfmt(env, pg));
-                               p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
-                               SWAP32(p);                      /* pgno */
-                               SWAP32(p);                      /* tlen */
-@@ -559,7 +583,6 @@
-                       default:
-                               return (__db_pgfmt(env, pg));
-                       }
--
-               }
- 
-               /*
-@@ -576,8 +599,12 @@
-       case P_LDUP:
-       case P_LRECNO:
-               for (i = 0; i < NUM_ENT(h); i++) {
-+                      if ((u_int8_t *)(inp + i) >= pgend)
-+                              return (__db_pgfmt(env, pg));
-                       if (pgin)
-                               M_16_SWAP(inp[i]);
-+                      if (inp[i] >= pagesize)
-+                              return (__db_pgfmt(env, pg));
- 
-                       /*
-                        * In the case of on-page duplicates, key information
-@@ -597,7 +624,7 @@
- 
-                       bk = GET_BKEYDATA(dbp, h, i);
-                       if ((u_int8_t *)bk >= pgend)
--                              continue;
-+                              return (__db_pgfmt(env, pg));
-                       switch (B_TYPE(bk->type)) {
-                       case B_KEYDATA:
-                               M_16_SWAP(bk->len);
-@@ -605,6 +632,8 @@
-                       case B_DUPLICATE:
-                       case B_OVERFLOW:
-                               bo = (BOVERFLOW *)bk;
-+                              if (((u_int8_t *)bo + BOVERFLOW_SIZE) > pgend)
-+                                      return (__db_pgfmt(env, pg));
-                               M_32_SWAP(bo->pgno);
-                               M_32_SWAP(bo->tlen);
-                               break;
-@@ -618,12 +647,17 @@
-               break;
-       case P_IBTREE:
-               for (i = 0; i < NUM_ENT(h); i++) {
-+                      if ((u_int8_t *)(inp + i) > pgend)
-+                              return (__db_pgfmt(env, pg));
-                       if (pgin)
-                               M_16_SWAP(inp[i]);
-+                      if ((u_int16_t)(inp[i] + 
-+                          BINTERNAL_SIZE(0) - 1) > pagesize)
-+                              break;
- 
-                       bi = GET_BINTERNAL(dbp, h, i);
--                      if ((u_int8_t *)bi >= pgend)
--                              continue;
-+                      if (((u_int8_t *)bi + BINTERNAL_SIZE(0)) > pgend)
-+                              return (__db_pgfmt(env, pg));
- 
-                       M_16_SWAP(bi->len);
-                       M_32_SWAP(bi->pgno);
-@@ -634,6 +668,10 @@
-                               break;
-                       case B_DUPLICATE:
-                       case B_OVERFLOW:
-+                              if ((u_int16_t)(inp[i] + 
-+                                  BINTERNAL_SIZE(BOVERFLOW_SIZE) - 1) >
-+                                  pagesize)
-+                                      goto out;
-                               bo = (BOVERFLOW *)bi->data;
-                               M_32_SWAP(bo->pgno);
-                               M_32_SWAP(bo->tlen);
-@@ -648,12 +686,16 @@
-               break;
-       case P_IRECNO:
-               for (i = 0; i < NUM_ENT(h); i++) {
-+                      if ((u_int8_t *)(inp + i) >= pgend)
-+                              return (__db_pgfmt(env, pg));
-                       if (pgin)
-                               M_16_SWAP(inp[i]);
-+                      if (inp[i] >= pagesize)
-+                              return (__db_pgfmt(env, pg));
- 
-                       ri = GET_RINTERNAL(dbp, h, i);
--                      if ((u_int8_t *)ri >= pgend)
--                              continue;
-+                      if ((((u_int8_t *)ri) + RINTERNAL_SIZE) > pgend)
-+                              return (__db_pgfmt(env, pg));
- 
-                       M_32_SWAP(ri->pgno);
-                       M_32_SWAP(ri->nrecs);
---- db-18.1.32/src/db/db_vrfy.c        2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/db/db_vrfy.c        2020-05-29 23:28:22.000000000 +0530
-@@ -381,8 +381,10 @@
-                   vdp, name, 0, lp, rp, flags)) != 0) {
-                       if (t_ret == DB_VERIFY_BAD)
-                               isbad = 1;
-+                      else {
-+                          ret = t_ret;
-+                          goto err;
-+                      }
--                      else
--                              goto err;
-               }
- 
-       /*
-@@ -771,9 +773,10 @@
-                */
-               if ((t_ret = __memp_fget(mpf, &i,
-                   vdp->thread_info, NULL, 0, &h)) != 0) {
-+                      if ((dbp->type == DB_HASH ||
--                      if (dbp->type == DB_HASH ||
-                           (dbp->type == DB_QUEUE &&
-+                          F_ISSET(dbp, DB_AM_INMEM))) &&
-+                          t_ret != DB_RUNRECOVERY) {
--                          F_ISSET(dbp, DB_AM_INMEM))) {
-                               if ((t_ret =
-                                   __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
-                                       goto err1;
-@@ -945,6 +948,8 @@
-                       return (ret == 0 ? t_ret : ret);
-       }
- 
-+      if (ret == DB_PAGE_NOTFOUND && isbad == 1)
-+              ret = 0;
-       return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
- }
- 
-@@ -1581,7 +1586,7 @@
-       if (pgno == PGNO_BASE_MD &&
-           dbtype != DB_QUEUE && meta->last_pgno != vdp->last_pgno) {
- #ifdef HAVE_FTRUNCATE
-+              ret = DB_VERIFY_FATAL;
--              isbad = 1;
-               EPRINT((env, DB_STR_A("0552",
-                   "Page %lu: last_pgno is not correct: %lu != %lu",
-                   "%lu %lu %lu"), (u_long)pgno,
-@@ -1622,7 +1627,11 @@
- 
-       env = dbp->env;
-       pgset = vdp->pgset;
-+      if (pgset == NULL) {
-+              EPRINT((env, DB_STR("5543",
-+                      "Error, database contains no visible pages.")));
-+              return (DB_RUNRECOVERY);
-+      }
--      DB_ASSERT(env, pgset != NULL);
- 
-       if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0)
-               return (ret);
-@@ -2014,7 +2023,8 @@
-       int keyflag, ret, t_ret;
- 
-       env = dbp->env;
-+      if (!LF_ISSET(DB_SALVAGE))
-+              return (EINVAL);
--      DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
- 
-       /*
-        * !!!
-@@ -2126,10 +2136,8 @@
-       int (*callback) __P((void *, const void *));
-       u_int32_t flags;
- {
--      ENV *env;
--
--      env = dbp->env;
--      DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
-+      if (!LF_ISSET(DB_SALVAGE))
-+              return (EINVAL);
- 
-       /* If we got this page in the subdb pass, we can safely skip it. */
-       if (__db_salvage_isdone(vdp, pgno))
-@@ -2242,8 +2253,8 @@
-                               ret = t_ret;
-                       break;
-               case SALVAGE_OVERFLOW:
-+                      EPRINT((env, DB_STR("5544", "Invalid page type to 
salvage.")));
-+                      return (EINVAL);
--                      DB_ASSERT(env, 0);      /* Shouldn't ever happen. */
--                      break;
-               case SALVAGE_HASH:
-                       if ((t_ret = __ham_salvage(dbp, vdp,
-                           pgno, h, handle, callback, flags)) != 0 && ret == 0)
-@@ -2256,8 +2267,8 @@
-                        * Shouldn't happen, but if it does, just do what the
-                        * nice man says.
-                        */
-+                      EPRINT((env, DB_STR("5545", "Invalid page type to 
salvage.")));
-+                      return (EINVAL);
--                      DB_ASSERT(env, 0);
--                      break;
-               }
-               if ((t_ret = __memp_fput(mpf,
-                   vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
-@@ -2303,8 +2314,8 @@
-                                       ret = t_ret;
-                       break;
-               default:
-+                      EPRINT((env, DB_STR("5546", "Invalid page type to 
salvage.")));
-+                      return (EINVAL);
--                      DB_ASSERT(env, 0);      /* Shouldn't ever happen. */
--                      break;
-               }
-               if ((t_ret = __memp_fput(mpf,
-                   vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
-@@ -2361,7 +2372,10 @@
- 
-       env = dbp->env;
- 
-+      if (himarkp == NULL) {
-+              __db_msg(env, "Page %lu index has no end.", (u_long)pgno);
-+              return (DB_VERIFY_FATAL);
-+      }
--      DB_ASSERT(env, himarkp != NULL);
-       inp = P_INP(dbp, h);
- 
-       /*
-@@ -2783,7 +2797,11 @@
-                                       goto err;
-                               ovfl_bufsz = bkkey->len + 1;
-                       }
-+                      if (subdbname == NULL) {
-+                              EPRINT((env, DB_STR("5547", "Subdatabase cannot 
be null.")));
-+                              ret = EINVAL;
-+                              goto err;
-+                      }
--                      DB_ASSERT(env, subdbname != NULL);
-                       memcpy(subdbname, bkkey->data, bkkey->len);
-                       subdbname[bkkey->len] = '\0';
-               }
---- db-18.1.32/src/db/db_vrfyutil.c    2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/db/db_vrfyutil.c    2020-05-29 23:28:22.000000000 +0530
-@@ -214,7 +214,8 @@
-       if ((ret = __db_get(pgdbp,
-           vdp->thread_info, vdp->txn, &key, &data, 0)) == 0) {
-               /* Found it. */
-+              if (data.size != sizeof(VRFY_PAGEINFO))
-+                      return (DB_VERIFY_FATAL);
--              DB_ASSERT(env, data.size == sizeof(VRFY_PAGEINFO));
-               pip = data.data;
-               LIST_INSERT_HEAD(&vdp->activepips, pip, links);
-               goto found;
-@@ -342,7 +343,8 @@
-       F_SET(&data, DB_DBT_USERMEM);
- 
-       if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
-+              if (data.size != sizeof(int))
-+                      return (EINVAL);
--              DB_ASSERT(dbp->env, data.size == sizeof(int));
-       } else if (ret == DB_NOTFOUND)
-               val = 0;
-       else
-@@ -382,7 +384,8 @@
-       F_SET(&data, DB_DBT_USERMEM);
- 
-       if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
-+              if (data.size != sizeof(int))
-+                      return (DB_VERIFY_FATAL);
--              DB_ASSERT(dbp->env, data.size == sizeof(int));
-       } else if (ret != DB_NOTFOUND)
-               return (ret);
- 
-@@ -419,7 +422,8 @@
-       if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) != 0)
-               return (ret);
- 
-+      if (key.size != sizeof(db_pgno_t))
-+              return (DB_VERIFY_FATAL);
--      DB_ASSERT(dbc->env, key.size == sizeof(db_pgno_t));
-       *pgnop = pgno;
- 
-       return (0);
-@@ -566,7 +570,8 @@
-       if ((ret = __dbc_get(dbc, &key, &data, DB_SET)) != 0)
-               return (ret);
- 
-+      if (data.size != sizeof(VRFY_CHILDINFO))
-+              return (DB_VERIFY_FATAL);
--      DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
-       *cipp = (VRFY_CHILDINFO *)data.data;
- 
-       return (0);
-@@ -594,7 +599,8 @@
-       if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)
-               return (ret);
- 
-+      if (data.size != sizeof(VRFY_CHILDINFO))
-+              return (DB_VERIFY_FATAL);
--      DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
-       *cipp = (VRFY_CHILDINFO *)data.data;
- 
-       return (0);
-@@ -721,7 +727,8 @@
-               return (ret);
- 
-       while ((ret = __dbc_get(*dbcp, &key, &data, DB_NEXT)) == 0) {
-+              if (data.size != sizeof(u_int32_t))
-+                      return (DB_VERIFY_FATAL);
--              DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
-               memcpy(&pgtype, data.data, sizeof(pgtype));
- 
-               if (skip_overflow && pgtype == SALVAGE_OVERFLOW)
-@@ -730,8 +737,9 @@
-               if ((ret = __dbc_del(*dbcp, 0)) != 0)
-                       return (ret);
-               if (pgtype != SALVAGE_IGNORE) {
-+                      if (key.size != sizeof(db_pgno_t)
-+                              || data.size != sizeof(u_int32_t))
-+                              return (DB_VERIFY_FATAL);
--                      DB_ASSERT(dbp->env, key.size == sizeof(db_pgno_t));
--                      DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
- 
-                       *pgnop = *(db_pgno_t *)key.data;
-                       *pgtypep = *(u_int32_t *)data.data;
---- db-18.1.32/src/db/partition.c      2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/db/partition.c      2020-05-29 23:28:22.000000000 +0530
-@@ -461,9 +461,19 @@
-               } else
-                       part->nparts = meta->nparts;
-       } else if (meta->nparts != 0 && part->nparts != meta->nparts) {
-+              ret = EINVAL;
-               __db_errx(env, DB_STR("0656",
-                   "Number of partitions does not match."));
--              ret = EINVAL;
-+              goto err;
-+      }
-+      /*
-+       * There is no limit on the number of partitions, but I cannot imagine 
a real
-+       * database having more than 10000.
-+       */
-+      if (meta->nparts > 10000) {
-+              ret = EINVAL;
-+              __db_errx(env, DB_STR_A("5553",
-+                      "Too many partitions %lu", "%lu"), 
(u_long)(meta->nparts));
-               goto err;
-       }
- 
-@@ -2106,10 +2116,13 @@
-                       memcpy(rp->data, key->data, key->size);
-                       B_TSET(rp->type, B_KEYDATA);
-               }
-+vrfy:   if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
-+            NULL, handle, callback,
-+            lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0) {
-+              ret = t_ret;
-+            if (ret == ENOENT)
-+                break;
-+          }
--vrfy:         if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
--                  NULL, handle, callback,
--                  lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0)
--                      ret = t_ret;
-       }
- 
- err:  if (lp != NULL)
---- db-18.1.32/src/hash/hash_page.c    2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/hash/hash_page.c    2020-05-29 23:28:22.000000000 +0530
-@@ -869,7 +869,11 @@
-       /* Validate that next, prev pointers are OK */
-       n = NUM_ENT(p);
-       dbp = dbc->dbp;
-+      if (n % 2 != 0) {
-+              __db_errx(dbp->env, DB_STR_A("5549",
-+                "Odd number of entries on page: %lu", "%lu"), 
(u_long)(p->pgno));
-+              return (DB_VERIFY_FATAL);
-+      }
--      DB_ASSERT(dbp->env, n%2 == 0 );
- 
-       env = dbp->env;
-       t = dbp->h_internal;
-@@ -940,7 +944,12 @@
-                       if ((ret = __db_prpage(dbp, p, DB_PR_PAGE)) != 0)
-                               return (ret);
- #endif
-+                      if (res >= 0) {
-+                              __db_errx(env, DB_STR_A("5550",
-+                                      "Odd number of entries on page: %lu", 
"%lu"),
-+                                      (u_long)p->pgno);
-+                              return (DB_VERIFY_FATAL);
-+                      }
--                      DB_ASSERT(dbp->env, res < 0);
-               }
- 
-               prev = curr;
---- db-18.1.32/src/hash/hash_verify.c  2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/hash/hash_verify.c  2020-05-29 23:28:22.000000000 +0530
-@@ -615,7 +615,7 @@
-                               isbad = 1;
-                       else
-                               goto err;
-+              }
--                  }
- 
-       /*
-        * There may be unused hash pages corresponding to buckets
-@@ -746,7 +746,7 @@
-                   "Page %lu: impossible first page in bucket %lu", "%lu %lu"),
-                   (u_long)pgno, (u_long)bucket));
-               /* Unsafe to continue. */
-+              ret = DB_VERIFY_FATAL;
--              isbad = 1;
-               goto err;
-       }
- 
-@@ -776,7 +776,7 @@
-                       EPRINT((env, DB_STR_A("1116",
-                           "Page %lu: hash page referenced twice", "%lu"),
-                           (u_long)pgno));
-+                      ret = DB_VERIFY_FATAL;
--                      isbad = 1;
-                       /* Unsafe to continue. */
-                       goto err;
-               } else if ((ret = __db_vrfy_pgset_inc(vdp->pgset,
-@@ -1307,7 +1307,11 @@
-       COMPQUIET(flags, 0);
-       ip = vdp->thread_info;
- 
-+      if (pgset == NULL) {
-+              EPRINT((dbp->env, DB_STR("5548",
-+                      "Error, database contains no visible pages.")));
-+              return (DB_VERIFY_FATAL);
-+      }
--      DB_ASSERT(dbp->env, pgset != NULL);
- 
-       mpf = dbp->mpf;
-       totpgs = 0;
---- db-18.1.32/src/qam/qam_verify.c    2019-02-20 03:21:20.000000000 +0530
-+++ db-18.1.40/src/qam/qam_verify.c    2020-05-29 23:28:22.000000000 +0530
-@@ -465,7 +465,14 @@
-       /* Verify/salvage each page. */
-       if ((ret = __db_cursor(dbp, vdp->thread_info, NULL, &dbc, 0)) != 0)
-               return (ret);
--begin:        for (; i <= stop; i++) {
-+begin:        if ((stop - i) > 100000) {
-+              EPRINT((env, DB_STR_A("5551",
-+"Warning, many possible extends files (%lu), will take a long time to verify",
-+          "%lu"), (u_long)(stop - i)));
-+      }
-+      for (; i <= stop; i++) {
-+              if (i == UINT32_MAX)
-+                      break;
-               /*
-                * If DB_SALVAGE is set, we inspect our database of completed
-                * pages, and skip any we've already printed in the subdb pass.

Copied: db5.3/repos/testing-x86_64/db-5.3.28_cve-2019-2708.patch (from rev 
464335, db5.3/trunk/db-5.3.28_cve-2019-2708.patch)
===================================================================
--- db-5.3.28_cve-2019-2708.patch                               (rev 0)
+++ db-5.3.28_cve-2019-2708.patch       2022-12-14 18:39:38 UTC (rev 464336)
@@ -0,0 +1,694 @@
+--- db-18.1.32/src/btree/bt_cursor.c   2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/btree/bt_cursor.c   2020-05-29 23:28:22.000000000 +0530
+@@ -282,6 +282,8 @@
+        *
+        * Recno uses the btree bt_ovflsize value -- it's close enough.
+        */
++      if (t->bt_minkey == 0)
++              return (DB_RECOVER);
+       cp->ovflsize = B_MINKEY_TO_OVFLSIZE(
+           dbp,  F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize);
+ 
+--- db-18.1.32/src/btree/bt_verify.c   2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/btree/bt_verify.c   2020-05-29 23:28:22.000000000 +0530
+@@ -700,7 +700,11 @@
+                       isbad = 1;
+                       goto err;
+               default:
++                      if (ret == 0) {
++                              isbad = 1;
++                              ret = DB_VERIFY_FATAL;
++                              goto err;
++                      }
+-                      DB_ASSERT(env, ret != 0);
+                       break;
+               }
+ 
+@@ -1074,7 +1078,7 @@
+       DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp;
+       ENV *env;
+       PAGE *child;
++      db_pgno_t cpgno, grandparent;
+-      db_pgno_t cpgno;
+       VRFY_PAGEINFO *pip;
+       db_indx_t i, *inp;
+       int adj, cmp, freedup_1, freedup_2, isbad, ret, t_ret;
+@@ -1106,7 +1110,8 @@
+ 
+       buf1 = buf2 = NULL;
+ 
++      if (LF_ISSET(DB_NOORDERCHK))
++              return (EINVAL);
+-      DB_ASSERT(env, !LF_ISSET(DB_NOORDERCHK));
+ 
+       dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare;
+       if (TYPE(h) == P_LDUP)
+@@ -1115,6 +1120,7 @@
+               func = __bam_defcmp;
+               if (dbp->bt_internal != NULL) {
+                       bt = (BTREE *)dbp->bt_internal;
++                      grandparent = bt->bt_root;
+                       if (TYPE(h) == P_IBTREE && (bt->bt_compare != NULL ||
+                           dupfunc != __bam_defcmp)) {
+                               /*
+@@ -974,8 +980,24 @@
+                                */
+                               mpf = dbp->mpf;
+                               child = h;
++                              cpgno = pgno;
+                               while (TYPE(child) == P_IBTREE) {
++                                      if (NUM_ENT(child) == 0) {
++                                              EPRINT((env, DB_STR_A("1088",
++                  "Page %lu: internal page is empty and should not be",
++                                          "%lu"), (u_long)cpgno));
++                                              ret = DB_VERIFY_BAD;
++                                              goto err;
++                                      }
+                                       bi = GET_BINTERNAL(dbp, child, 0);
++                                      if (grandparent == bi->pgno) {
++                                              EPRINT((env, DB_STR_A("5552",
++                                            "Page %lu: found twice in the 
btree",
++                                        "%lu"), (u_long)grandparent));
++                                              ret = DB_VERIFY_FATAL;
++                                              goto err;
++                                      } else
++                                              grandparent = cpgno;
+                                       cpgno = bi->pgno;
+                                       if (child != h &&
+                                           (ret = __memp_fput(mpf,
+@@ -1402,7 +1416,10 @@
+                                        */
+                                       if (dup_1.data == NULL ||
+                                           dup_2.data == NULL) {
++                                              if (ovflok) {
++                                                      isbad = 1;
++                                                      goto err;
++                                              }
+-                                              DB_ASSERT(env, !ovflok);
+                                               if (pip != NULL)
+                                                       F_SET(pip,
+                                                           VRFY_INCOMPLETE);
+@@ -1747,9 +1764,10 @@
+                           (ret = __db_vrfy_ovfl_structure(dbp, vdp,
+                           child->pgno, child->tlen,
+                           flags | DB_ST_OVFL_LEAF)) != 0) {
++                              if (ret == DB_VERIFY_BAD) {
+-                              if (ret == DB_VERIFY_BAD)
+                                       isbad = 1;
++                                      break;
++                              } else
+-                              else
+                                       goto done;
+                       }
+ 
+@@ -1823,9 +1841,10 @@
+                                                   stflags | DB_ST_TOPLEVEL,
+                                                   NULL, NULL, NULL)) != 0) {
+                                                       if (ret ==
++                                                          DB_VERIFY_BAD) {
+-                                                          DB_VERIFY_BAD)
+                                                               isbad = 1;
++                                                              break;
++                                                      } else
+-                                                      else
+                                                               goto err;
+                                               }
+                                       }
+@@ -1969,7 +1988,10 @@
+                        */
+ 
+                       /* Otherwise, __db_vrfy_childput would be broken. */
++                      if (child->refcnt < 1) {
++                              isbad = 1;
++                              goto err;
++                      }
+-                      DB_ASSERT(env, child->refcnt >= 1);
+ 
+                       /*
+                        * An overflow referenced more than twice here
+@@ -1986,9 +2008,10 @@
+                                       if ((ret = __db_vrfy_ovfl_structure(dbp,
+                                           vdp, child->pgno, child->tlen,
+                                           flags)) != 0) {
++                                              if (ret == DB_VERIFY_BAD) {
+-                                              if (ret == DB_VERIFY_BAD)
+                                                       isbad = 1;
++                                                      break;
++                                              } else
+-                                              else
+                                                       goto done;
+                                       }
+               }
+@@ -2026,9 +2049,10 @@
+               if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno,
+                   i == 0 ? NULL : li, ri, flags, &child_level,
+                   &child_nrecs, NULL)) != 0) {
++                      if (ret == DB_VERIFY_BAD) {
+-                      if (ret == DB_VERIFY_BAD)
+                               isbad = 1;
++                              break;
++                      } else
+-                      else
+                               goto done;
+               }
+ 
+@@ -2929,7 +2953,11 @@
+       db_pgno_t current, p;
+       int err_ret, ret;
+ 
++      if (pgset == NULL) {
++              EPRINT((dbp->env, DB_STR("5542",
++                      "Error, database contains no visible pages.")));
++              return (DB_RUNRECOVERY);
++      }
+-      DB_ASSERT(dbp->env, pgset != NULL);
+ 
+       mpf = dbp->mpf;
+       h = NULL;
+--- db-18.1.32/src/db/db_conv.c        2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/db/db_conv.c        2020-05-29 23:28:22.000000000 +0530
+@@ -493,8 +493,11 @@
+       db_indx_t i, *inp, len, tmp;
+       u_int8_t *end, *p, *pgend;
+ 
+-      if (pagesize == 0)
+-              return (0);
++      /* This function is also used to byteswap logs, so
++       * the pagesize might not be an actual page size.
++       */
++      if (!(pagesize >= 24 && pagesize <= DB_MAX_PGSIZE))
++              return (EINVAL);
+ 
+       if (pgin) {
+               M_32_SWAP(h->lsn.file);
+@@ -513,26 +516,41 @@
+       pgend = (u_int8_t *)h + pagesize;
+ 
+       inp = P_INP(dbp, h);
+-      if ((u_int8_t *)inp >= pgend)
+-              goto out;
++      if ((u_int8_t *)inp > pgend)
++              return (__db_pgfmt(env, pg));
+ 
+       switch (TYPE(h)) {
+       case P_HASH_UNSORTED:
+       case P_HASH:
+               for (i = 0; i < NUM_ENT(h); i++) {
++                      if ((u_int8_t*)(inp + i) >= pgend)
++                              return (__db_pgfmt(env, pg));
++                      if (inp[i] == 0)
++                              continue;
+                       if (pgin)
+                               M_16_SWAP(inp[i]);
++                      if (inp[i] >= pagesize)
++                              return (__db_pgfmt(env, pg));
+ 
+-                      if (P_ENTRY(dbp, h, i) >= pgend)
+-                              continue;
++                      if (P_ENTRY(dbp, h, i) >= pgend)
++                              return (__db_pgfmt(env, pg));
+ 
+                       switch (HPAGE_TYPE(dbp, h, i)) {
+                       case H_KEYDATA:
+                               break;
+                       case H_DUPLICATE:
++                              if (LEN_HITEM(dbp, h, pagesize, i) < 
++                                  HKEYDATA_SIZE(0))
++                                      return (__db_pgfmt(env, pg));
++
+                               len = LEN_HKEYDATA(dbp, h, pagesize, i);
+                               p = HKEYDATA_DATA(P_ENTRY(dbp, h, i));
+-                              for (end = p + len; p < end;) {
++
++                              end = p + len;
++                              if (end > pgend)
++                                      return (__db_pgfmt(env, pg));
++
++                              while (p < end) {
+                                       if (pgin) {
+                                               P_16_SWAP(p);
+                                               memcpy(&tmp,
+@@ -544,14 +562,20 @@
+                                               SWAP16(p);
+                                       }
+                                       p += tmp;
++                                      if (p >= end)
++                                              return (__db_pgfmt(env, pg));
+                                       SWAP16(p);
+                               }
+                               break;
+                       case H_OFFDUP:
++                              if ((inp[i] + HOFFDUP_SIZE) > pagesize)
++                                      return (__db_pgfmt(env, pg));
+                               p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
+                               SWAP32(p);                      /* pgno */
+                               break;
+                       case H_OFFPAGE:
++                              if ((inp[i] + HOFFPAGE_SIZE) > pagesize)
++                                      return (__db_pgfmt(env, pg));
+                               p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
+                               SWAP32(p);                      /* pgno */
+                               SWAP32(p);                      /* tlen */
+@@ -559,7 +583,6 @@
+                       default:
+                               return (__db_pgfmt(env, pg));
+                       }
+-
+               }
+ 
+               /*
+@@ -576,8 +599,12 @@
+       case P_LDUP:
+       case P_LRECNO:
+               for (i = 0; i < NUM_ENT(h); i++) {
++                      if ((u_int8_t *)(inp + i) >= pgend)
++                              return (__db_pgfmt(env, pg));
+                       if (pgin)
+                               M_16_SWAP(inp[i]);
++                      if (inp[i] >= pagesize)
++                              return (__db_pgfmt(env, pg));
+ 
+                       /*
+                        * In the case of on-page duplicates, key information
+@@ -597,7 +624,7 @@
+ 
+                       bk = GET_BKEYDATA(dbp, h, i);
+                       if ((u_int8_t *)bk >= pgend)
+-                              continue;
++                              return (__db_pgfmt(env, pg));
+                       switch (B_TYPE(bk->type)) {
+                       case B_KEYDATA:
+                               M_16_SWAP(bk->len);
+@@ -605,6 +632,8 @@
+                       case B_DUPLICATE:
+                       case B_OVERFLOW:
+                               bo = (BOVERFLOW *)bk;
++                              if (((u_int8_t *)bo + BOVERFLOW_SIZE) > pgend)
++                                      return (__db_pgfmt(env, pg));
+                               M_32_SWAP(bo->pgno);
+                               M_32_SWAP(bo->tlen);
+                               break;
+@@ -618,12 +647,17 @@
+               break;
+       case P_IBTREE:
+               for (i = 0; i < NUM_ENT(h); i++) {
++                      if ((u_int8_t *)(inp + i) > pgend)
++                              return (__db_pgfmt(env, pg));
+                       if (pgin)
+                               M_16_SWAP(inp[i]);
++                      if ((u_int16_t)(inp[i] + 
++                          BINTERNAL_SIZE(0) - 1) > pagesize)
++                              break;
+ 
+                       bi = GET_BINTERNAL(dbp, h, i);
+-                      if ((u_int8_t *)bi >= pgend)
+-                              continue;
++                      if (((u_int8_t *)bi + BINTERNAL_SIZE(0)) > pgend)
++                              return (__db_pgfmt(env, pg));
+ 
+                       M_16_SWAP(bi->len);
+                       M_32_SWAP(bi->pgno);
+@@ -634,6 +668,10 @@
+                               break;
+                       case B_DUPLICATE:
+                       case B_OVERFLOW:
++                              if ((u_int16_t)(inp[i] + 
++                                  BINTERNAL_SIZE(BOVERFLOW_SIZE) - 1) >
++                                  pagesize)
++                                      goto out;
+                               bo = (BOVERFLOW *)bi->data;
+                               M_32_SWAP(bo->pgno);
+                               M_32_SWAP(bo->tlen);
+@@ -648,12 +686,16 @@
+               break;
+       case P_IRECNO:
+               for (i = 0; i < NUM_ENT(h); i++) {
++                      if ((u_int8_t *)(inp + i) >= pgend)
++                              return (__db_pgfmt(env, pg));
+                       if (pgin)
+                               M_16_SWAP(inp[i]);
++                      if (inp[i] >= pagesize)
++                              return (__db_pgfmt(env, pg));
+ 
+                       ri = GET_RINTERNAL(dbp, h, i);
+-                      if ((u_int8_t *)ri >= pgend)
+-                              continue;
++                      if ((((u_int8_t *)ri) + RINTERNAL_SIZE) > pgend)
++                              return (__db_pgfmt(env, pg));
+ 
+                       M_32_SWAP(ri->pgno);
+                       M_32_SWAP(ri->nrecs);
+--- db-18.1.32/src/db/db_vrfy.c        2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/db/db_vrfy.c        2020-05-29 23:28:22.000000000 +0530
+@@ -381,8 +381,10 @@
+                   vdp, name, 0, lp, rp, flags)) != 0) {
+                       if (t_ret == DB_VERIFY_BAD)
+                               isbad = 1;
++                      else {
++                          ret = t_ret;
++                          goto err;
++                      }
+-                      else
+-                              goto err;
+               }
+ 
+       /*
+@@ -771,9 +773,10 @@
+                */
+               if ((t_ret = __memp_fget(mpf, &i,
+                   vdp->thread_info, NULL, 0, &h)) != 0) {
++                      if ((dbp->type == DB_HASH ||
+-                      if (dbp->type == DB_HASH ||
+                           (dbp->type == DB_QUEUE &&
++                          F_ISSET(dbp, DB_AM_INMEM))) &&
++                          t_ret != DB_RUNRECOVERY) {
+-                          F_ISSET(dbp, DB_AM_INMEM))) {
+                               if ((t_ret =
+                                   __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
+                                       goto err1;
+@@ -945,6 +948,8 @@
+                       return (ret == 0 ? t_ret : ret);
+       }
+ 
++      if (ret == DB_PAGE_NOTFOUND && isbad == 1)
++              ret = 0;
+       return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
+ }
+ 
+@@ -1581,7 +1586,7 @@
+       if (pgno == PGNO_BASE_MD &&
+           dbtype != DB_QUEUE && meta->last_pgno != vdp->last_pgno) {
+ #ifdef HAVE_FTRUNCATE
++              ret = DB_VERIFY_FATAL;
+-              isbad = 1;
+               EPRINT((env, DB_STR_A("0552",
+                   "Page %lu: last_pgno is not correct: %lu != %lu",
+                   "%lu %lu %lu"), (u_long)pgno,
+@@ -1622,7 +1627,11 @@
+ 
+       env = dbp->env;
+       pgset = vdp->pgset;
++      if (pgset == NULL) {
++              EPRINT((env, DB_STR("5543",
++                      "Error, database contains no visible pages.")));
++              return (DB_RUNRECOVERY);
++      }
+-      DB_ASSERT(env, pgset != NULL);
+ 
+       if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0)
+               return (ret);
+@@ -2014,7 +2023,8 @@
+       int keyflag, ret, t_ret;
+ 
+       env = dbp->env;
++      if (!LF_ISSET(DB_SALVAGE))
++              return (EINVAL);
+-      DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
+ 
+       /*
+        * !!!
+@@ -2126,10 +2136,8 @@
+       int (*callback) __P((void *, const void *));
+       u_int32_t flags;
+ {
+-      ENV *env;
+-
+-      env = dbp->env;
+-      DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
++      if (!LF_ISSET(DB_SALVAGE))
++              return (EINVAL);
+ 
+       /* If we got this page in the subdb pass, we can safely skip it. */
+       if (__db_salvage_isdone(vdp, pgno))
+@@ -2242,8 +2253,8 @@
+                               ret = t_ret;
+                       break;
+               case SALVAGE_OVERFLOW:
++                      EPRINT((env, DB_STR("5544", "Invalid page type to 
salvage.")));
++                      return (EINVAL);
+-                      DB_ASSERT(env, 0);      /* Shouldn't ever happen. */
+-                      break;
+               case SALVAGE_HASH:
+                       if ((t_ret = __ham_salvage(dbp, vdp,
+                           pgno, h, handle, callback, flags)) != 0 && ret == 0)
+@@ -2256,8 +2267,8 @@
+                        * Shouldn't happen, but if it does, just do what the
+                        * nice man says.
+                        */
++                      EPRINT((env, DB_STR("5545", "Invalid page type to 
salvage.")));
++                      return (EINVAL);
+-                      DB_ASSERT(env, 0);
+-                      break;
+               }
+               if ((t_ret = __memp_fput(mpf,
+                   vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+@@ -2303,8 +2314,8 @@
+                                       ret = t_ret;
+                       break;
+               default:
++                      EPRINT((env, DB_STR("5546", "Invalid page type to 
salvage.")));
++                      return (EINVAL);
+-                      DB_ASSERT(env, 0);      /* Shouldn't ever happen. */
+-                      break;
+               }
+               if ((t_ret = __memp_fput(mpf,
+                   vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+@@ -2361,7 +2372,10 @@
+ 
+       env = dbp->env;
+ 
++      if (himarkp == NULL) {
++              __db_msg(env, "Page %lu index has no end.", (u_long)pgno);
++              return (DB_VERIFY_FATAL);
++      }
+-      DB_ASSERT(env, himarkp != NULL);
+       inp = P_INP(dbp, h);
+ 
+       /*
+@@ -2783,7 +2797,11 @@
+                                       goto err;
+                               ovfl_bufsz = bkkey->len + 1;
+                       }
++                      if (subdbname == NULL) {
++                              EPRINT((env, DB_STR("5547", "Subdatabase cannot 
be null.")));
++                              ret = EINVAL;
++                              goto err;
++                      }
+-                      DB_ASSERT(env, subdbname != NULL);
+                       memcpy(subdbname, bkkey->data, bkkey->len);
+                       subdbname[bkkey->len] = '\0';
+               }
+--- db-18.1.32/src/db/db_vrfyutil.c    2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/db/db_vrfyutil.c    2020-05-29 23:28:22.000000000 +0530
+@@ -214,7 +214,8 @@
+       if ((ret = __db_get(pgdbp,
+           vdp->thread_info, vdp->txn, &key, &data, 0)) == 0) {
+               /* Found it. */
++              if (data.size != sizeof(VRFY_PAGEINFO))
++                      return (DB_VERIFY_FATAL);
+-              DB_ASSERT(env, data.size == sizeof(VRFY_PAGEINFO));
+               pip = data.data;
+               LIST_INSERT_HEAD(&vdp->activepips, pip, links);
+               goto found;
+@@ -342,7 +343,8 @@
+       F_SET(&data, DB_DBT_USERMEM);
+ 
+       if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
++              if (data.size != sizeof(int))
++                      return (EINVAL);
+-              DB_ASSERT(dbp->env, data.size == sizeof(int));
+       } else if (ret == DB_NOTFOUND)
+               val = 0;
+       else
+@@ -382,7 +384,8 @@
+       F_SET(&data, DB_DBT_USERMEM);
+ 
+       if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
++              if (data.size != sizeof(int))
++                      return (DB_VERIFY_FATAL);
+-              DB_ASSERT(dbp->env, data.size == sizeof(int));
+       } else if (ret != DB_NOTFOUND)
+               return (ret);
+ 
+@@ -419,7 +422,8 @@
+       if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) != 0)
+               return (ret);
+ 
++      if (key.size != sizeof(db_pgno_t))
++              return (DB_VERIFY_FATAL);
+-      DB_ASSERT(dbc->env, key.size == sizeof(db_pgno_t));
+       *pgnop = pgno;
+ 
+       return (0);
+@@ -566,7 +570,8 @@
+       if ((ret = __dbc_get(dbc, &key, &data, DB_SET)) != 0)
+               return (ret);
+ 
++      if (data.size != sizeof(VRFY_CHILDINFO))
++              return (DB_VERIFY_FATAL);
+-      DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
+       *cipp = (VRFY_CHILDINFO *)data.data;
+ 
+       return (0);
+@@ -594,7 +599,8 @@
+       if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)
+               return (ret);
+ 
++      if (data.size != sizeof(VRFY_CHILDINFO))
++              return (DB_VERIFY_FATAL);
+-      DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
+       *cipp = (VRFY_CHILDINFO *)data.data;
+ 
+       return (0);
+@@ -721,7 +727,8 @@
+               return (ret);
+ 
+       while ((ret = __dbc_get(*dbcp, &key, &data, DB_NEXT)) == 0) {
++              if (data.size != sizeof(u_int32_t))
++                      return (DB_VERIFY_FATAL);
+-              DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
+               memcpy(&pgtype, data.data, sizeof(pgtype));
+ 
+               if (skip_overflow && pgtype == SALVAGE_OVERFLOW)
+@@ -730,8 +737,9 @@
+               if ((ret = __dbc_del(*dbcp, 0)) != 0)
+                       return (ret);
+               if (pgtype != SALVAGE_IGNORE) {
++                      if (key.size != sizeof(db_pgno_t)
++                              || data.size != sizeof(u_int32_t))
++                              return (DB_VERIFY_FATAL);
+-                      DB_ASSERT(dbp->env, key.size == sizeof(db_pgno_t));
+-                      DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
+ 
+                       *pgnop = *(db_pgno_t *)key.data;
+                       *pgtypep = *(u_int32_t *)data.data;
+--- db-18.1.32/src/db/partition.c      2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/db/partition.c      2020-05-29 23:28:22.000000000 +0530
+@@ -461,9 +461,19 @@
+               } else
+                       part->nparts = meta->nparts;
+       } else if (meta->nparts != 0 && part->nparts != meta->nparts) {
++              ret = EINVAL;
+               __db_errx(env, DB_STR("0656",
+                   "Number of partitions does not match."));
+-              ret = EINVAL;
++              goto err;
++      }
++      /*
++       * There is no limit on the number of partitions, but I cannot imagine 
a real
++       * database having more than 10000.
++       */
++      if (meta->nparts > 10000) {
++              ret = EINVAL;
++              __db_errx(env, DB_STR_A("5553",
++                      "Too many partitions %lu", "%lu"), 
(u_long)(meta->nparts));
+               goto err;
+       }
+ 
+@@ -2106,10 +2116,13 @@
+                       memcpy(rp->data, key->data, key->size);
+                       B_TSET(rp->type, B_KEYDATA);
+               }
++vrfy:   if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
++            NULL, handle, callback,
++            lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0) {
++              ret = t_ret;
++            if (ret == ENOENT)
++                break;
++          }
+-vrfy:         if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
+-                  NULL, handle, callback,
+-                  lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0)
+-                      ret = t_ret;
+       }
+ 
+ err:  if (lp != NULL)
+--- db-18.1.32/src/hash/hash_page.c    2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/hash/hash_page.c    2020-05-29 23:28:22.000000000 +0530
+@@ -869,7 +869,11 @@
+       /* Validate that next, prev pointers are OK */
+       n = NUM_ENT(p);
+       dbp = dbc->dbp;
++      if (n % 2 != 0) {
++              __db_errx(dbp->env, DB_STR_A("5549",
++                "Odd number of entries on page: %lu", "%lu"), 
(u_long)(p->pgno));
++              return (DB_VERIFY_FATAL);
++      }
+-      DB_ASSERT(dbp->env, n%2 == 0 );
+ 
+       env = dbp->env;
+       t = dbp->h_internal;
+@@ -940,7 +944,12 @@
+                       if ((ret = __db_prpage(dbp, p, DB_PR_PAGE)) != 0)
+                               return (ret);
+ #endif
++                      if (res >= 0) {
++                              __db_errx(env, DB_STR_A("5550",
++                                      "Odd number of entries on page: %lu", 
"%lu"),
++                                      (u_long)p->pgno);
++                              return (DB_VERIFY_FATAL);
++                      }
+-                      DB_ASSERT(dbp->env, res < 0);
+               }
+ 
+               prev = curr;
+--- db-18.1.32/src/hash/hash_verify.c  2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/hash/hash_verify.c  2020-05-29 23:28:22.000000000 +0530
+@@ -615,7 +615,7 @@
+                               isbad = 1;
+                       else
+                               goto err;
++              }
+-                  }
+ 
+       /*
+        * There may be unused hash pages corresponding to buckets
+@@ -746,7 +746,7 @@
+                   "Page %lu: impossible first page in bucket %lu", "%lu %lu"),
+                   (u_long)pgno, (u_long)bucket));
+               /* Unsafe to continue. */
++              ret = DB_VERIFY_FATAL;
+-              isbad = 1;
+               goto err;
+       }
+ 
+@@ -776,7 +776,7 @@
+                       EPRINT((env, DB_STR_A("1116",
+                           "Page %lu: hash page referenced twice", "%lu"),
+                           (u_long)pgno));
++                      ret = DB_VERIFY_FATAL;
+-                      isbad = 1;
+                       /* Unsafe to continue. */
+                       goto err;
+               } else if ((ret = __db_vrfy_pgset_inc(vdp->pgset,
+@@ -1307,7 +1307,11 @@
+       COMPQUIET(flags, 0);
+       ip = vdp->thread_info;
+ 
++      if (pgset == NULL) {
++              EPRINT((dbp->env, DB_STR("5548",
++                      "Error, database contains no visible pages.")));
++              return (DB_VERIFY_FATAL);
++      }
+-      DB_ASSERT(dbp->env, pgset != NULL);
+ 
+       mpf = dbp->mpf;
+       totpgs = 0;
+--- db-18.1.32/src/qam/qam_verify.c    2019-02-20 03:21:20.000000000 +0530
++++ db-18.1.40/src/qam/qam_verify.c    2020-05-29 23:28:22.000000000 +0530
+@@ -465,7 +465,14 @@
+       /* Verify/salvage each page. */
+       if ((ret = __db_cursor(dbp, vdp->thread_info, NULL, &dbc, 0)) != 0)
+               return (ret);
+-begin:        for (; i <= stop; i++) {
++begin:        if ((stop - i) > 100000) {
++              EPRINT((env, DB_STR_A("5551",
++"Warning, many possible extends files (%lu), will take a long time to verify",
++          "%lu"), (u_long)(stop - i)));
++      }
++      for (; i <= stop; i++) {
++              if (i == UINT32_MAX)
++                      break;
+               /*
+                * If DB_SALVAGE is set, we inspect our database of completed
+                * pages, and skip any we've already printed in the subdb pass.

Reply via email to