diff --git a/CODING b/CODING
index e0a81f89e4..e89b691eba 100644
--- a/CODING
+++ b/CODING
@@ -339,6 +339,8 @@ external/heimdal/hcrypto/evp.c:      cast-function-type
              : Linux kernel build uses -Wcast-function-type
 external/heimdal/hcrypto/evp-algs.c: cast-function-type
              : Linux kernel build uses -Wcast-function-type
+external/heimdal/krb5/crypto.c: use-after-free : False postive on certain GCC
+                                                 compilers
 kauth/admin_tools.c  : strict-proto  : ubik_Call
 kauth/authclient.c   : strict-proto  : ubik_Call nonsense
 libadmin/kas/afs_kasAdmin.c: strict-proto : ubik_Call nonsense
diff --git a/Makefile.in b/Makefile.in
index 307a5a0bcd..57a11233f5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -761,8 +761,14 @@ dist:
 	mkdir -p packages
 	./build-tools/make-release --dir=packages HEAD
 
-srpm:
-	(cd packages && ../src/packaging/RedHat/makesrpm.pl *-src.tar.bz2 *-doc.tar.bz2)
+srpm: dist
+	./src/packaging/RedHat/makesrpm.pl --dir=packages \
+	  packages/openafs-*-src.tar.bz2 \
+	  packages/openafs-*-doc.tar.bz2
+
+rpm: srpm
+	rpmbuild --rebuild --define "_topdir @TOP_OBJDIR@/packages/rpmbuild" \
+	  packages/openafs-*.src.rpm
 
 dox:
 	if test "x$(DOXYGEN)" != "x"; then \
diff --git a/NEWS b/NEWS
index e7f3df8f88..ee059b7c01 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,93 @@
                        User-Visible OpenAFS Changes
 
+OpenAFS 1.8.11
+
+  All platforms
+
+    * Check Rx RPC call number in incoming packets before allocating new
+      RPC calls to avoid re-running RPC calls when spurious packets are
+      received (15562)
+
+    * Fix memory leaks (15516 15517)
+
+    * Fix build failure when building with _FORTIFY_SOURCE (15518 15519)
+
+    * Fix build failures when building with the clang compiler (15540 15541
+      15547 15548)
+
+    * Improve error detection in OpenAFS directories for both clients
+      and servers (15544 15545 15546)
+
+    * Add a Makefile target to build Red Hat RPM packages (15514)
+
+    * Add support for custom version numbers in Red Hat RPM packages (15513)
+
+  All server platforms
+
+    * Fix File Server and Protection Server crashes due to recursive thread
+      lock bug (15609)
+
+    * Fix fileserver crashes during startup (15509 15543)
+
+    * The bosserver no longer creates the client configuration directory and
+      "ThisCell" and "CellServDB" symlinks.  The "vos", "pts", and "bos"
+      commands now read cell configuration from the server cell configuration
+      directory when the client cell configuration directory is not present.
+      This change allows server packaging to be independent of client packaging
+      and removes the need for client configuration artifacts on hosts running
+      server processes only (15510 15511 15512)
+
+    * Print a warning in the volserver log when an older version of a volume
+      is restored over an existing volume, unless the volume was restored with
+      "-overwrite full" (15531)
+
+    * Print a warning in the bosserver log when the bosserver was not started
+      in restricted mode (15537)
+
+    * Avoid unbounded string copies when looking up volumes by name in
+      the vlserver (15538)
+
+    * Fix off-by-one directory entry name size check in salvager (15598)
+
+  All client platforms
+
+    * Updated the CellServDB to the latest version from grand.central.org
+      (15603)
+
+  All UNIX/Linux client platforms
+
+    * Fix PAG object memory leak which can degrade performance (15506)
+
+    * Improve kernel memory reclamation after accessing a large number of
+      files (15536)
+
+    * Improve cache corruption detection and refetch cache entries
+      when cache entry size mismatches are detected (15532 15533 15535)
+
+    * Fix panic in user-space client (libuafs, Fuse client) (15539)
+
+  Linux clients
+
+    * Add support for Linux 6.7 (15600)
+
+    * Add support for Linux 6.6 (15575 15589 15590)
+
+    * Add support for Linux 6.5 (15520 15521 15522 15523 15558)
+
+    * Fix BUG when directory entry names are longer than 16 characters.
+      Affects Linux 6.5 or higher built with GCC 13 or higher (15599)
+
+    * Invalidate Linux VFS dentry caches in the AFS filesystem when running
+      "fs flush*" commands. This reduces the need to drop Linux VFS caches
+      by writing to the "/proc/sys/vm/drop_caches" file when
+      troubleshooting (15515)
+
+    * Fix build failures (15507 15508 15596 15542 15549)
+
+  macOS
+
+    * Add support for MacOS 14 ("Sonoma") (15602)
+
 OpenAFS 1.8.10
 
   All platforms
diff --git a/acinclude.m4 b/acinclude.m4
index 16339682db..812bece986 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -56,6 +56,7 @@ OPENAFS_HCRYPTO
 OPENAFS_CURSES
 OPENAFS_C_ATTRIBUTE
 OPENAFS_C_PRAGMA
+OPENAFS_C_FLEXIBLE_ARRAY
 OPENAFS_MORE_ROKEN_CHECKS
 OPENAFS_NETDB_CHECKS
 OPENAFS_ROKEN_HEADERS
diff --git a/build-tools/libafsdep b/build-tools/libafsdep
index f7bfa3a4dc..c32b2f6572 100644
--- a/build-tools/libafsdep
+++ b/build-tools/libafsdep
@@ -2,5 +2,6 @@ config.guess
 config.sub
 git-version
 install-sh
+ltmain.sh
 missing
 mkinstalldirs
diff --git a/configure-libafs.ac b/configure-libafs.ac
index 28677937aa..644376c551 100644
--- a/configure-libafs.ac
+++ b/configure-libafs.ac
@@ -4,7 +4,7 @@ AC_CONFIG_AUX_DIR([build-tools])
 AC_CONFIG_SRCDIR([src/libafs/Makefile.common.in])
 
 AC_CONFIG_HEADERS([src/config/afsconfig.h])
-MACOS_VERSION=1.8.10
+MACOS_VERSION=1.8.11
 
 AC_SUBST([MACOS_VERSION])
 
diff --git a/configure.ac b/configure.ac
index ac35f44b31..c23514e940 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@ AC_CONFIG_MACRO_DIR([src/cf])
 AC_CONFIG_SRCDIR([src/config/stds.h])
 
 AC_CONFIG_HEADERS([src/config/afsconfig.h])
-MACOS_VERSION=1.8.10
+MACOS_VERSION=1.8.11
 
 AC_SUBST([MACOS_VERSION])
 
diff --git a/doc/man-pages/pod1/pts.pod b/doc/man-pages/pod1/pts.pod
index d3a890b053..978ee356be 100644
--- a/doc/man-pages/pod1/pts.pod
+++ b/doc/man-pages/pod1/pts.pod
@@ -111,18 +111,36 @@ The value of the AFSCELL environment variable.
 
 The local F</usr/vice/etc/ThisCell> file.
 
+=item *
+
+The local F</usr/afs/etc/ThisCell> file.
+
+=back
+
 Do not combine the B<-cell> and B<-localauth> options. A command on which
 the B<-localauth> flag is included always runs in the local cell (as
 defined in the server machine's local F</usr/afs/etc/ThisCell> file),
 whereas a command on which the B<-cell> argument is included runs in the
 specified foreign cell.
 
-=back
-
 =item B<-config> <I<config directory>>
 
 The location of the directory to use to obtain configuration information,
 including the CellServDB. This is primarily provided for testing purposes.
+If the B<-config> and B<-localauth> arguments are omitted, the command
+interpreter searches for the configuration information in the following order:
+
+=over 4
+
+=item *
+
+The F</usr/vice/etc> directory.
+
+=item *
+
+The F</usr/afs/etc> directory.
+
+=back
 
 =item B<-force>
 
diff --git a/doc/man-pages/pod1/vos.pod.in b/doc/man-pages/pod1/vos.pod.in
index f0ec34acd9..fb321326a0 100644
--- a/doc/man-pages/pod1/vos.pod.in
+++ b/doc/man-pages/pod1/vos.pod.in
@@ -157,6 +157,10 @@ The value of the AFSCELL environment variable.
 
 The local F</usr/vice/etc/ThisCell> file.
 
+=item *
+
+The local F</usr/afs/etc/ThisCell> file.
+
 =back
 
 Do not combine the B<-cell> and B<-localauth> options. A command on which
@@ -169,6 +173,20 @@ specified foreign cell.
 
 The location of the directory to use to obtain configuration information,
 including the CellServDB. This is primarily provided for testing purposes.
+If the B<-config> and B<-localauth> arguments are omitted, the command
+interpreter searches for the configuration information in the following order:
+
+=over 4
+
+=item *
+
+The F</usr/vice/etc> directory.
+
+=item *
+
+The F</usr/afs/etc> directory.
+
+=back
 
 =item B<-help>
 
diff --git a/doc/man-pages/pod8/bos.pod b/doc/man-pages/pod8/bos.pod
index 70f912667f..59889ed60e 100644
--- a/doc/man-pages/pod8/bos.pod
+++ b/doc/man-pages/pod8/bos.pod
@@ -147,6 +147,10 @@ The value of the AFSCELL environment variable.
 
 The local F</usr/vice/etc/ThisCell> file.
 
+=item *
+
+The local F</usr/afs/etc/ThisCell> file.
+
 =back
 
 Do not combine the B<-cell> and B<-localauth> options. A command on which
diff --git a/src/WINNT/afsd/cm_dir.c b/src/WINNT/afsd/cm_dir.c
index 7430bd4d2b..521ec204ec 100644
--- a/src/WINNT/afsd/cm_dir.c
+++ b/src/WINNT/afsd/cm_dir.c
@@ -24,8 +24,6 @@
 #include <rx/rx.h>
 
 
-afs_int32 DErrno;
-
 afs_uint32 dir_lookup_hits = 0;
 afs_uint32 dir_lookup_misses = 0;
 afs_uint32 dir_create_entry = 0;
diff --git a/src/WINNT/install/NSIS/CellServDB b/src/WINNT/install/NSIS/CellServDB
index 2cc93965a8..63e3330a38 100644
--- a/src/WINNT/install/NSIS/CellServDB
+++ b/src/WINNT/install/NSIS/CellServDB
@@ -1,4 +1,4 @@
->grand.central.org      #GCO Public CellServDB 09 May 2022
+>grand.central.org      #GCO Public CellServDB 31 Oct 2023
 18.9.48.14                      #grand.mit.edu
 128.2.13.219                    #grand-old-opry.central.org
 >wu-wien.ac.at          #University of Economics, Vienna, Austria
@@ -26,9 +26,8 @@
 129.128.125.40                  #drake.ucs.ualberta.ca
 >cern.ch                #European Laboratory for Particle Physics, Geneva
 137.138.54.120                  #afsdb13.cern.ch
-137.138.128.148                 #afsdb1.cern.ch
-137.138.246.51                  #afsdb2.cern.ch
 188.184.21.218                  #afsdb11.cern.ch
+188.184.23.130                  #afsdb14.cern.ch
 188.184.81.230                  #afsdb12.cern.ch
 >ams.cern.ch            #AMS Experiment
 >epfl.ch                #Swiss Federal Institute of Technology at Lausanne
@@ -95,7 +94,7 @@
 >ipp-garching.mpg.de    #Institut fuer Plasmaphysik
 130.183.9.5                     #afs-db1.rzg.mpg.de
 130.183.14.14                   #afs-db3.bc.rzg.mpg.de
-130.183.100.10                  #afs-db2.aug.ipp-garching.mpg.de
+130.183.30.30                   #afs-db4.mpcdf.mpg.de
 >mpe.mpg.de             #MPE cell
 130.183.130.7                   #irafs1.mpe-garching.mpg.de
 130.183.134.20                  #irafs2.mpe-garching.mpg.de
@@ -196,16 +195,10 @@
 128.2.10.2                      #afsdb-01.andrew.cmu.edu
 128.2.10.7                      #afsdb-02.andrew.cmu.edu
 128.2.10.11                     #afsdb-03.andrew.cmu.edu
->mw.andrew.cmu.edu      #Carnegie Mellon University - Middleware Test Cell
-128.2.234.24                    #null.andrew.cmu.edu
-128.2.234.170                   #mw-mgr.andrew.cmu.edu
 >club.cc.cmu.edu        #Carnegie Mellon University Computer Club
 128.2.204.149                   #barium.club.cc.cmu.edu
 128.237.157.11                  #sodium.club.cc.cmu.edu
 128.237.157.13                  #potassium.club.cc.cmu.edu
->chem.cmu.edu           #Carnegie Mellon University - Chemistry Dept.
-128.2.40.134                    #afs.chem.cmu.edu
-128.2.40.140                    #afs2.chem.cmu.edu
 >cs.cmu.edu             #Carnegie Mellon University - School of Comp. Sci.
 128.2.104.79                    #afsdb-scs-01.srv.cs.cmu.edu
 128.2.104.80                    #afsdb-scs-02.srv.cs.cmu.edu
@@ -214,15 +207,10 @@
 128.2.129.7                     #porok.ece.cmu.edu
 128.2.129.8                     #vicio.ece.cmu.edu
 128.2.129.9                     #e-xing.ece.cmu.edu
->scotch.ece.cmu.edu     #CMU ECE CALCM research group
-128.2.134.82                    #lagavulin.ece.cmu.edu
 >qatar.cmu.edu          #Carnegie Mellon University - Qatar
 86.36.46.6                      #afsdb-01.qatar.cmu.edu
 86.36.46.7                      #afsdb-02.qatar.cmu.edu
 86.36.46.9                      #afsdb-03.qatar.cmu.edu
->sbp.ri.cmu.edu         #Carnegie Mellon University - Sensor Based Planning Lab
-128.2.179.12                    #nihao.sbp.ri.cmu.edu
-128.2.179.113                   #youtheman.sbp.ri.cmu.edu
 >ee.cooper.edu          #The Cooper Union EE Department
 199.98.27.202                   #stallman.ee.cooper.edu
 >cnf.cornell.edu        #CNF
@@ -242,9 +230,9 @@
 129.170.30.144                  #dbicafs2.dartmouth.edu
 129.170.30.145                  #dbicafs3.dartmouth.edu
 >northstar.dartmouth.edu #Dartmouth College Research Computing
-129.170.16.22                   #halley.dartmouth.edu
-129.170.16.26                   #andromeda.dartmouth.edu
-129.170.199.250                 #kuiper.dartmouth.edu
+129.170.137.194                 #halley.dartmouth.edu
+129.170.137.195                 #andromeda.dartmouth.edu
+129.170.137.196                 #kuiper.dartmouth.edu
 >cs.hm.edu              #Department Computer Science Munich University Of Applied Science
 129.187.208.31                  #afs1.cs.hm.edu
 >eecs.harvard.edu       #Harvard - EECS
@@ -286,9 +274,9 @@
 136.142.8.20                    #afs10.srv.cis.pitt.edu
 136.142.8.21                    #afs11.srv.cis.pitt.edu
 >cs.pitt.edu            #University of Pittsburgh - Computer Science
-136.142.22.5                    #afs01.cs.pitt.edu
-136.142.22.6                    #afs02.cs.pitt.edu
-136.142.22.7                    #afs03.cs.pitt.edu
+136.142.55.232                  #afs01.cs.pitt.edu
+136.142.55.233                  #afs02.cs.pitt.edu
+136.142.55.234                  #afs03.cs.pitt.edu
 >psc.edu                #PSC (Pittsburgh Supercomputing Center)
 128.182.59.182                  #shaggy.psc.edu
 128.182.66.184                  #velma.psc.edu
@@ -339,17 +327,17 @@
 130.85.24.87                    #db3.afs.umbc.edu
 130.85.24.101                   #db1.afs.umbc.edu
 >glue.umd.edu           #University of Maryland - Project Glue
-128.8.70.11                     #olmec.umd.edu
 128.8.163.205                   #hurricane.umd.edu
 128.8.236.2                     #cyclone.umd.edu
+128.8.236.230                   #babylon.umd.edu
 >umich.edu              #University of Michigan - Campus
 141.211.1.32                    #fear.ifs.umich.edu
 141.211.1.33                    #surprise.ifs.umich.edu
 141.211.1.34                    #ruthless.ifs.umich.edu
 >atlas.umich.edu        #ATLAS group cell in physics at University of Michigan
-141.211.43.102                  #linat02.grid.umich.edu
-141.211.43.103                  #linat03.grid.umich.edu
-141.211.43.104                  #linat04.grid.umich.edu
+192.41.230.102                  #linat02.aglt2.org
+192.41.230.103                  #linat03.aglt2.org
+192.41.230.104                  #linat04.aglt2.org
 >citi.umich.edu         #University of Michigan - Center for Information Technology Integ
 141.212.112.5                   #babylon.citi.umich.edu
 >isis.unc.edu           #Univ. of NC at Chapel Hill - ITS
@@ -505,9 +493,9 @@
 66.66.102.254                   #supercore.laroia.net
 >pallissard.net         #pallissard.net
 >sinenomine.net         #Sine Nomine Associates
-207.89.43.108                   #afsdb3.sinenomine.net
-207.89.43.109                   #afsdb4.sinenomine.net
-207.89.43.110                   #afsdb5.sinenomine.net
+198.44.193.30                   #afsdb3.sinenomine.net
+198.44.193.31                   #afsdb4.sinenomine.net
+198.44.193.32                   #afsdb5.sinenomine.net
 >slackers.net           #The Slackers' Network
 199.4.150.159                   #alexandria.slackers.net
 >tproa.net              #The People's Republic of Ames
@@ -530,13 +518,9 @@
 66.93.61.184                    #vice1.coed.org
 128.237.157.35                  #vice3.coed.org
 >dementia.org           #Dementia Unlimited (old)
-128.2.13.209                    #dedlock.dementix.org
-128.2.234.204                   #vorkana.dementix.org
-128.2.235.26                    #meredith.dementix.org
+204.29.154.67                   #alice-comfort.dementix.org
 >dementix.org           #Dementia Unlimited
-128.2.13.209                    #dedlock.dementix.org
-128.2.234.204                   #vorkana.dementix.org
-128.2.235.26                    #meredith.dementix.org
+204.29.154.67                   #alice-comfort.dementix.org
 >idahofuturetruck.org   #University of Idaho hybrid vehicle development
 12.18.238.210                   #dsle210.fsr.net
 >afs.ietfng.org         #ietfng.org
@@ -560,7 +544,7 @@
 >riscpkg.org            #The RISC OS Packaging Project
 83.104.175.10                   #delenn.riscpkg.org
 >kth.se                 #Royal Institute of Technology, Stockholm, Sweden
-130.237.32.145                  #sonen.e.kth.se
+130.237.48.5                    #sonen.e.kth.se
 130.237.48.7                    #anden.e.kth.se
 130.237.48.244                  #fadern.e.kth.se
 >ict.kth.se             #Royal Institute of Technology, Information and Communication tec
@@ -568,17 +552,17 @@
 130.237.216.12                  #afsdb2.ict.kth.se
 130.237.216.13                  #afsdb3.ict.kth.se
 >it.kth.se              #Royal Institute of Technology, Teleinformatics, Kista
-130.237.48.190                  #itafs-1.sys.kth.se
+130.237.48.68                   #itafs-2.sys.kth.se
 >md.kth.se              #Royal Institute of Technology, MMK
-130.237.48.223                  #mdafs-2.sys.kth.se
+130.237.48.170                  #mdafs-3.sys.kth.se
 >mech.kth.se            #Royal Institute of Technology, MECH
 130.237.233.142                 #matterhorn.mech.kth.se
 130.237.233.143                 #castor.mech.kth.se
 130.237.233.144                 #pollux.mech.kth.se
 >nada.kth.se            #Royal Institute of Technology, NADA
-130.237.32.150                  #nadaafsdb-2.sys.kth.se
-130.237.48.8                    #nadaafsdb-3.sys.kth.se
-130.237.227.23                  #afsdb-4.csc.kth.se
+130.237.48.8                    #nadaafs-3.sys.kth.se
+130.237.48.41                   #nadaafs-1.sys.kth.se
+130.237.48.58                   #nadaafs-2.sys.kth.se
 >pdc.kth.se             #Royal Institute of Technology, PDC
 130.237.232.29                  #crab.pdc.kth.se
 130.237.232.112                 #anna.pdc.kth.se
@@ -600,6 +584,8 @@
 >p-ng.si                #University of Nova Gorica
 193.2.120.2                     #solkan.p-ng.si
 193.2.120.9                     #sabotin.p-ng.si
+>ung.si                 #University of Nova Gorica
+193.2.120.63                    #afs1.ung.si
 >ihep.su                #Institute for High-Energy Physics
 194.190.165.201                 #fs0001.ihep.su
 194.190.165.202                 #fs0002.ihep.su
diff --git a/src/WINNT/install/wix/CellServDB b/src/WINNT/install/wix/CellServDB
index 2cc93965a8..63e3330a38 100644
--- a/src/WINNT/install/wix/CellServDB
+++ b/src/WINNT/install/wix/CellServDB
@@ -1,4 +1,4 @@
->grand.central.org      #GCO Public CellServDB 09 May 2022
+>grand.central.org      #GCO Public CellServDB 31 Oct 2023
 18.9.48.14                      #grand.mit.edu
 128.2.13.219                    #grand-old-opry.central.org
 >wu-wien.ac.at          #University of Economics, Vienna, Austria
@@ -26,9 +26,8 @@
 129.128.125.40                  #drake.ucs.ualberta.ca
 >cern.ch                #European Laboratory for Particle Physics, Geneva
 137.138.54.120                  #afsdb13.cern.ch
-137.138.128.148                 #afsdb1.cern.ch
-137.138.246.51                  #afsdb2.cern.ch
 188.184.21.218                  #afsdb11.cern.ch
+188.184.23.130                  #afsdb14.cern.ch
 188.184.81.230                  #afsdb12.cern.ch
 >ams.cern.ch            #AMS Experiment
 >epfl.ch                #Swiss Federal Institute of Technology at Lausanne
@@ -95,7 +94,7 @@
 >ipp-garching.mpg.de    #Institut fuer Plasmaphysik
 130.183.9.5                     #afs-db1.rzg.mpg.de
 130.183.14.14                   #afs-db3.bc.rzg.mpg.de
-130.183.100.10                  #afs-db2.aug.ipp-garching.mpg.de
+130.183.30.30                   #afs-db4.mpcdf.mpg.de
 >mpe.mpg.de             #MPE cell
 130.183.130.7                   #irafs1.mpe-garching.mpg.de
 130.183.134.20                  #irafs2.mpe-garching.mpg.de
@@ -196,16 +195,10 @@
 128.2.10.2                      #afsdb-01.andrew.cmu.edu
 128.2.10.7                      #afsdb-02.andrew.cmu.edu
 128.2.10.11                     #afsdb-03.andrew.cmu.edu
->mw.andrew.cmu.edu      #Carnegie Mellon University - Middleware Test Cell
-128.2.234.24                    #null.andrew.cmu.edu
-128.2.234.170                   #mw-mgr.andrew.cmu.edu
 >club.cc.cmu.edu        #Carnegie Mellon University Computer Club
 128.2.204.149                   #barium.club.cc.cmu.edu
 128.237.157.11                  #sodium.club.cc.cmu.edu
 128.237.157.13                  #potassium.club.cc.cmu.edu
->chem.cmu.edu           #Carnegie Mellon University - Chemistry Dept.
-128.2.40.134                    #afs.chem.cmu.edu
-128.2.40.140                    #afs2.chem.cmu.edu
 >cs.cmu.edu             #Carnegie Mellon University - School of Comp. Sci.
 128.2.104.79                    #afsdb-scs-01.srv.cs.cmu.edu
 128.2.104.80                    #afsdb-scs-02.srv.cs.cmu.edu
@@ -214,15 +207,10 @@
 128.2.129.7                     #porok.ece.cmu.edu
 128.2.129.8                     #vicio.ece.cmu.edu
 128.2.129.9                     #e-xing.ece.cmu.edu
->scotch.ece.cmu.edu     #CMU ECE CALCM research group
-128.2.134.82                    #lagavulin.ece.cmu.edu
 >qatar.cmu.edu          #Carnegie Mellon University - Qatar
 86.36.46.6                      #afsdb-01.qatar.cmu.edu
 86.36.46.7                      #afsdb-02.qatar.cmu.edu
 86.36.46.9                      #afsdb-03.qatar.cmu.edu
->sbp.ri.cmu.edu         #Carnegie Mellon University - Sensor Based Planning Lab
-128.2.179.12                    #nihao.sbp.ri.cmu.edu
-128.2.179.113                   #youtheman.sbp.ri.cmu.edu
 >ee.cooper.edu          #The Cooper Union EE Department
 199.98.27.202                   #stallman.ee.cooper.edu
 >cnf.cornell.edu        #CNF
@@ -242,9 +230,9 @@
 129.170.30.144                  #dbicafs2.dartmouth.edu
 129.170.30.145                  #dbicafs3.dartmouth.edu
 >northstar.dartmouth.edu #Dartmouth College Research Computing
-129.170.16.22                   #halley.dartmouth.edu
-129.170.16.26                   #andromeda.dartmouth.edu
-129.170.199.250                 #kuiper.dartmouth.edu
+129.170.137.194                 #halley.dartmouth.edu
+129.170.137.195                 #andromeda.dartmouth.edu
+129.170.137.196                 #kuiper.dartmouth.edu
 >cs.hm.edu              #Department Computer Science Munich University Of Applied Science
 129.187.208.31                  #afs1.cs.hm.edu
 >eecs.harvard.edu       #Harvard - EECS
@@ -286,9 +274,9 @@
 136.142.8.20                    #afs10.srv.cis.pitt.edu
 136.142.8.21                    #afs11.srv.cis.pitt.edu
 >cs.pitt.edu            #University of Pittsburgh - Computer Science
-136.142.22.5                    #afs01.cs.pitt.edu
-136.142.22.6                    #afs02.cs.pitt.edu
-136.142.22.7                    #afs03.cs.pitt.edu
+136.142.55.232                  #afs01.cs.pitt.edu
+136.142.55.233                  #afs02.cs.pitt.edu
+136.142.55.234                  #afs03.cs.pitt.edu
 >psc.edu                #PSC (Pittsburgh Supercomputing Center)
 128.182.59.182                  #shaggy.psc.edu
 128.182.66.184                  #velma.psc.edu
@@ -339,17 +327,17 @@
 130.85.24.87                    #db3.afs.umbc.edu
 130.85.24.101                   #db1.afs.umbc.edu
 >glue.umd.edu           #University of Maryland - Project Glue
-128.8.70.11                     #olmec.umd.edu
 128.8.163.205                   #hurricane.umd.edu
 128.8.236.2                     #cyclone.umd.edu
+128.8.236.230                   #babylon.umd.edu
 >umich.edu              #University of Michigan - Campus
 141.211.1.32                    #fear.ifs.umich.edu
 141.211.1.33                    #surprise.ifs.umich.edu
 141.211.1.34                    #ruthless.ifs.umich.edu
 >atlas.umich.edu        #ATLAS group cell in physics at University of Michigan
-141.211.43.102                  #linat02.grid.umich.edu
-141.211.43.103                  #linat03.grid.umich.edu
-141.211.43.104                  #linat04.grid.umich.edu
+192.41.230.102                  #linat02.aglt2.org
+192.41.230.103                  #linat03.aglt2.org
+192.41.230.104                  #linat04.aglt2.org
 >citi.umich.edu         #University of Michigan - Center for Information Technology Integ
 141.212.112.5                   #babylon.citi.umich.edu
 >isis.unc.edu           #Univ. of NC at Chapel Hill - ITS
@@ -505,9 +493,9 @@
 66.66.102.254                   #supercore.laroia.net
 >pallissard.net         #pallissard.net
 >sinenomine.net         #Sine Nomine Associates
-207.89.43.108                   #afsdb3.sinenomine.net
-207.89.43.109                   #afsdb4.sinenomine.net
-207.89.43.110                   #afsdb5.sinenomine.net
+198.44.193.30                   #afsdb3.sinenomine.net
+198.44.193.31                   #afsdb4.sinenomine.net
+198.44.193.32                   #afsdb5.sinenomine.net
 >slackers.net           #The Slackers' Network
 199.4.150.159                   #alexandria.slackers.net
 >tproa.net              #The People's Republic of Ames
@@ -530,13 +518,9 @@
 66.93.61.184                    #vice1.coed.org
 128.237.157.35                  #vice3.coed.org
 >dementia.org           #Dementia Unlimited (old)
-128.2.13.209                    #dedlock.dementix.org
-128.2.234.204                   #vorkana.dementix.org
-128.2.235.26                    #meredith.dementix.org
+204.29.154.67                   #alice-comfort.dementix.org
 >dementix.org           #Dementia Unlimited
-128.2.13.209                    #dedlock.dementix.org
-128.2.234.204                   #vorkana.dementix.org
-128.2.235.26                    #meredith.dementix.org
+204.29.154.67                   #alice-comfort.dementix.org
 >idahofuturetruck.org   #University of Idaho hybrid vehicle development
 12.18.238.210                   #dsle210.fsr.net
 >afs.ietfng.org         #ietfng.org
@@ -560,7 +544,7 @@
 >riscpkg.org            #The RISC OS Packaging Project
 83.104.175.10                   #delenn.riscpkg.org
 >kth.se                 #Royal Institute of Technology, Stockholm, Sweden
-130.237.32.145                  #sonen.e.kth.se
+130.237.48.5                    #sonen.e.kth.se
 130.237.48.7                    #anden.e.kth.se
 130.237.48.244                  #fadern.e.kth.se
 >ict.kth.se             #Royal Institute of Technology, Information and Communication tec
@@ -568,17 +552,17 @@
 130.237.216.12                  #afsdb2.ict.kth.se
 130.237.216.13                  #afsdb3.ict.kth.se
 >it.kth.se              #Royal Institute of Technology, Teleinformatics, Kista
-130.237.48.190                  #itafs-1.sys.kth.se
+130.237.48.68                   #itafs-2.sys.kth.se
 >md.kth.se              #Royal Institute of Technology, MMK
-130.237.48.223                  #mdafs-2.sys.kth.se
+130.237.48.170                  #mdafs-3.sys.kth.se
 >mech.kth.se            #Royal Institute of Technology, MECH
 130.237.233.142                 #matterhorn.mech.kth.se
 130.237.233.143                 #castor.mech.kth.se
 130.237.233.144                 #pollux.mech.kth.se
 >nada.kth.se            #Royal Institute of Technology, NADA
-130.237.32.150                  #nadaafsdb-2.sys.kth.se
-130.237.48.8                    #nadaafsdb-3.sys.kth.se
-130.237.227.23                  #afsdb-4.csc.kth.se
+130.237.48.8                    #nadaafs-3.sys.kth.se
+130.237.48.41                   #nadaafs-1.sys.kth.se
+130.237.48.58                   #nadaafs-2.sys.kth.se
 >pdc.kth.se             #Royal Institute of Technology, PDC
 130.237.232.29                  #crab.pdc.kth.se
 130.237.232.112                 #anna.pdc.kth.se
@@ -600,6 +584,8 @@
 >p-ng.si                #University of Nova Gorica
 193.2.120.2                     #solkan.p-ng.si
 193.2.120.9                     #sabotin.p-ng.si
+>ung.si                 #University of Nova Gorica
+193.2.120.63                    #afs1.ung.si
 >ihep.su                #Institute for High-Energy Physics
 194.190.165.201                 #fs0001.ihep.su
 194.190.165.202                 #fs0002.ihep.su
diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h
index 3588799b27..44bcb440ef 100644
--- a/src/afs/LINUX/osi_compat.h
+++ b/src/afs/LINUX/osi_compat.h
@@ -49,6 +49,10 @@ typedef struct path afs_linux_path_t;
 # define d_alias d_u.d_alias
 #endif
 
+#if defined(STRUCT_DENTRY_HAS_D_U_D_CHILD)
+# define d_child d_u.d_child
+#endif
+
 #if defined(STRUCT_FILE_HAS_F_PATH)
 # if !defined(f_dentry)
 #  define f_dentry f_path.dentry
diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c
index b8bdce7e7e..e8c2980681 100644
--- a/src/afs/LINUX/osi_file.c
+++ b/src/afs/LINUX/osi_file.c
@@ -138,7 +138,7 @@ osi_UFSOpen(afs_dcache_id_t *ainode)
     }
 
     afile->offset = 0;
-    afile->proc = (int (*)())0;
+    afile->proc = NULL;
     return (void *)afile;
 }
 
@@ -175,9 +175,8 @@ afs_osi_Stat(struct osi_file *afile, struct osi_stat *astat)
 {
     AFS_STATCNT(osi_Stat);
     astat->size = i_size_read(OSIFILE_INODE(afile));
-    astat->mtime = OSIFILE_INODE(afile)->i_mtime.tv_sec;
-    astat->atime = OSIFILE_INODE(afile)->i_atime.tv_sec;
-
+    astat->mtime = afs_inode_get_mtime_sec(OSIFILE_INODE(afile));
+    astat->atime = afs_inode_get_atime_sec(OSIFILE_INODE(afile));
     return 0;
 }
 
diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h
index 2220e05307..916a1dfeda 100644
--- a/src/afs/LINUX/osi_machdep.h
+++ b/src/afs/LINUX/osi_machdep.h
@@ -118,6 +118,46 @@ osi_GetTime(osi_timeval32_t *atv)
 }
 #endif
 
+#if defined(HAVE_LINUX_INODE_SET_CTIME)
+# define afs_inode_set_ctime(inode, sec, nsec) inode_set_ctime((inode), (sec), (nsec))
+#else
+static inline void
+afs_inode_set_ctime(struct inode *inode, time_t sec, long nsec)
+{
+    inode->i_ctime.tv_sec = sec;
+    inode->i_ctime.tv_nsec = nsec;
+}
+#endif
+#if defined(HAVE_LINUX_INODE_ATIME_MTIME_ACCESSORS)
+# define afs_inode_set_atime(inode, sec, nsec) inode_set_atime((inode), (sec), (nsec))
+# define afs_inode_get_atime_sec(inode) inode_get_atime_sec((inode))
+# define afs_inode_set_mtime(inode, sec, nsec) inode_set_mtime((inode), (sec), (nsec))
+# define afs_inode_get_mtime_sec(inode) inode_get_mtime_sec((inode))
+#else
+static inline void
+afs_inode_set_atime(struct inode *inode, time_t sec, long nsec)
+{
+    inode->i_atime.tv_sec = sec;
+    inode->i_atime.tv_nsec = nsec;
+}
+static inline time_t
+afs_inode_get_atime_sec(struct inode *inode)
+{
+    return inode->i_atime.tv_sec;
+}
+static inline void
+afs_inode_set_mtime(struct inode *inode, time_t sec, long nsec)
+{
+    inode->i_mtime.tv_sec = sec;
+    inode->i_mtime.tv_nsec = nsec;
+}
+static inline time_t
+afs_inode_get_mtime_sec(struct inode *inode)
+{
+    return inode->i_mtime.tv_sec;
+}
+#endif /* HAVE_LINUX_INODE_ATIME_MTIME_ACCESSORS */
+
 #undef gop_lookupname
 #define gop_lookupname osi_lookupname
 
diff --git a/src/afs/LINUX/osi_sysctl.c b/src/afs/LINUX/osi_sysctl.c
index 8e7dd70e1c..a0a0398923 100644
--- a/src/afs/LINUX/osi_sysctl.c
+++ b/src/afs/LINUX/osi_sysctl.c
@@ -18,6 +18,8 @@
 #include <linux/config.h>
 #endif
 
+#ifdef CONFIG_SYSCTL
+
 /* From afs_util.c */
 extern afs_int32 afs_md5inum;
 
@@ -31,220 +33,56 @@ extern afs_int32 afs_blocksUsed_2;
 extern afs_int32 afs_pct1;
 extern afs_int32 afs_pct2;
 
-#ifdef CONFIG_SYSCTL
+# ifdef STRUCT_CTL_TABLE_HAS_CTL_NAME
+#  ifdef CTL_UNNUMBERED
+#   define AFS_SYSCTL_NAME(num) .ctl_name = CTL_UNNUMBERED,
+#  else
+#   define AFS_SYSCTL_NAME(num) .ctl_name = num,
+#  endif
+# else
+#  define AFS_SYSCTL_NAME(num)
+# endif
+
+# define AFS_SYSCTL_INT2(num, perms, name, var) { \
+    AFS_SYSCTL_NAME(num) \
+    .procname		= name, \
+    .data		= &var, \
+    .maxlen		= sizeof(var), \
+    .mode		= perms, \
+    .proc_handler	= &proc_dointvec \
+}
+# define AFS_SYSCTL_INT(num, perms, var) \
+	AFS_SYSCTL_INT2(num, perms, #var, var)
+
 static struct ctl_table_header *afs_sysctl = NULL;
 
 static struct ctl_table afs_sysctl_table[] = {
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 1,
-#endif
-#endif
-	.procname	= "hm_retry_RO",
-	.data		= &hm_retry_RO,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 2,
-#endif
-#endif
-	.procname	= "hm_retry_RW",
-	.data		= &hm_retry_RW,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 3,
-#endif
-#endif
-	.procname	= "hm_retry_int",
-	.data		= &hm_retry_int,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 4,
-#endif
-#endif
-	.procname	= "GCPAGs",
-	.data		= &afs_gcpags,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 5,
-#endif
-#endif
-	.procname	= "rx_deadtime",
-	.data		= &afs_rx_deadtime,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 6,
-#endif
-#endif
-	.procname	= "bkVolPref",
-	.data		= &afs_bkvolpref,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 7,
-#endif
-#endif
-	.procname	= "afs_blocksUsed",
-	.data		= &afs_blocksUsed,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0444,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 8,
-#endif
-#endif
-	.procname	= "afs_blocksUsed_0",
-	.data		= &afs_blocksUsed_0,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 9,
-#endif
-#endif
-	.procname	= "afs_blocksUsed_1",
-	.data		= &afs_blocksUsed_1,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 10,
-#endif
-#endif
-	.procname	= "afs_blocksUsed_2",
-	.data		= &afs_blocksUsed_2,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 11,
-#endif
-#endif
-	.procname	= "afs_pct1",
-	.data		= &afs_pct1,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 12,
-#endif
-#endif
-	.procname	= "afs_pct2",
-	.data		= &afs_pct2,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler   = &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 13,
-#endif
-#endif
-	.procname	= "afs_cacheBlocks",
-	.data		= &afs_cacheBlocks,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
-    {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 14,
-#endif
-#endif
-	.procname	= "md5inum",
-	.data		= &afs_md5inum,
-	.maxlen		= sizeof(afs_int32),
-	.mode		= 0644,
-	.proc_handler	= &proc_dointvec
-    },
+    AFS_SYSCTL_INT(1, 0644, hm_retry_RO),
+    AFS_SYSCTL_INT(2, 0644, hm_retry_RW),
+    AFS_SYSCTL_INT(3, 0644, hm_retry_int),
+
+    AFS_SYSCTL_INT2(4, 0644, "GCPAGs",      afs_gcpags),
+    AFS_SYSCTL_INT2(5, 0644, "rx_deadtime", afs_rx_deadtime),
+    AFS_SYSCTL_INT2(6, 0644, "bkVolPref",   afs_bkvolpref),
+
+    AFS_SYSCTL_INT( 7, 0444, afs_blocksUsed),
+    AFS_SYSCTL_INT( 8, 0644, afs_blocksUsed_0),
+    AFS_SYSCTL_INT( 9, 0644, afs_blocksUsed_1),
+    AFS_SYSCTL_INT(10, 0644, afs_blocksUsed_2),
+
+    AFS_SYSCTL_INT( 11, 0644, afs_pct1),
+    AFS_SYSCTL_INT( 12, 0644, afs_pct2),
+    AFS_SYSCTL_INT( 13, 0644, afs_cacheBlocks),
+    AFS_SYSCTL_INT2(14, 0644, "md5inum", afs_md5inum),
+
     {
 	.procname	= 0
     }
 };
-
+# if !defined(HAVE_LINUX_REGISTER_SYSCTL)
 static struct ctl_table fs_sysctl_table[] = {
     {
-#if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME)
-#if defined(CTL_UNNUMBERED)
-	.ctl_name	= CTL_UNNUMBERED,
-#else
-	.ctl_name	= 1,
-#endif
-#endif
+	AFS_SYSCTL_NAME(1)
 	.procname	= "afs",
 	.mode		= 0555,
 	.child		= afs_sysctl_table
@@ -253,15 +91,17 @@ static struct ctl_table fs_sysctl_table[] = {
 	.procname	= 0
     }
 };
-
+# endif
 int
 osi_sysctl_init(void)
 {
-#if defined(REGISTER_SYSCTL_TABLE_NOFLAG)
+# if defined(HAVE_LINUX_REGISTER_SYSCTL)
+    afs_sysctl = register_sysctl("afs", afs_sysctl_table);
+# elif defined(REGISTER_SYSCTL_TABLE_NOFLAG)
     afs_sysctl = register_sysctl_table(fs_sysctl_table);
-#else
+# else
     afs_sysctl = register_sysctl_table(fs_sysctl_table, 0);
-#endif
+# endif
     if (!afs_sysctl)
 	return -1;
 
diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c
index 38fd3b4b8d..897fd37abd 100644
--- a/src/afs/LINUX/osi_vcache.c
+++ b/src/afs/LINUX/osi_vcache.c
@@ -272,3 +272,56 @@ osi_ShouldDeferRemunlink(struct vcache *avc)
     }
     return 0;
 }
+
+/*
+ * Invalidate Linux-specific cached data for the given vcache. This doesn't
+ * handle anything with the OpenAFS disk cache or stat cache, etc; those things
+ * are handled by afs_ResetVCache().
+ *
+ * The Linux-specific stuff we clear here is dcache entries. This means
+ * clearing d_time in all dentry's for the vcache, and all immediate children
+ * (for directories). We don't call d_invalidate() or any similar functions
+ * here; let afs_linux_dentry_revalidate() figure out what to do with the
+ * invalid dentry's whenever they are accessed.
+ *
+ * @pre AFS_GLOCK held
+ */
+void
+osi_ResetVCache(struct vcache *avc)
+{
+    struct dentry *dp;
+    struct inode *ip = AFSTOV(avc);
+#if defined(D_ALIAS_IS_HLIST) && !defined(HLIST_ITERATOR_NO_NODE)
+    struct hlist_node *node;
+#endif
+
+    AFS_GUNLOCK();
+
+    afs_d_alias_lock(ip);
+
+    afs_d_alias_foreach(dp, ip, node) {
+	spin_lock(&dp->d_lock);
+
+	/* Invalidate the dentry for the given vcache. */
+	dp->d_time = 0;
+
+	if (S_ISDIR(ip->i_mode)) {
+	    /*
+	     * If the vcache is a dir, also invalidate all of its children.
+	     * Note that we can lock child->d_lock while dp->d_lock is held,
+	     * because 'dp' is an ancestor of 'child'.
+	     */
+	    struct dentry *child;
+	    list_for_each_entry(child, &dp->d_subdirs, d_child) {
+		spin_lock(&child->d_lock);
+		child->d_time = 0;
+		spin_unlock(&child->d_lock);
+	    }
+	}
+
+	spin_unlock(&dp->d_lock);
+    }
+    afs_d_alias_unlock(ip);
+
+    AFS_GLOCK();
+}
diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
index ccec382897..7e85aa5528 100644
--- a/src/afs/LINUX/osi_vnodeops.c
+++ b/src/afs/LINUX/osi_vnodeops.c
@@ -54,14 +54,16 @@
 # define D_SPLICE_ALIAS_RACE
 #endif
 
+#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE_SHARED) && defined(HAVE_LINUX_WRAP_DIRECTORY_ITERATOR)
+# define USE_FOP_ITERATE 1
+#elif defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) && !defined(FMODE_KABI_ITERATE)
 /* Workaround for RH 7.5 which introduced file operation iterate() but requires
  * each file->f_mode to be marked with FMODE_KABI_ITERATE.  Instead OpenAFS will
  * continue to use file opearation readdir() in this case.
  */
-#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) && !defined(FMODE_KABI_ITERATE)
-#define USE_FOP_ITERATE 1
+# define USE_FOP_ITERATE 1
 #else
-#undef USE_FOP_ITERATE
+# undef USE_FOP_ITERATE
 #endif
 
 /* Kernels from before 2.6.19 may not be able to return errors from
@@ -424,7 +426,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
     int code;
     int offset;
     afs_int32 dirpos;
-    struct DirEntry *de;
+    struct DirEntryFlex *de;
     struct DirBuffer entry;
     ino_t ino;
     int len;
@@ -529,7 +531,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
 	    goto unlock_out;
         }
 
-	de = (struct DirEntry *)entry.data;
+	de = entry.data;
 	ino = afs_calc_inum (avc->f.fid.Cell, avc->f.fid.Fid.Volume,
 			     ntohl(de->fid.vnode));
 	len = strlen(de->name);
@@ -909,10 +911,19 @@ out:
     crfree(credp);
     return afs_convert_code(code);
 }
+#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE_SHARED) && defined(HAVE_LINUX_WRAP_DIRECTORY_ITERATOR)
+# if defined(WRAP_DIR_ITER)
+WRAP_DIR_ITER(afs_linux_readdir)	/* Adds necessary locking for iterate_shared */
+# else
+#  error the Linux provided macro WRAP_DIR_ITER is not available
+# endif
+#endif
 
 struct file_operations afs_dir_fops = {
   .read =	generic_read_dir,
-#if defined(USE_FOP_ITERATE)
+#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE_SHARED) && defined(HAVE_LINUX_WRAP_DIRECTORY_ITERATOR)
+  .iterate_shared = shared_afs_linux_readdir,
+#elif defined(USE_FOP_ITERATE)
   .iterate =	afs_linux_readdir,
 #else
   .readdir =	afs_linux_readdir,
@@ -960,7 +971,11 @@ struct file_operations afs_file_fops = {
 # else
   .splice_write = generic_file_splice_write,
 # endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(6,5,0)
+  .splice_read = filemap_splice_read,
+# else
   .splice_read = generic_file_splice_read,
+# endif
 #endif
   .release =	afs_linux_release,
   .fsync =	afs_linux_fsync,
@@ -1121,16 +1136,13 @@ vattr2inode(struct inode *ip, struct vattr *vp)
     ip->i_uid = afs_make_kuid(vp->va_uid);
     ip->i_gid = afs_make_kgid(vp->va_gid);
     i_size_write(ip, vp->va_size);
-    ip->i_atime.tv_sec = vp->va_atime.tv_sec;
-    ip->i_atime.tv_nsec = 0;
-    ip->i_mtime.tv_sec = vp->va_mtime.tv_sec;
+    afs_inode_set_atime(ip, vp->va_atime.tv_sec, 0);
     /* Set the mtime nanoseconds to the sysname generation number.
      * This convinces NFS clients that all directories have changed
      * any time the sysname list changes.
      */
-    ip->i_mtime.tv_nsec = afs_sysnamegen;
-    ip->i_ctime.tv_sec = vp->va_ctime.tv_sec;
-    ip->i_ctime.tv_nsec = 0;
+    afs_inode_set_mtime(ip, vp->va_mtime.tv_sec, afs_sysnamegen);
+    afs_inode_set_ctime(ip, vp->va_ctime.tv_sec, 0);
 }
 
 /* afs_notify_change
@@ -1181,7 +1193,11 @@ afs_linux_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat
 {
 	int err = afs_linux_revalidate(path->dentry);
 	if (!err) {
+# if defined(GENERIC_FILLATTR_TAKES_REQUEST_MASK)
+		generic_fillattr(afs_mnt_idmap, request_mask, path->dentry->d_inode, stat);
+# else
 		generic_fillattr(afs_mnt_idmap, path->dentry->d_inode, stat);
+# endif
 	}
 	return err;
 }
diff --git a/src/afs/afs_buffer.c b/src/afs/afs_buffer.c
index 11f1819912..5552d1c21e 100644
--- a/src/afs/afs_buffer.c
+++ b/src/afs/afs_buffer.c
@@ -147,8 +147,22 @@ DInit(int abuffers)
     return;
 }
 
+/*!
+ * Read and return the requested directory page.
+ *
+ * \param[in]   adc	pointer to directory dcache
+ * \param[in]	page	number of the desired directory page
+ * \param[out]	entry	buffer to return requested page
+ * \param[out]	physerr	(optional) pointer to return errno, if any
+ *
+ * \retval 0	    success
+ * \retval non-zero invalid directory or internal IO error;
+ *		    if physerr is supplied by caller, it will be set:
+ *			0	logical error
+ *			errno	physical error
+ */
 int
-DRead(struct dcache *adc, int page, struct DirBuffer *entry)
+DReadWithErrno(struct dcache *adc, int page, struct DirBuffer *entry, int *physerr)
 {
     /* Read a page from the disk. */
     struct buffer *tb, *tb2;
@@ -157,8 +171,20 @@ DRead(struct dcache *adc, int page, struct DirBuffer *entry)
 
     AFS_STATCNT(DRead);
 
+    if (physerr != NULL)
+	*physerr = 0;
+
     memset(entry, 0, sizeof(struct DirBuffer));
 
+    if (adc->f.chunk == 0 && adc->f.chunkBytes == 0) {
+        /* The directory blob is empty, apparently. This is not a valid dir
+         * blob, so throw an error. */
+        return EIO;
+    }
+    if (page * AFS_BUFFER_PAGESIZE >= adc->f.chunkBytes) {
+        return ENOENT; /* past the end */
+    }
+
     ObtainWriteLock(&afs_bufferLock, 256);
 
 #define bufmatch(tb) (tb->page == page && tb->fid == adc->index)
@@ -231,17 +257,6 @@ DRead(struct dcache *adc, int page, struct DirBuffer *entry)
     ObtainWriteLock(&tb->lock, 260);
     tb->lockers++;
     ReleaseWriteLock(&afs_bufferLock);
-    code = 0;
-    if (adc->f.chunk == 0 && adc->f.chunkBytes == 0) {
-        /* The directory blob is empty, apparently. This is not a valid dir
-         * blob, so throw an error. */
-        code = EIO;
-	goto error;
-    } else if (page * AFS_BUFFER_PAGESIZE >= adc->f.chunkBytes) {
-        code = ENOENT; /* past the end */
-	goto error;
-    }
-
     tfile = afs_CFileOpen(&adc->f.inode);
     if (!tfile) {
 	code = EIO;
@@ -252,6 +267,8 @@ DRead(struct dcache *adc, int page, struct DirBuffer *entry)
 		      AFS_BUFFER_PAGESIZE);
     afs_CFileClose(tfile);
     if (code < AFS_BUFFER_PAGESIZE) {
+	if (code < 0 && physerr != NULL)
+	   *physerr = -code;
 	code = EIO;
 	goto error;
     }
@@ -270,6 +287,22 @@ DRead(struct dcache *adc, int page, struct DirBuffer *entry)
     return code;
 }
 
+/*!
+ * Read and return the requested directory page.
+ *
+ * \param[in]   adc	pointer to directory dcache
+ * \param[in]	page	number of the desired directory page
+ * \param[out]	entry	buffer to return requested page
+ *
+ * \retval 0	    success
+ * \retval non-zero invalid directory or internal IO error;
+ */
+int
+DRead(struct dcache *adc, int page, struct DirBuffer *entry)
+{
+    return DReadWithErrno(adc, page, entry, NULL);
+}
+
 static void
 FixupBucket(struct buffer *ap)
 {
diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c
index e278a0848d..3572f2f231 100644
--- a/src/afs/afs_dcache.c
+++ b/src/afs/afs_dcache.c
@@ -1734,14 +1734,118 @@ afs_AllocDCache(struct vcache *avc, afs_int32 chunk, afs_int32 lock,
     return tdc;
 }
 
+static int
+IsDCacheSizeOK(struct dcache *adc, struct vcache *avc, afs_int32 chunk_bytes,
+	       afs_size_t file_length, afs_uint32 versionNo, int from_net)
+{
+    afs_size_t expected_bytes;
+    afs_size_t chunk_start = AFS_CHUNKTOBASE(adc->f.chunk);
+
+    if (vType(avc) == VDIR) {
+	/*
+	 * Directory blobs may be constructed locally (see afs_LocalHero), and
+	 * the size of the blob may differ slightly compared to what's on the
+	 * fileserver. So, skip size checks for directories.
+	 */
+	return 1;
+    }
+
+    if ((avc->f.states & CDirty)) {
+	/*
+	 * Our vcache may have writes that are local to our cache, but not yet
+	 * written to the fileserver. In such a situation, we may have dcaches
+	 * for that file that are "short". For example:
+	 *
+	 * Say we have a file that is 0 bytes long. A process opens that file,
+	 * and writes some data to offset 5M (keeping the file open). Another
+	 * process comes along and reads data from offset 1M. We'll try to
+	 * fetch data at offset 1M, and the fileserver will respond with 0
+	 * bytes, since our locally-written data hasn't been written to the
+	 * fileserver yet (on the fileserver, the file is still 0-bytes long).
+	 * So our dcache at offset 1M will have 0 bytes.
+	 *
+	 * So if CDirty is set, don't do any size/length checks at all, since
+	 * we have no idea if the avc length is valid.
+	 */
+	return 1;
+    }
+
+    if (file_length < chunk_start) {
+	expected_bytes = 0;
+
+    } else {
+	expected_bytes = file_length - chunk_start;
+
+	if (vType(avc) != VDIR && expected_bytes > AFS_CHUNKTOSIZE(adc->f.chunk)) {
+	    /* A non-dir chunk cannot have more bytes than the chunksize. */
+	    expected_bytes = AFS_CHUNKTOSIZE(adc->f.chunk);
+	}
+    }
+
+    if (chunk_bytes != expected_bytes) {
+	static const afs_uint32 one_hour = 60 * 60;
+	static afs_uint32 last_warn;
+	afs_uint32 now = osi_Time();
+
+	if (now < last_warn) {
+	    /* clock went backwards */
+	    last_warn = now;
+	}
+
+	if (now - last_warn > one_hour) {
+	    unsigned int mtime = adc->f.modTime;
+
+	    last_warn = now;
+
+	    if (from_net) {
+		/*
+		 * The dcache we're looking at didn't come from the cache, but is
+		 * being populated from the net. Don't print out its mtime in that
+		 * case; that would be misleading since that's the mtime from the
+		 * last time this dcache slot was written to.
+		 */
+		mtime = 0;
+	    }
+
+	    afs_warn("afs: Detected corrupt dcache for file %d.%u.%u.%u: chunk %d "
+		     "(offset %lu) has %d bytes, but it should have %lu bytes\n",
+		     adc->f.fid.Cell,
+		     adc->f.fid.Fid.Volume,
+		     adc->f.fid.Fid.Vnode,
+		     adc->f.fid.Fid.Unique,
+		     adc->f.chunk,
+		     (unsigned long)chunk_start,
+		     chunk_bytes,
+		     (unsigned long)expected_bytes);
+	    afs_warn("afs: (dcache %p, file length %lu, DV %u, dcache mtime %u, "
+		     "index %d, dflags 0x%x, mflags 0x%x, states 0x%x, vcache "
+		     "states 0x%x)\n",
+		     adc,
+		     (unsigned long)file_length,
+		     versionNo,
+		     mtime,
+		     adc->index,
+		     (unsigned)adc->dflags,
+		     (unsigned)adc->mflags,
+		     (unsigned)adc->f.states,
+		     avc->f.states);
+	    afs_warn("afs: Ignoring the dcache for now, but this may indicate "
+		     "corruption in the AFS cache, or a bug.\n");
+	}
+	return 0;
+    }
+    return 1;
+}
+
 /*!
  * Check if a dcache is "fresh". That is, if the dcache's DV matches the DV of
- * the vcache for that file.
+ * the vcache for that file, and the dcache looks "sane" (its length makes
+ * sense, when considering the length of the given avc).
  *
  * \param adc The dcache to check
  * \param avc The vcache for adc
  *
- * \return 1 if the dcache does match avc's DV; 0 otherwise.
+ * \return 1 if the dcache is "fresh". 0 otherwise.
  */
 int
 afs_IsDCacheFresh(struct dcache *adc, struct vcache *avc)
@@ -1749,6 +1853,20 @@ afs_IsDCacheFresh(struct dcache *adc, struct vcache *avc)
     if (!hsame(adc->f.versionNo, avc->f.m.DataVersion)) {
 	return 0;
     }
+
+    /*
+     * If we've reached here, the DV in adc matches the DV of our avc. Check if
+     * the number of bytes in adc agrees with the avc file length, as a sanity
+     * check. If they don't match, we'll pretend the DVs don't match, so the
+     * bad dcache data will not be used, and we'll probably re-fetch the chunk
+     * data, replacing the bad chunk.
+     */
+
+    if (!IsDCacheSizeOK(adc, avc, adc->f.chunkBytes, avc->f.m.Length,
+			hgetlo(adc->f.versionNo), 0)) {
+	return 0;
+    }
+
     return 1;
 }
 
@@ -2488,11 +2606,23 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte,
 		     * validPos is updated by CacheFetchProc, and can only be
 		     * modifed under a dcache write lock, which we've blocked out
 		     */
+		    afs_size_t length;
+
 		    size = tdc->validPos - Position;	/* actual segment size */
 		    if (size < 0)
 			size = 0;
 		    afs_CFileTruncate(file, size);	/* prune it */
-		} else {
+
+		    /* Check that the amount of data that we fetched for the
+		     * dcache makes sense. */
+		    FillInt64(length, tsmall->OutStatus.Length_hi, tsmall->OutStatus.Length);
+		    if (!IsDCacheSizeOK(tdc, avc, size,
+					length,
+					tsmall->OutStatus.DataVersion, 1)) {
+			code = EIO;
+		    }
+		}
+		if (code) {
 		    if (!setLocks || slowPass) {
 			afs_StaleVCacheFlags(avc, AFS_STALEVC_CLEARCB, CUnique);
 		    } else {
diff --git a/src/afs/afs_dynroot.c b/src/afs/afs_dynroot.c
index 281b168eb4..37200abc13 100644
--- a/src/afs/afs_dynroot.c
+++ b/src/afs/afs_dynroot.c
@@ -228,7 +228,7 @@ afs_dynroot_addDirEnt(struct DirHeader *dirHeader, int *curPageP,
 {
     char *dirBase = (char *)dirHeader;
     struct PageHeader *pageHeader;
-    struct DirEntry *dirEntry;
+    struct DirEntryFlex *dirEntry;
     int sizeOfEntry, i, t1, t2;
     int curPage = *curPageP;
     int curChunk = *curChunkP;
@@ -257,7 +257,7 @@ afs_dynroot_addDirEnt(struct DirHeader *dirHeader, int *curPageP,
 	dirHeader->alloMap[curPage] = EPP - 1;
     }
 
-    dirEntry = (struct DirEntry *)(pageHeader + curChunk);
+    dirEntry = (struct DirEntryFlex *)(pageHeader + curChunk);
     dirEntry->flag = 1;
     dirEntry->length = 0;
     dirEntry->next = 0;
diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h
index f92c3f9391..79c44a985e 100644
--- a/src/afs/afs_osi.h
+++ b/src/afs/afs_osi.h
@@ -149,6 +149,12 @@ extern void osi_PrePopulateVCache(struct vcache *);
 extern void osi_PostPopulateVCache(struct vcache *);
 extern void osi_AttachVnode(struct vcache *, int seq);
 
+#ifdef AFS_LINUX_ENV
+extern void osi_ResetVCache(struct vcache *avc);
+#else
+# define osi_ResetVCache(avc) do { } while (0)
+#endif
+
 /**
  * Increment the refcount on the given vcache.
  *
diff --git a/src/afs/afs_user.c b/src/afs/afs_user.c
index 693b506489..5631b37d0c 100644
--- a/src/afs/afs_user.c
+++ b/src/afs/afs_user.c
@@ -77,7 +77,7 @@ afs_GCUserData(void)
 	    delFlag = 0;	/* should we delete this dude? */
 	    /* Don't garbage collect users in use now (refCount) */
 	    if (tu->refCount == 0) {
-		if (tu->tokens) {
+		if (tu->tokens != NULL && (tu->states & UHasTokens) != 0) {
 		    /* Need to walk the token stack, and dispose of
 		     * all expired tokens */
 		    afs_DiscardExpiredTokens(&tu->tokens, now);
diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c
index 6d22f6f609..e72b45ea42 100644
--- a/src/afs/afs_vcache.c
+++ b/src/afs/afs_vcache.c
@@ -807,12 +807,16 @@ afs_VCacheStressed(void)
 int
 afs_ShakeLooseVCaches(afs_int32 anumber)
 {
+    /* Try not to run for more than about 3 seconds */
+    static const int DEADLINE = 3;
+
     afs_int32 i, loop;
     int evicted;
     struct vcache *tvc;
     struct afs_q *tq, *uq;
     int fv_slept, defersleep = 0;
     int limit;
+    afs_uint32 start = osi_Time();
 
     loop = 0;
 
@@ -841,8 +845,33 @@ afs_ShakeLooseVCaches(afs_int32 anumber)
 	}
 
 	if (fv_slept) {
-	    if (loop++ > 100)
-		break;
+	    if (loop++ > 100) {
+		afs_uint32 now = osi_Time();
+		loop = 0;
+		if (now < start) {
+		    start = now;
+		}
+		if (now - start >= DEADLINE) {
+		    static afs_uint32 last_warned;
+		    /* Warn about this at most every VCACHE_STRESS_LOGINTERVAL secs */
+		    if (now < last_warned ||
+			now - last_warned > VCACHE_STRESS_LOGINTERVAL) {
+			last_warned = now;
+			afs_warn("afs: Warning: it took us a long time (around "
+				 "%d seconds) to try to trim our stat cache "
+				 "down to a reasonable size. This may indicate "
+				 "someone is accessing an excessive number of "
+				 "files, or something is wrong with the AFS "
+				 "cache.\n",
+				 now - start);
+			afs_warn("afs: Consider raising the afsd -stat parameter "
+				 "(current setting: %d, current vcount: %d), or "
+				 "figure out what is accessing so many files.\n",
+				 afs_cacheStats, afs_vcount);
+		    }
+		    break;
+		}
+	    }
 	    if (!evicted) {
 		/*
 		 * This vcache was busy and we slept while trying to evict it.
@@ -2561,6 +2590,8 @@ afs_ResetVCache(struct vcache *avc, afs_ucred_t *acred, afs_int32 skipdnlc)
 	afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
 	avc->linkData = NULL;
     }
+
+    osi_ResetVCache(avc);
 }
 
 /*!
diff --git a/src/afsd/CellServDB b/src/afsd/CellServDB
index 2cc93965a8..63e3330a38 100644
--- a/src/afsd/CellServDB
+++ b/src/afsd/CellServDB
@@ -1,4 +1,4 @@
->grand.central.org      #GCO Public CellServDB 09 May 2022
+>grand.central.org      #GCO Public CellServDB 31 Oct 2023
 18.9.48.14                      #grand.mit.edu
 128.2.13.219                    #grand-old-opry.central.org
 >wu-wien.ac.at          #University of Economics, Vienna, Austria
@@ -26,9 +26,8 @@
 129.128.125.40                  #drake.ucs.ualberta.ca
 >cern.ch                #European Laboratory for Particle Physics, Geneva
 137.138.54.120                  #afsdb13.cern.ch
-137.138.128.148                 #afsdb1.cern.ch
-137.138.246.51                  #afsdb2.cern.ch
 188.184.21.218                  #afsdb11.cern.ch
+188.184.23.130                  #afsdb14.cern.ch
 188.184.81.230                  #afsdb12.cern.ch
 >ams.cern.ch            #AMS Experiment
 >epfl.ch                #Swiss Federal Institute of Technology at Lausanne
@@ -95,7 +94,7 @@
 >ipp-garching.mpg.de    #Institut fuer Plasmaphysik
 130.183.9.5                     #afs-db1.rzg.mpg.de
 130.183.14.14                   #afs-db3.bc.rzg.mpg.de
-130.183.100.10                  #afs-db2.aug.ipp-garching.mpg.de
+130.183.30.30                   #afs-db4.mpcdf.mpg.de
 >mpe.mpg.de             #MPE cell
 130.183.130.7                   #irafs1.mpe-garching.mpg.de
 130.183.134.20                  #irafs2.mpe-garching.mpg.de
@@ -196,16 +195,10 @@
 128.2.10.2                      #afsdb-01.andrew.cmu.edu
 128.2.10.7                      #afsdb-02.andrew.cmu.edu
 128.2.10.11                     #afsdb-03.andrew.cmu.edu
->mw.andrew.cmu.edu      #Carnegie Mellon University - Middleware Test Cell
-128.2.234.24                    #null.andrew.cmu.edu
-128.2.234.170                   #mw-mgr.andrew.cmu.edu
 >club.cc.cmu.edu        #Carnegie Mellon University Computer Club
 128.2.204.149                   #barium.club.cc.cmu.edu
 128.237.157.11                  #sodium.club.cc.cmu.edu
 128.237.157.13                  #potassium.club.cc.cmu.edu
->chem.cmu.edu           #Carnegie Mellon University - Chemistry Dept.
-128.2.40.134                    #afs.chem.cmu.edu
-128.2.40.140                    #afs2.chem.cmu.edu
 >cs.cmu.edu             #Carnegie Mellon University - School of Comp. Sci.
 128.2.104.79                    #afsdb-scs-01.srv.cs.cmu.edu
 128.2.104.80                    #afsdb-scs-02.srv.cs.cmu.edu
@@ -214,15 +207,10 @@
 128.2.129.7                     #porok.ece.cmu.edu
 128.2.129.8                     #vicio.ece.cmu.edu
 128.2.129.9                     #e-xing.ece.cmu.edu
->scotch.ece.cmu.edu     #CMU ECE CALCM research group
-128.2.134.82                    #lagavulin.ece.cmu.edu
 >qatar.cmu.edu          #Carnegie Mellon University - Qatar
 86.36.46.6                      #afsdb-01.qatar.cmu.edu
 86.36.46.7                      #afsdb-02.qatar.cmu.edu
 86.36.46.9                      #afsdb-03.qatar.cmu.edu
->sbp.ri.cmu.edu         #Carnegie Mellon University - Sensor Based Planning Lab
-128.2.179.12                    #nihao.sbp.ri.cmu.edu
-128.2.179.113                   #youtheman.sbp.ri.cmu.edu
 >ee.cooper.edu          #The Cooper Union EE Department
 199.98.27.202                   #stallman.ee.cooper.edu
 >cnf.cornell.edu        #CNF
@@ -242,9 +230,9 @@
 129.170.30.144                  #dbicafs2.dartmouth.edu
 129.170.30.145                  #dbicafs3.dartmouth.edu
 >northstar.dartmouth.edu #Dartmouth College Research Computing
-129.170.16.22                   #halley.dartmouth.edu
-129.170.16.26                   #andromeda.dartmouth.edu
-129.170.199.250                 #kuiper.dartmouth.edu
+129.170.137.194                 #halley.dartmouth.edu
+129.170.137.195                 #andromeda.dartmouth.edu
+129.170.137.196                 #kuiper.dartmouth.edu
 >cs.hm.edu              #Department Computer Science Munich University Of Applied Science
 129.187.208.31                  #afs1.cs.hm.edu
 >eecs.harvard.edu       #Harvard - EECS
@@ -286,9 +274,9 @@
 136.142.8.20                    #afs10.srv.cis.pitt.edu
 136.142.8.21                    #afs11.srv.cis.pitt.edu
 >cs.pitt.edu            #University of Pittsburgh - Computer Science
-136.142.22.5                    #afs01.cs.pitt.edu
-136.142.22.6                    #afs02.cs.pitt.edu
-136.142.22.7                    #afs03.cs.pitt.edu
+136.142.55.232                  #afs01.cs.pitt.edu
+136.142.55.233                  #afs02.cs.pitt.edu
+136.142.55.234                  #afs03.cs.pitt.edu
 >psc.edu                #PSC (Pittsburgh Supercomputing Center)
 128.182.59.182                  #shaggy.psc.edu
 128.182.66.184                  #velma.psc.edu
@@ -339,17 +327,17 @@
 130.85.24.87                    #db3.afs.umbc.edu
 130.85.24.101                   #db1.afs.umbc.edu
 >glue.umd.edu           #University of Maryland - Project Glue
-128.8.70.11                     #olmec.umd.edu
 128.8.163.205                   #hurricane.umd.edu
 128.8.236.2                     #cyclone.umd.edu
+128.8.236.230                   #babylon.umd.edu
 >umich.edu              #University of Michigan - Campus
 141.211.1.32                    #fear.ifs.umich.edu
 141.211.1.33                    #surprise.ifs.umich.edu
 141.211.1.34                    #ruthless.ifs.umich.edu
 >atlas.umich.edu        #ATLAS group cell in physics at University of Michigan
-141.211.43.102                  #linat02.grid.umich.edu
-141.211.43.103                  #linat03.grid.umich.edu
-141.211.43.104                  #linat04.grid.umich.edu
+192.41.230.102                  #linat02.aglt2.org
+192.41.230.103                  #linat03.aglt2.org
+192.41.230.104                  #linat04.aglt2.org
 >citi.umich.edu         #University of Michigan - Center for Information Technology Integ
 141.212.112.5                   #babylon.citi.umich.edu
 >isis.unc.edu           #Univ. of NC at Chapel Hill - ITS
@@ -505,9 +493,9 @@
 66.66.102.254                   #supercore.laroia.net
 >pallissard.net         #pallissard.net
 >sinenomine.net         #Sine Nomine Associates
-207.89.43.108                   #afsdb3.sinenomine.net
-207.89.43.109                   #afsdb4.sinenomine.net
-207.89.43.110                   #afsdb5.sinenomine.net
+198.44.193.30                   #afsdb3.sinenomine.net
+198.44.193.31                   #afsdb4.sinenomine.net
+198.44.193.32                   #afsdb5.sinenomine.net
 >slackers.net           #The Slackers' Network
 199.4.150.159                   #alexandria.slackers.net
 >tproa.net              #The People's Republic of Ames
@@ -530,13 +518,9 @@
 66.93.61.184                    #vice1.coed.org
 128.237.157.35                  #vice3.coed.org
 >dementia.org           #Dementia Unlimited (old)
-128.2.13.209                    #dedlock.dementix.org
-128.2.234.204                   #vorkana.dementix.org
-128.2.235.26                    #meredith.dementix.org
+204.29.154.67                   #alice-comfort.dementix.org
 >dementix.org           #Dementia Unlimited
-128.2.13.209                    #dedlock.dementix.org
-128.2.234.204                   #vorkana.dementix.org
-128.2.235.26                    #meredith.dementix.org
+204.29.154.67                   #alice-comfort.dementix.org
 >idahofuturetruck.org   #University of Idaho hybrid vehicle development
 12.18.238.210                   #dsle210.fsr.net
 >afs.ietfng.org         #ietfng.org
@@ -560,7 +544,7 @@
 >riscpkg.org            #The RISC OS Packaging Project
 83.104.175.10                   #delenn.riscpkg.org
 >kth.se                 #Royal Institute of Technology, Stockholm, Sweden
-130.237.32.145                  #sonen.e.kth.se
+130.237.48.5                    #sonen.e.kth.se
 130.237.48.7                    #anden.e.kth.se
 130.237.48.244                  #fadern.e.kth.se
 >ict.kth.se             #Royal Institute of Technology, Information and Communication tec
@@ -568,17 +552,17 @@
 130.237.216.12                  #afsdb2.ict.kth.se
 130.237.216.13                  #afsdb3.ict.kth.se
 >it.kth.se              #Royal Institute of Technology, Teleinformatics, Kista
-130.237.48.190                  #itafs-1.sys.kth.se
+130.237.48.68                   #itafs-2.sys.kth.se
 >md.kth.se              #Royal Institute of Technology, MMK
-130.237.48.223                  #mdafs-2.sys.kth.se
+130.237.48.170                  #mdafs-3.sys.kth.se
 >mech.kth.se            #Royal Institute of Technology, MECH
 130.237.233.142                 #matterhorn.mech.kth.se
 130.237.233.143                 #castor.mech.kth.se
 130.237.233.144                 #pollux.mech.kth.se
 >nada.kth.se            #Royal Institute of Technology, NADA
-130.237.32.150                  #nadaafsdb-2.sys.kth.se
-130.237.48.8                    #nadaafsdb-3.sys.kth.se
-130.237.227.23                  #afsdb-4.csc.kth.se
+130.237.48.8                    #nadaafs-3.sys.kth.se
+130.237.48.41                   #nadaafs-1.sys.kth.se
+130.237.48.58                   #nadaafs-2.sys.kth.se
 >pdc.kth.se             #Royal Institute of Technology, PDC
 130.237.232.29                  #crab.pdc.kth.se
 130.237.232.112                 #anna.pdc.kth.se
@@ -600,6 +584,8 @@
 >p-ng.si                #University of Nova Gorica
 193.2.120.2                     #solkan.p-ng.si
 193.2.120.9                     #sabotin.p-ng.si
+>ung.si                 #University of Nova Gorica
+193.2.120.63                    #afs1.ung.si
 >ihep.su                #Institute for High-Energy Physics
 194.190.165.201                 #fs0001.ihep.su
 194.190.165.202                 #fs0002.ihep.su
diff --git a/src/bozo/bos.c b/src/bozo/bos.c
index 7d56ce07a6..62f2a60303 100644
--- a/src/bozo/bos.c
+++ b/src/bozo/bos.c
@@ -88,6 +88,7 @@ GetConn(struct cmd_syndesc *as, int aencrypt)
     char *hostname;
     char *cellname = NULL;
     const char *confdir;
+    const char *retry_confdir;
     afs_int32 code;
     struct rx_connection *tconn;
     afs_int32 addr;
@@ -113,16 +114,23 @@ GetConn(struct cmd_syndesc *as, int aencrypt)
     if (as->parms[ADDPARMOFFSET + 2].items) { /* -localauth */
 	secFlags |= AFSCONF_SECOPTS_LOCALAUTH;
 	confdir = AFSDIR_SERVER_ETC_DIRPATH;
+	retry_confdir = NULL;
     } else {
 	confdir = AFSDIR_CLIENT_ETC_DIRPATH;
+	retry_confdir = AFSDIR_SERVER_ETC_DIRPATH;
     }
 
     if (as->parms[ADDPARMOFFSET + 1].items) { /* -noauth */
+	/* If we're running with -noauth, we don't need a configuration
+	 * directory. */
 	secFlags |= AFSCONF_SECOPTS_NOAUTH;
     } else {
-	/* If we're running with -noauth, we don't need a configuration
-	 * directory */
 	tdir = afsconf_Open(confdir);
+	if (tdir == NULL && retry_confdir != NULL) {
+	    fprintf(stderr, "bos: Retrying initialization with directory %s\n",
+		    retry_confdir);
+	    tdir = afsconf_Open(retry_confdir);
+	}
 	if (tdir == NULL) {
 	    fprintf(stderr, "bos: can't open cell database (%s)\n", confdir);
 	    exit(1);
diff --git a/src/bozo/bosserver.c b/src/bozo/bosserver.c
index 7286b67271..371cb638e4 100644
--- a/src/bozo/bosserver.c
+++ b/src/bozo/bosserver.c
@@ -246,13 +246,9 @@ MakeDir(const char *adir)
 static int
 CreateDirs(const char *coredir)
 {
-    if ((!strncmp
-	 (AFSDIR_USR_DIRPATH, AFSDIR_CLIENT_ETC_DIRPATH,
-	  strlen(AFSDIR_USR_DIRPATH)))
-	||
-	(!strncmp
+    if (!strncmp
 	 (AFSDIR_USR_DIRPATH, AFSDIR_SERVER_BIN_DIRPATH,
-	  strlen(AFSDIR_USR_DIRPATH)))) {
+	  strlen(AFSDIR_USR_DIRPATH))) {
 	if (MakeDir(AFSDIR_USR_DIRPATH))
 	    return errno;
     }
@@ -272,29 +268,6 @@ CreateDirs(const char *coredir)
 	return errno;
     if (MakeDir(AFSDIR_SERVER_LOGS_DIRPATH))
 	return errno;
-#ifndef AFS_NT40_ENV
-    if (!strncmp
-	(AFSDIR_CLIENT_VICE_DIRPATH, AFSDIR_CLIENT_ETC_DIRPATH,
-	 strlen(AFSDIR_CLIENT_VICE_DIRPATH))) {
-	if (MakeDir(AFSDIR_CLIENT_VICE_DIRPATH))
-	    return errno;
-    }
-    if (MakeDir(AFSDIR_CLIENT_ETC_DIRPATH))
-	return errno;
-
-    if (symlink(AFSDIR_SERVER_THISCELL_FILEPATH,
-	    AFSDIR_CLIENT_THISCELL_FILEPATH)) {
-	if (errno != EEXIST) {
-	    return errno;
-	}
-    }
-    if (symlink(AFSDIR_SERVER_CELLSERVDB_FILEPATH,
-	    AFSDIR_CLIENT_CELLSERVDB_FILEPATH)) {
-	if (errno != EEXIST) {
-	    return errno;
-	}
-    }
-#endif /* AFS_NT40_ENV */
     if (coredir) {
 	if (MakeDir(coredir))
 	    return errno;
@@ -1186,6 +1159,15 @@ main(int argc, char **argv, char **envp)
 	exit(code);
     }
 
+    if (bozo_isrestricted) {
+	bozo_Log("NOTICE: bosserver is running in restricted mode.\n");
+    } else {
+	bozo_Log("WARNING: bosserver is not running in restricted mode.\n");
+	bozo_Log("WARNING: Superusers have unrestricted access to this host via bos.\n");
+	bozo_Log("WARNING: Use 'bos setrestricted' or restart with the -restricted option\n");
+	bozo_Log("WARNING: to enable restricted mode.\n");
+    }
+
     if (rxBind) {
 	host = GetRxBindAddress();
     }
diff --git a/src/budb/database.c b/src/budb/database.c
index a57d830b18..a68b1f241c 100644
--- a/src/budb/database.c
+++ b/src/budb/database.c
@@ -108,8 +108,8 @@ dbread(struct ubik_trans *ut, afs_int32 pos, void *buff, afs_int32 len)
     }
     code = ubik_Read(ut, buff, len);
     if (code) {
-	LogError(code, "dbread: ubik_Read pos %d, buff %"AFS_PTR_FMT
-		 ", len %d\n", pos, buff, len);
+	LogError(code, "dbread: ubik_Read pos %d, buff %p, len %d\n",
+		 pos, buff, len);
 	ERROR(code);
     }
 
@@ -143,8 +143,8 @@ cdbread(struct ubik_trans *ut, int type, afs_int32 pos, void *buff, afs_int32 le
     }
     code = ubik_Read(ut, buff, len);
     if (code) {
-	LogError(code, "cdbread: ubik_Read pos 0x%x, buff %"AFS_PTR_FMT
-		 ", len %d\n", pos, buff, len);
+	LogError(code, "cdbread: ubik_Read pos 0x%x, buff %p, len %d\n",
+		 pos, buff, len);
 	ERROR(code);
     }
 
diff --git a/src/budb/db_hash.c b/src/budb/db_hash.c
index b2b00d6852..eee8604a5f 100644
--- a/src/budb/db_hash.c
+++ b/src/budb/db_hash.c
@@ -884,7 +884,7 @@ ht_HashIn(struct ubik_trans *ut,
 		      htonl(ea));
     if (code)
 	return BUDB_IO;
-    LogDebug(5, "Hashin: set %"AFS_PTR_FMT" to %d\n",
+    LogDebug(5, "Hashin: set %p to %d\n",
 	     &block->b.bucket[bo], htonl(ea));
 
     pentries = &ht->entries;
diff --git a/src/budb/db_text.c b/src/budb/db_text.c
index e88ef51e7f..d66d8344db 100644
--- a/src/budb/db_text.c
+++ b/src/budb/db_text.c
@@ -69,8 +69,8 @@ GetText(struct rx_call *call, afs_uint32 lockHandle, afs_int32 textType,
     char *textPtr;
     afs_int32 code;
 
-    LogDebug(5, "GetText: type %d, offset %d, nextOffset %"AFS_PTR_FMT
-	     ", maxLength %d\n", textType, offset, nextOffset, maxLength);
+    LogDebug(5, "GetText: type %d, offset %d, nextOffset %p, maxLength %d\n",
+		textType, offset, nextOffset, maxLength);
 
     if (callPermitted(call) == 0) {
 	code = BUDB_NOTPERMITTED;
diff --git a/src/cf/c-flexible-array.m4 b/src/cf/c-flexible-array.m4
new file mode 100644
index 0000000000..e281166f82
--- /dev/null
+++ b/src/cf/c-flexible-array.m4
@@ -0,0 +1,16 @@
+AC_DEFUN([OPENAFS_C_FLEXIBLE_ARRAY],[
+  dnl Check to see if the compiler support C99 flexible arrays, e.g., var[]
+  AC_MSG_CHECKING([for C99 flexible arrays])
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+      struct flexarraytest {
+          int flag;
+          int numbers[];
+      };
+      ]], [[]])
+    ],
+    [AC_MSG_RESULT([yes])
+     AC_DEFINE([HAVE_FLEXIBLE_ARRAY], [1],
+       [Define to 1 if your compiler supports C99 flexible arrays.])
+    ],[AC_MSG_RESULT([no])]
+  )
+])
diff --git a/src/cf/gcc.m4 b/src/cf/gcc.m4
new file mode 100644
index 0000000000..bcd30ac39d
--- /dev/null
+++ b/src/cf/gcc.m4
@@ -0,0 +1,51 @@
+dnl Checks for specific gcc behavior
+
+dnl Helper to test for UAF warning message
+dnl _OPENAFS_UAF_COMPILE_IFELSE([success], [fail])
+AC_DEFUN([_OPENAFS_UAF_COMPILE_IFELSE],[
+    AC_COMPILE_IFELSE(
+	[AC_LANG_PROGRAM([[
+		#include <stdlib.h>
+		struct gcc_check {
+		    char *ptr;
+		};
+		void test(struct gcc_check *p, char *cp, int size)
+		{
+		    p->ptr = realloc(cp, size);
+		    if (p->ptr == NULL && size != 0) {
+			free(cp);	/* If compiler has UAF bug this will be flagged */
+		    }
+		}
+	    ]]
+	)],
+	[$1],
+	[$2]
+    )
+])
+
+dnl Check to see if the GCC compiler incorrectly flags use-after-free (UAF).
+dnl This false positive has been observed with gcc 12 when
+dnl optimization is disabled (-O0) and gcc 13.
+AC_DEFUN([OPENAFS_GCC_UAF_BUG_CHECK],[
+    CFLAGS_USE_AFTER_FREE_GCCBUG=
+    AS_IF([test "x$GCC" = "xyes"], [
+	AC_MSG_CHECKING([gcc use-after-free warning bug])
+	ac_save_CFLAGS="$CFLAGS"
+	CFLAGS="$CFLAGS -Wall -Werror -O0 -U_FORTIFY_SOURCE"
+	_OPENAFS_UAF_COMPILE_IFELSE(
+	    [AC_MSG_RESULT(no)],
+	    [
+		dnl Compiler flagged an error.  Run one more check to ensure
+		dnl the error was only the false positive for a UAF.
+		AX_APPEND_COMPILE_FLAGS([-Wno-use-after-free],
+					[CFLAGS_USE_AFTER_FREE_GCCBUG], [-Werror])
+		CFLAGS=" $CFLAGS $CFLAGS_USE_AFTER_FREE_GCCBUG"
+		_OPENAFS_UAF_COMPILE_IFELSE(
+		    [AC_MSG_RESULT(yes)],
+		    [AC_MSG_ERROR([Unexpected compiler error while testing for gcc use-after-free bug])])
+	    ]
+	)
+	CFLAGS="$ac_save_CFLAGS"
+    ])
+    AC_SUBST([CFLAGS_USE_AFTER_FREE_GCCBUG])
+])
diff --git a/src/cf/linux-kernel-assorted.m4 b/src/cf/linux-kernel-assorted.m4
index 03d5f65830..49827d5be9 100644
--- a/src/cf/linux-kernel-assorted.m4
+++ b/src/cf/linux-kernel-assorted.m4
@@ -39,7 +39,9 @@ LINUX_LINUX_KEYRING_SUPPORT
 LINUX_KEY_ALLOC_NEEDS_STRUCT_TASK
 LINUX_KEY_ALLOC_NEEDS_CRED
 LINUX_INIT_WORK_HAS_DATA
-LINUX_REGISTER_SYSCTL_TABLE_NOFLAG
+dnl Don't bother checking register_sysctl_table if using register_sysctl
+AS_IF([test "x$ac_cv_linux_func_register_sysctl" != "xyes"],
+      [LINUX_REGISTER_SYSCTL_TABLE_NOFLAG])
 LINUX_HAVE_DCACHE_LOCK
 LINUX_D_COUNT_IS_INT
 LINUX_IOP_GETATTR_TAKES_PATH_STRUCT
@@ -56,6 +58,7 @@ LINUX_IOP_LOOKUP_TAKES_UNSIGNED
 LINUX_D_INVALIDATE_IS_VOID
 LINUX_KERNEL_READ_OFFSET_IS_LAST
 LINUX_KEYRING_SEARCH_TAKES_RECURSE
+LINUX_GENERIC_FILLATTR_TAKES_REQUEST_MASK
 ])
 
 
diff --git a/src/cf/linux-kernel-func.m4 b/src/cf/linux-kernel-func.m4
index ee22158db0..7f3000fc16 100644
--- a/src/cf/linux-kernel-func.m4
+++ b/src/cf/linux-kernel-func.m4
@@ -217,6 +217,41 @@ AC_CHECK_LINUX_FUNC([block_dirty_folio],
     		     #include <linux/buffer_head.h>],
     		    [block_dirty_folio(NULL, NULL);])
 
+dnl Linux 6.5 removed the Linux function register_sysctl_table(), which
+dnl was deprecated in Linux 6.3 in favor of register_sysctl() which was
+dnl introduced in Linux 3.3
+dnl Linux 6.6 changed the function register_sysctl to a macro that requires
+dnl an array of ctl_table structures as its 2nd parameter
+AC_CHECK_LINUX_FUNC([register_sysctl],
+		    [#include <linux/kernel.h>
+		     #include <linux/sysctl.h>],
+		    [[static struct ctl_table cf_sysctl_table[1];
+		    (void)register_sysctl(NULL, cf_sysctl_table);]])
+
+dnl Linux 6.5 removed the file_operations method 'iterate'.  Filesystems should
+dnl using the iterate_shared method (introduced in linux 4.6).  Linux 6.4
+dnl provides a wrapper that can be used for filesystems that haven't fully
+dnl converted to meet the iterate_shared requirements.
+
+AC_CHECK_LINUX_FUNC([wrap_directory_iterator],
+    		    [#include <linux/kernel.h>
+    		     #include <linux/fs.h>],
+    		    [(void)wrap_directory_iterator(NULL, NULL, NULL);])
+
+dnl Linux 6.6 requires the use of a getter/setter for accessing a inode's
+dnl ctime member.  Test for the setter inode_set_ctime
+AC_CHECK_LINUX_FUNC([inode_set_ctime],
+		    [#include <linux/fs.h>],
+		    [inode_set_ctime(NULL, 0, 0);])
+
+dnl Linux 6.7 requires the use of a getter/setter for accessing a inode's
+dnl atime and mtime members.  Test for the setters.  Assummes that the
+dnl getters are present if the setters are.
+AC_CHECK_LINUX_FUNC([inode_atime_mtime_accessors],
+		    [#include <linux/fs.h>],
+		    [inode_set_atime(NULL, 0, 0);
+		     inode_set_mtime(NULL, 0, 0);])
+
 dnl Consequences - things which get set as a result of the
 dnl                above tests
 AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"],
diff --git a/src/cf/linux-kernel-struct.m4 b/src/cf/linux-kernel-struct.m4
index 8082308e8c..2824ec1986 100644
--- a/src/cf/linux-kernel-struct.m4
+++ b/src/cf/linux-kernel-struct.m4
@@ -14,6 +14,9 @@ AC_CHECK_LINUX_STRUCT([backing_dev_info], [name],
 AC_CHECK_LINUX_STRUCT([cred], [session_keyring], [cred.h])
 AC_CHECK_LINUX_STRUCT([ctl_table], [ctl_name], [sysctl.h])
 AC_CHECK_LINUX_STRUCT([dentry], [d_u.d_alias], [dcache.h])
+dnl linux 2.6.16 moved dentry->d_child to dentry->d_u.d_child
+dnl linux 3.19 moved it back to dentry->d_child
+AC_CHECK_LINUX_STRUCT([dentry], [d_u.d_child], [dcache.h])
 AC_CHECK_LINUX_STRUCT([dentry_operations], [d_automount], [dcache.h])
 AC_CHECK_LINUX_STRUCT([group_info], [gid], [cred.h])
 AC_CHECK_LINUX_STRUCT([inode], [i_alloc_sem], [fs.h])
@@ -23,6 +26,7 @@ AC_CHECK_LINUX_STRUCT([inode], [i_mutex], [fs.h])
 AC_CHECK_LINUX_STRUCT([inode], [i_security], [fs.h])
 AC_CHECK_LINUX_STRUCT([file], [f_path], [fs.h])
 AC_CHECK_LINUX_STRUCT([file_operations], [flock], [fs.h])
+AC_CHECK_LINUX_STRUCT([file_operations], [iterate_shared], [fs.h])
 AC_CHECK_LINUX_STRUCT([file_operations], [iterate], [fs.h])
 AC_CHECK_LINUX_STRUCT([file_operations], [read_iter], [fs.h])
 AC_CHECK_LINUX_STRUCT([file_operations], [sendfile], [fs.h])
diff --git a/src/cf/linux-test1.m4 b/src/cf/linux-test1.m4
index 94bd0692ce..7bb5a677c2 100644
--- a/src/cf/linux-test1.m4
+++ b/src/cf/linux-test1.m4
@@ -173,7 +173,7 @@ AC_DEFUN([AC_CHECK_LINUX_TYPE],
  [AC_CHECK_LINUX_BUILD([for $1],
                        [ac_cv_linux_type_$1_exists],
                        [#include <linux/$2>],
-                       [$1 _test; ],
+                       [static $1 _test; ],
                        AS_TR_CPP(HAVE_LINUX_$1),
                        [Define if kernel defines $1])
  ])
@@ -188,7 +188,7 @@ AC_DEFUN([AC_CHECK_LINUX_TYPED_STRUCT],
  [AC_CHECK_LINUX_BUILD([for $2 in $1],
 		       [ac_cv_linux_$1_has_$2],
 		       [#include <linux/$3>],
-		       [$1 _test; printk("%x\n", &_test.$2); ],
+		       [static $1 _test; printk("%x\n", &_test.$2); ],
 		       AS_TR_CPP($1_HAS_$2),
 		       [Define if kernel $1 has the $2 element])
  ])
@@ -199,7 +199,10 @@ AC_DEFUN([AC_CHECK_LINUX_OPERATION],
   AC_CACHE_CHECK([operation $2 in $1], [ac_linux_operation],
     [save_CPPFLAGS="$CPPFLAGS"
      CPPFLAGS="$CPPFLAGS -Werror"
-     AC_TRY_KBUILD([$4], [struct $1 ops; $5 op($6) { return ($5)0; }; ops.$2 = op;],
+     AC_TRY_KBUILD(
+      [$4
+       $5 op($6) { return ($5)0; };],
+      [static struct $1 ops;  ops.$2 = op;],
 		   AS_VAR_SET([ac_linux_operation], [yes]),
 		   AS_VAR_SET([ac_linux_operation], [no]))
      CPPFLAGS="$save_CPPFLAGS"
diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4
index 0d6b645f41..3596b6aad0 100644
--- a/src/cf/linux-test4.m4
+++ b/src/cf/linux-test4.m4
@@ -132,7 +132,7 @@ AC_DEFUN([LINUX_SCHED_STRUCT_TASK_STRUCT_HAS_SIGNAL_RLIM], [
 #ifdef HAVE_LINUX_SCHED_SIGNAL_H
 #include <linux/sched/signal.h>
 #endif],
-		       [struct task_struct _tsk; printk("%d\n", _tsk.signal->rlim);],
+		       [static struct task_struct _tsk; printk("%d\n", _tsk.signal->rlim);],
 		       [STRUCT_TASK_STRUCT_HAS_SIGNAL_RLIM],
 		       [define if your struct task_struct has signal->rlim],
 		       [])
@@ -178,8 +178,8 @@ AC_DEFUN([LINUX_INODE_SETATTR_RETURN_TYPE], [
   AC_CHECK_LINUX_BUILD([for inode_setattr return type],
 		       [ac_cv_linux_func_inode_setattr_returns_int],
 		       [#include <linux/fs.h>],
-		       [struct inode _inode;
-			struct iattr _iattr;
+		       [static struct inode _inode;
+			static struct iattr _iattr;
 			int i;
 			i = inode_setattr(&_inode, &_iattr);],
 		       [INODE_SETATTR_NOT_VOID],
@@ -192,7 +192,7 @@ AC_DEFUN([LINUX_IATTR_64BIT_TIME], [
                        [ac_cv_linux_func_iattr_ctime_takes_timespec64],
                        [#include <linux/fs.h>
                         #include <linux/timekeeping.h>],
-                       [struct iattr _attrs;
+                       [static struct iattr _attrs;
                        #if defined(HAVE_LINUX_KTIME_GET_COARSE_REAL_TS64)
                         ktime_get_coarse_real_ts64(&_attrs.ia_ctime);
                        #else
@@ -210,9 +210,9 @@ AC_DEFUN([LINUX_AOP_WRITEBACK_CONTROL], [
 [#include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/writeback.h>],
-[struct address_space_operations _aops;
-struct page _page;
-struct writeback_control _writeback_control;
+[static struct address_space_operations _aops;
+static struct page _page;
+static struct writeback_control _writeback_control;
 (void)_aops.writepage(&_page, &_writeback_control);],
 		       [AOP_WRITEPAGE_TAKES_WRITEBACK_CONTROL],
 		       [define if aops.writepage takes a struct writeback_control],
@@ -239,9 +239,9 @@ AC_DEFUN([LINUX_IOP_I_CREATE_TAKES_NAMEIDATA], [
 		       [ac_cv_linux_func_i_create_takes_nameidata],
 [#include <linux/fs.h>
 #include <linux/namei.h>],
-[struct inode _inode;
-struct dentry _dentry;
-struct nameidata _nameidata;
+[static struct inode _inode;
+static struct dentry _dentry;
+static struct nameidata _nameidata;
 (void)_inode.i_op->create(&_inode, &_dentry, 0, &_nameidata);],
 
 		       [IOP_CREATE_TAKES_NAMEIDATA],
@@ -255,9 +255,9 @@ AC_DEFUN([LINUX_IOP_I_LOOKUP_TAKES_NAMEIDATA], [
 		       [ac_cv_linux_func_i_lookup_takes_nameidata],
 [#include <linux/fs.h>
 #include <linux/namei.h>],
-[struct inode _inode;
-struct dentry _dentry;
-struct nameidata _nameidata;
+[static struct inode _inode;
+static struct dentry _dentry;
+static struct nameidata _nameidata;
 (void)_inode.i_op->lookup(&_inode, &_dentry, &_nameidata);],
 		       [IOP_LOOKUP_TAKES_NAMEIDATA],
 		       [define if your iops.lookup takes a nameidata argument],
@@ -270,8 +270,8 @@ AC_DEFUN([LINUX_IOP_I_PERMISSION_TAKES_NAMEIDATA], [
 		       [ac_cv_linux_func_i_permission_takes_nameidata],
 [#include <linux/fs.h>
 #include <linux/namei.h>],
-[struct inode _inode;
-struct nameidata _nameidata;
+[static struct inode _inode;
+static struct nameidata _nameidata;
 (void)_inode.i_op->permission(&_inode, 0, &_nameidata);],
 		       [IOP_PERMISSION_TAKES_NAMEIDATA],
 		       [define if your iops.permission takes a nameidata argument],
@@ -297,8 +297,8 @@ AC_DEFUN([LINUX_IOP_I_PUT_LINK_TAKES_COOKIE], [
 		       [ac_cv_linux_func_i_put_link_takes_cookie],
 [#include <linux/fs.h>
 #include <linux/namei.h>],
-[struct inode _inode;
-struct dentry _dentry;
+[static struct inode _inode;
+static struct dentry _dentry;
 struct nameidata *_nameidata;
 void *cookie;
 (void)_inode.i_op->put_link(&_dentry, _nameidata, cookie);],
@@ -373,7 +373,7 @@ AC_DEFUN([LINUX_KEY_ALLOC_NEEDS_STRUCT_TASK], [
 			[ac_cv_key_alloc_needs_struct_task],
 			[#include <linux/rwsem.h>
 			#include <linux/key.h> ],
-			[struct task_struct *t=NULL;
+			[static struct task_struct *t=NULL;
 			struct key k = {};
 			(void) key_alloc(NULL, NULL, k.uid, k.gid, t, 0, 0);],
 			[KEY_ALLOC_NEEDS_STRUCT_TASK],
@@ -427,8 +427,8 @@ AC_DEFUN([LINUX_FOP_F_FLUSH_TAKES_FL_OWNER_T], [
   AC_CHECK_LINUX_BUILD([whether file_operations.flush takes a fl_owner_t],
 		       [ac_cv_linux_func_f_flush_takes_fl_owner_t],
 		       [#include <linux/fs.h>],
-[struct inode _inode;
-struct file _file;
+[static struct inode _inode;
+static struct file _file;
 fl_owner_t id;
 (void)_inode.i_fop->flush(&_file, &id);],
 		       [FOP_FLUSH_TAKES_FL_OWNER_T],
@@ -441,9 +441,9 @@ AC_DEFUN([LINUX_FOP_F_FSYNC_TAKES_DENTRY], [
   AC_CHECK_LINUX_BUILD([whether file_operations.fsync takes a dentry argument],
 		       [ac_cv_linux_func_f_fsync_takes_dentry],
 		       [#include <linux/fs.h>],
-[struct inode _inode;
-struct file _file;
-struct dentry _d;
+[static struct inode _inode;
+static struct file _file;
+static struct dentry _d;
 (void)_inode.i_fop->fsync(&_file, &_d, 0);],
 		       [FOP_FSYNC_TAKES_DENTRY],
 		       [define if your fops.fsync takes an dentry argument],
@@ -457,8 +457,8 @@ AC_DEFUN([LINUX_FOP_F_FSYNC_TAKES_RANGE], [
   AC_CHECK_LINUX_BUILD([whether file_operations.fsync takes a range],
 		       [ac_cv_linux_func_f_fsync_takes_range],
 		       [#include <linux/fs.h>],
-[struct inode _inode;
-struct file _file;
+[static struct inode _inode;
+static struct file _file;
 loff_t start, end;
 (void)_inode.i_fop->fsync(&_file, start, end, 0);],
 		       [FOP_FSYNC_TAKES_RANGE],
@@ -492,8 +492,9 @@ AC_DEFUN([LINUX_KMEM_CACHE_CREATE_TAKES_DTOR], [
 AC_DEFUN([LINUX_KMEM_CACHE_CREATE_CTOR_TAKES_VOID],[
   AC_CHECK_LINUX_BUILD([whether kmem_cache_create constructor takes a void pointer],
 			[ac_cv_linux_kmem_cache_create_ctor_takes_void],
-			[#include <linux/slab.h>],
-			[void _ctor(void *v) { }; kmem_cache_create(NULL, 0, 0, 0, _ctor);],
+			[#include <linux/slab.h>
+			 void _ctor(void *v) { };],
+			[kmem_cache_create(NULL, 0, 0, 0, _ctor);],
 			[KMEM_CACHE_CTOR_TAKES_VOID],
 			[define if kmem_cache_create constructor takes a single void ptr],
 			[-Werror])
@@ -507,7 +508,7 @@ AC_DEFUN([LINUX_FS_STRUCT_FOP_HAS_SPLICE], [
   AC_CHECK_LINUX_BUILD([for splice_write and splice_read in struct file_operations],
 		       [ac_cv_linux_fs_struct_fop_has_splice],
 		       [#include <linux/fs.h>],
-		       [struct file_operations _fop;
+		       [static struct file_operations _fop;
 			_fop.splice_write(NULL, NULL, NULL, 0, 0);
 			_fop.splice_read(NULL, NULL, NULL, 0, 0);],
 		       [STRUCT_FILE_OPERATIONS_HAS_SPLICE],
@@ -557,7 +558,7 @@ AC_DEFUN([LINUX_NEW_EXPORT_OPS], [
   AC_CHECK_LINUX_BUILD([if kernel uses new export ops],
 		       [ac_cv_linux_new_export_ops],
 		       [#include <linux/exportfs.h>],
-		       [struct export_operations _eops;
+		       [static struct export_operations _eops;
 			_eops.fh_to_parent(NULL, NULL, 0, 0);],
 		       [NEW_EXPORT_OPS],
 		       [define if kernel uses new export ops],
@@ -692,7 +693,7 @@ AC_DEFUN([LINUX_IOP_CREATE_TAKES_UMODE_T], [
   AC_CHECK_LINUX_BUILD([whether inode.i_op->create takes a umode_t argument],
 			[ac_cv_linux_iop_create_takes_umode_t],
 			[#include <linux/fs.h>],
-			[struct inode_operations _i_ops;
+			[static struct inode_operations _i_ops;
 			int _create(struct inode *i, struct dentry *d, umode_t m, struct nameidata *n)
 				{return 0;};
 			_i_ops.create = _create;],
@@ -731,7 +732,7 @@ AC_DEFUN([LINUX_DENTRY_OPEN_TAKES_PATH], [
   AC_CHECK_LINUX_BUILD([whether dentry_open takes a path argument],
 			[ac_cv_linux_dentry_open_takes_path],
 			[#include <linux/fs.h>],
-			[struct path p;
+			[static struct path p;
 			dentry_open(&p, 0, NULL);],
 			[DENTRY_OPEN_TAKES_PATH],
 			[define if dentry_open takes a path argument],
@@ -779,8 +780,8 @@ AC_DEFUN([LINUX_IOP_I_CREATE_TAKES_BOOL], [
 			[ac_cv_linux_func_i_create_takes_bool],
 			[#include <linux/fs.h>
 			#include <linux/namei.h>],
-			[struct inode _inode = {};
-			struct dentry _dentry;
+			[static struct inode _inode = {};
+			static struct dentry _dentry;
 			bool b = true;
 			(void)_inode.i_op->create(&_inode, &_dentry, 0, b);],
 		       [IOP_CREATE_TAKES_BOOL],
@@ -853,3 +854,16 @@ AC_DEFUN([LINUX_KEYRING_SEARCH_TAKES_RECURSE], [
                        [define if your keyring_search has the recurse parameter],
                        [])
 ])
+
+dnl Linux 6.6 added the 'request_mask' parameter to generic_fillattr.
+AC_DEFUN([LINUX_GENERIC_FILLATTR_TAKES_REQUEST_MASK], [
+  AC_CHECK_LINUX_BUILD([whether generic_fillattr has the request_mask parameter],
+                       [ac_cv_linux_func_generic_fillattr_takes_request_mask],
+                       [#include <linux/fs.h>],
+                       [
+                       generic_fillattr(NULL, 0, NULL, NULL);
+                       ],
+                       [GENERIC_FILLATTR_TAKES_REQUEST_MASK],
+                       [define if your generic_fillattr has the request_mask_parameter],
+                       [])
+])
diff --git a/src/cf/osconf.m4 b/src/cf/osconf.m4
index e5fdc22aa1..843998542e 100644
--- a/src/cf/osconf.m4
+++ b/src/cf/osconf.m4
@@ -347,7 +347,7 @@ case $AFS_SYSNAME in
 		XLIBS="${LIB_AFSDB} -framework CoreFoundation"
 		;;
 
-	*_darwin_190 | *_darwin_200 | *_darwin_210 | *_darwin_220)
+	*_darwin_190 | *_darwin_200 | *_darwin_210 | *_darwin_220 | *_darwin_230)
 		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration -framework SystemConfiguration -framework IOKit -framework CoreFoundation"
 		MT_CFLAGS="-D_REENTRANT"
 		MT_LIBS='${XLIBS}'
@@ -662,15 +662,24 @@ if test "x$GCC" = "xyes"; then
       CFLAGS_NOOLDSTYLE="-Wno-old-style-definition"
       AX_APPEND_COMPILE_FLAGS([-Wno-implicit-fallthrough],
 			      [CFLAGS_NOIMPLICIT_FALLTHROUGH], [-Werror])
-      AX_APPEND_COMPILE_FLAGS([-Wno-cast-function-type],
-			      [CFLAGS_NOCAST_FUNCTION_TYPE], [-Werror])
       AX_APPEND_COMPILE_FLAGS([-Wno-dangling-pointer],
 			      [CFLAGS_NODANGLING_POINTER], [-Werror])
+      OPENAFS_GCC_UAF_BUG_CHECK
       AC_DEFINE(IGNORE_SOME_GCC_WARNINGS, 1, [define to disable some gcc warnings in warnings-as-errors mode])
     else
       CFLAGS_NOSTRICT=
     fi
   fi
+dnl If a linux kernel has CONFIG_WERROR enabled, the openafs kernel module
+dnl will be built with the -Werror compiler flag even when the openafs tree is
+dnl configured with --disable-checking.
+
+dnl Provide compiler flags that can be used to disable certain warnings when the
+dnl openafs tree is configued with --enable-checking or --disable-checking.
+  AS_IF([test "x$enable_checking" != "xall"],
+	[AX_APPEND_COMPILE_FLAGS([-Wno-cast-function-type],
+				 [CFLAGS_NOCAST_FUNCTION_TYPE], [-Werror])
+  ])
 else
   case $AFS_SYSNAME in
     sun*_51?)
diff --git a/src/cf/sysname.m4 b/src/cf/sysname.m4
index c872c072fb..aa4ad2cb42 100644
--- a/src/cf/sysname.m4
+++ b/src/cf/sysname.m4
@@ -226,6 +226,18 @@ else
 			AFS_SYSNAME="arm_darwin_220"
 			OSXSDK="macosx13.0"
 			;;
+		x86_64-apple-darwin23.*)
+			AFS_SYSNAME="x86_darwin_230"
+			OSXSDK="macosx14.0"
+			;;
+		arm-apple-darwin23.*)
+			AFS_SYSNAME="arm_darwin_230"
+			OSXSDK="macosx14.0"
+			;;
+		aarch64-apple-darwin23.*)
+			AFS_SYSNAME="arm_darwin_230"
+			OSXSDK="macosx14.0"
+			;;
                 sparc-sun-solaris2.8)
                         AFS_SYSNAME="sun4x_58"
                         ;;
@@ -426,6 +438,9 @@ case $AFS_SYSNAME in
         *_darwin_220)
                 AFS_PARAM=param.darwin_220.h
                 ;;
+        *_darwin_230)
+                AFS_PARAM=param.darwin_230.h
+                ;;
         *)
                 AFS_PARAM=param.${AFS_SYSNAME}.h
                 ;;
diff --git a/src/config/NTMakefile.amd64_w2k b/src/config/NTMakefile.amd64_w2k
index bd279b7a87..d732ecc3a9 100644
--- a/src/config/NTMakefile.amd64_w2k
+++ b/src/config/NTMakefile.amd64_w2k
@@ -88,7 +88,7 @@ AFSPRODUCT_VER_MAJOR=1
 AFSPRODUCT_VER_MINOR=8
 !ENDIF
 !IF !DEFINED(AFSPRODUCT_VER_PATCH)
-AFSPRODUCT_VER_PATCH=1001
+AFSPRODUCT_VER_PATCH=1101
 !ENDIF
 !IF !DEFINED(AFSPRODUCT_VER_BUILD)
 AFSPRODUCT_VER_BUILD=0
diff --git a/src/config/NTMakefile.i386_nt40 b/src/config/NTMakefile.i386_nt40
index de3a7282b1..81e0968b93 100644
--- a/src/config/NTMakefile.i386_nt40
+++ b/src/config/NTMakefile.i386_nt40
@@ -88,7 +88,7 @@ AFSPRODUCT_VER_MAJOR=1
 AFSPRODUCT_VER_MINOR=8
 !ENDIF
 !IF !DEFINED(AFSPRODUCT_VER_PATCH)
-AFSPRODUCT_VER_PATCH=1001
+AFSPRODUCT_VER_PATCH=1101
 !ENDIF
 !IF !DEFINED(AFSPRODUCT_VER_BUILD)
 AFSPRODUCT_VER_BUILD=0
diff --git a/src/config/NTMakefile.i386_w2k b/src/config/NTMakefile.i386_w2k
index 24d8f1478a..c7232094b9 100644
--- a/src/config/NTMakefile.i386_w2k
+++ b/src/config/NTMakefile.i386_w2k
@@ -92,7 +92,7 @@ AFSPRODUCT_VER_MAJOR=1
 AFSPRODUCT_VER_MINOR=8
 !ENDIF
 !IF !DEFINED(AFSPRODUCT_VER_PATCH)
-AFSPRODUCT_VER_PATCH=1001
+AFSPRODUCT_VER_PATCH=1101
 !ENDIF
 !IF !DEFINED(AFSPRODUCT_VER_BUILD)
 AFSPRODUCT_VER_BUILD=0
diff --git a/src/config/afs_sysnames.h b/src/config/afs_sysnames.h
index 612d631006..196a5d9f2f 100644
--- a/src/config/afs_sysnames.h
+++ b/src/config/afs_sysnames.h
@@ -101,6 +101,8 @@
 #define SYS_NAME_ID_arm_darwin_210       548
 #define SYS_NAME_ID_amd64_darwin_220     549
 #define SYS_NAME_ID_arm_darwin_220       550
+#define SYS_NAME_ID_amd64_darwin_230     551
+#define SYS_NAME_ID_arm_darwin_230       552
 
 #define SYS_NAME_ID_next_mach20		 601
 #define SYS_NAME_ID_next_mach30		 602
diff --git a/src/config/param.darwin_230.h b/src/config/param.darwin_230.h
new file mode 100644
index 0000000000..000ebb0e28
--- /dev/null
+++ b/src/config/param.darwin_230.h
@@ -0,0 +1,203 @@
+#ifndef AFS_PARAM_H
+# define AFS_PARAM_H
+
+# ifndef UKERNEL
+/* This section for kernel libafs compiles only */
+
+#  define AFS_ENV                     1
+#  define AFS_64BIT_ENV               1	/* Defines afs_int32 as int, not long. */
+#  define AFS_64BIT_CLIENT            1
+#  define AFS_64BIT_IOPS_ENV          1
+#  define AFS_64BIT_SIZEOF            1 /* seriously? */
+
+#  include <afs/afs_sysnames.h>
+
+#  define AFS_DARWIN_ENV
+#  define AFS_DARWIN70_ENV
+#  define AFS_DARWIN80_ENV
+#  define AFS_DARWIN90_ENV
+#  define AFS_DARWIN100_ENV
+#  define AFS_DARWIN110_ENV
+#  define AFS_DARWIN120_ENV
+#  define AFS_DARWIN130_ENV
+#  define AFS_DARWIN140_ENV
+#  define AFS_DARWIN150_ENV
+#  define AFS_DARWIN160_ENV
+#  define AFS_DARWIN170_ENV
+#  define AFS_DARWIN180_ENV
+#  define AFS_DARWIN190_ENV
+#  define AFS_DARWIN200_ENV
+#  define AFS_DARWIN210_ENV
+#  define AFS_DARWIN220_ENV
+#  define AFS_DARWIN230_ENV
+#  undef  AFS_NONFSTRANS
+#  define AFS_NONFSTRANS
+#  define AFS_SYSCALL                 230
+#  define AFS_NAMEI_ENV               1
+#  define DARWIN_REFBASE              3
+#  define AFS_WARNUSER_MARINER_ENV    1
+#  define AFS_CACHE_VNODE_PATH
+#  define AFS_NEW_BKG                 1
+#  define NEED_IOCTL32
+
+/* File system entry (used if mount.h doesn't define MOUNT_AFS) */
+#  define AFS_MOUNT_AFS               "afs"
+
+#  define AFS_HAVE_FFS                1	/* Use system's ffs. */
+
+#  define AFS_GCPAGS                  0
+#  define RXK_UPCALL_ENV              1
+#  define RXK_TIMEDSLEEP_ENV          1
+#  define AFS_USERSPACE_IP_ADDR       1
+#  define AFS_SOCKPROXY_ENV           1
+
+#  ifdef KERNEL
+#   undef MACRO_BEGIN
+#   undef MACRO_END
+
+#   include <kern/macro_help.h>
+
+#   define AFS_GLOBAL_SUNLOCK         1
+#   define AFS_VFS34                  1	/* What is VFS34??? */
+
+#   define afsio_iov                  uio_iov
+#   define afsio_iovcnt               uio_iovcnt
+#   define afsio_offset               uio_offset
+#   define afsio_seg                  uio_segflg
+#   define afsio_resid                uio_resid
+
+#   define AFS_UIOSYS                 UIO_SYSSPACE
+#   define AFS_UIOUSER                UIO_USERSPACE
+#   define AFS_CLBYTES                CLBYTES
+#   define AFS_KALLOC(x)              _MALLOC(x, M_TEMP, M_WAITOK)
+#   define AFS_KFREE(x,y)             _FREE(x,M_TEMP)
+
+#   define v_count                    v_usecount
+#   define v_vfsp                     v_mount
+#   define vfs_bsize                  mnt_stat.f_bsize
+#   define vfs_fsid                   mnt_stat.f_fsid
+#   define va_nodeid                  va_fileid
+#   define vfs_vnodecovered           mnt_vnodecovered
+#   define direct                     dirent
+
+#   define BIND_8_COMPAT
+#  endif /* KERNEL */
+
+# else /* !defined(UKERNEL) */
+
+/* This section for user space compiles only */
+
+#  define AFS_ENV                     1
+#  define AFS_64BIT_ENV               1	/* Defines afs_int32 as int, not long. */
+#  define AFS_64BIT_CLIENT            1
+
+#  include <afs/afs_sysnames.h>
+
+#  define AFS_USERSPACE_ENV
+#  define AFS_USR_DARWIN_ENV
+#  define AFS_USR_DARWIN70_ENV
+#  define AFS_USR_DARWIN80_ENV
+#  define AFS_USR_DARWIN90_ENV
+#  define AFS_USR_DARWIN100_ENV
+#  define AFS_USR_DARWIN110_ENV
+#  define AFS_USR_DARWIN120_ENV
+#  define AFS_USR_DARWIN130_ENV
+#  define AFS_USR_DARWIN140_ENV
+#  define AFS_USR_DARWIN150_ENV
+#  define AFS_USR_DARWIN160_ENV
+#  define AFS_USR_DARWIN170_ENV
+#  define AFS_USR_DARWIN180_ENV
+#  define AFS_USR_DARWIN190_ENV
+#  define AFS_USR_DARWIN200_ENV
+#  define AFS_USR_DARWIN210_ENV
+#  define AFS_USR_DARWIN220_ENV
+#  define AFS_USR_DARWIN230_ENV
+
+#  undef  AFS_NONFSTRANS
+#  define AFS_NONFSTRANS
+
+#  define AFS_SYSCALL                 230
+#  define DARWIN_REFBASE              0
+#  define AFS_WARNUSER_MARINER_ENV    1
+
+/* File system entry (used if mount.h doesn't define MOUNT_AFS) */
+#  define AFS_MOUNT_AFS               "afs"
+
+#  define AFS_HAVE_FFS                1	/* Use system's ffs. */
+
+#  define AFS_UIOSYS                  UIO_SYSSPACE
+#  define AFS_UIOUSER                 UIO_USERSPACE
+
+#  define AFS_GCPAGS                  0	/* if nonzero, garbage collect PAGs */
+#  define RXK_LISTENER_ENV            1
+
+#  define AFS_VFS34                   1	/* What is VFS34??? */
+
+#  define afsio_iov                   uio_iov
+#  define afsio_iovcnt                uio_iovcnt
+#  define afsio_offset                uio_offset
+#  define afsio_seg                   uio_segflg
+#  define afsio_resid                 uio_resid
+
+#  define VATTR_NULL                  usr_vattr_null
+
+#  define AFS_DIRENT
+#  ifndef CMSERVERPREF
+#   define CMSERVERPREF
+#  endif
+
+#  define BIND_8_COMPAT
+# endif /* !defined(UKERNEL) */
+
+/* Machine / Operating system information */
+# if defined(__amd64__)
+
+#  define AFS_X86_ENV                 1
+#  define AFS_64BITUSERPOINTER_ENV    1
+
+#  define sys_x86_darwin_12           1
+#  define sys_x86_darwin_13           1
+#  define sys_x86_darwin_14           1
+#  define sys_x86_darwin_60           1
+#  define sys_x86_darwin_70           1
+#  define sys_x86_darwin_80           1
+#  define sys_x86_darwin_90           1
+#  define sys_x86_darwin_100          1
+#  define sys_amd64_darwin_100        1
+#  define sys_amd64_darwin_110        1
+#  define sys_amd64_darwin_120        1
+#  define sys_amd64_darwin_130        1
+#  define sys_amd64_darwin_140        1
+#  define sys_amd64_darwin_150        1
+#  define sys_amd64_darwin_160        1
+#  define sys_amd64_darwin_170        1
+#  define sys_amd64_darwin_180        1
+#  define sys_amd64_darwin_190        1
+#  define sys_amd64_darwin_200        1
+#  define sys_amd64_darwin_210        1
+#  define sys_amd64_darwin_220        1
+#  define sys_amd64_darwin_230        1
+
+#  define SYS_NAME                    "amd64_darwin_230"
+#  define SYS_NAME_ID                 SYS_NAME_ID_amd64_darwin_230
+#  define AFSLITTLE_ENDIAN            1
+
+# elif defined(__arm64__)
+
+#  define AFS_ARM_ENV                 1
+#  define AFS_ARM64_DARWIN_ENV        1
+
+#  define sys_arm_darwin_200          1
+#  define sys_arm_darwin_210          1
+#  define sys_arm_darwin_220          1
+#  define sys_arm_darwin_230          1
+
+#  define SYS_NAME                    "arm_darwin_230"
+#  define SYS_NAME_ID                 SYS_NAME_ID_arm_darwin_230
+#  define AFSLITTLE_ENDIAN            1
+
+# else
+# error Unsupported architecture
+# endif /* __amd64__ */
+
+#endif /* AFS_PARAM_H */
diff --git a/src/config/stds.h b/src/config/stds.h
index 0b28e4d6eb..8ae6834345 100644
--- a/src/config/stds.h
+++ b/src/config/stds.h
@@ -219,12 +219,10 @@ typedef struct afsUUID afsUUID;
 #ifdef AFS_NT40_ENV
 # define AFS_INT64_FMT "I64d"
 # define AFS_UINT64_FMT "I64u"
-# define AFS_PTR_FMT   "p"
 # define AFS_SIZET_FMT "Iu"
 #else
 # define AFS_INT64_FMT "lld"
 # define AFS_UINT64_FMT "llu"
-# define AFS_PTR_FMT   "p"
 # ifdef PRINTF_TAKES_Z_LEN
 #  define AFS_SIZET_FMT "zu"
 # else
diff --git a/src/crypto/hcrypto/kernel/config.h b/src/crypto/hcrypto/kernel/config.h
index 9623fa9e7b..ea0f60b644 100644
--- a/src/crypto/hcrypto/kernel/config.h
+++ b/src/crypto/hcrypto/kernel/config.h
@@ -91,7 +91,13 @@ extern int osi_readRandom(void *, afs_size_t);
 static_inline pid_t getpid(void) {return 1;};
 #endif
 static_inline int open(const char *path, int flags, ...) {return -1;}
-static_inline void abort(void) {osi_Panic("hckernel aborting\n");}
+
+#ifdef abort
+# undef abort
+#endif
+#define abort _afscrypto_abort
+static_inline void _afscrypto_abort(void) {osi_Panic("hckernel aborting\n");}
+
 static_inline void rk_cloexec(int fd) {}
 static_inline ssize_t read(int d, void *buf, size_t nbytes) {return -1;}
 static_inline int close(int d) {return -1;}
diff --git a/src/crypto/rfc3961/Makefile.in b/src/crypto/rfc3961/Makefile.in
index 6fce447ad9..e389048716 100644
--- a/src/crypto/rfc3961/Makefile.in
+++ b/src/crypto/rfc3961/Makefile.in
@@ -48,6 +48,7 @@ ${TOP_LIBDIR}/libafsrfc3961.a: libafsrfc3961.a
 
 CFLAGS_crypto-arcfour.lo=@CFLAGS_NOERROR@
 CFLAGS_crypto-des-common.lo=@CFLAGS_NOERROR@
+CFLAGS_crypto.lo=@CFLAGS_USE_AFTER_FREE_GCCBUG@
 
 context.lo: context.c ${HEADERS}
 copy.lo: copy.c ${HEADERS}
diff --git a/src/dir/buffer.c b/src/dir/buffer.c
index 1a8da8f196..d522d92cd9 100644
--- a/src/dir/buffer.c
+++ b/src/dir/buffer.c
@@ -83,12 +83,12 @@ struct buffer *newslot(dir_file_t dir, afs_int32 apage,
  *
  * extern void FidZero(DirHandle *);
  * extern int  FidEq(DirHandle *a, DirHandle *b);
- * extern int  ReallyRead(DirHandle *a, int block, char *data);
+ * extern int  ReallyRead(DirHandle *a, int block, char *data, int *physerr);
  */
 
 extern void FidZero(dir_file_t);
 extern int FidEq(dir_file_t, dir_file_t);
-extern int ReallyRead(dir_file_t, int block, char *data);
+extern int ReallyRead(dir_file_t, int block, char *data, int *physerr);
 extern int ReallyWrite(dir_file_t, int block, char *data);
 extern void FidZap(dir_file_t);
 extern int  FidVolEq(dir_file_t, afs_int32 vid);
@@ -148,17 +148,26 @@ DInit(int abuffers)
 /**
  * read a page out of a directory object.
  *
- * @param[in] fid   directory object fid
- * @param[in] page  page in hash table to be read
+ * @param[in]	fid	directory object fid
+ * @param[in]   page	page in hash table to be read
+ * @param[out]	entry	buffer to be filled w/ page contents
+ * @param[out]	physerr	(optional) pointer to return possible errno
  *
- * @return pointer to requested page in directory cache
- *    @retval NULL read failed
+ * @retval 0	success
+ * @retval EIO	logical directory error or physical IO error;
+ *		if *physerr was supplied, it will be set to 0
+ *		for logical errors, or the errno for physical
+ *		errors.
  */
 int
-DRead(dir_file_t fid, int page, struct DirBuffer *entry)
+DReadWithErrno(dir_file_t fid, int page, struct DirBuffer *entry, int *physerr)
 {
     /* Read a page from the disk. */
     struct buffer *tb, *tb2, **bufhead;
+    int code;
+
+    if (physerr != NULL)
+	*physerr = 0;
 
     memset(entry, 0, sizeof(struct DirBuffer));
 
@@ -228,11 +237,12 @@ DRead(dir_file_t fid, int page, struct DirBuffer *entry)
     ObtainWriteLock(&tb->lock);
     tb->lockers++;
     ReleaseWriteLock(&afs_bufferLock);
-    if (ReallyRead(bufferDir(tb), tb->page, tb->data)) {
+    code = ReallyRead(bufferDir(tb), tb->page, tb->data, physerr);
+    if (code != 0) {
 	tb->lockers--;
 	FidZap(bufferDir(tb));	/* disaster */
 	ReleaseWriteLock(&tb->lock);
-	return EIO;
+	return code;
     }
     /* Note that findslot sets the page field in the buffer equal to
      * what it is searching for.
@@ -243,6 +253,22 @@ DRead(dir_file_t fid, int page, struct DirBuffer *entry)
     return 0;
 }
 
+/**
+ * read a page out of a directory object.
+ *
+ * @param[in]	fid   directory object fid
+ * @param[in]	page  page in hash table to be read
+ * @param[out]	entry buffer to be filled w/ page contents
+ *
+ * @retval 0	success
+ * @retval EIO	logical directory error or physical IO error
+ */
+int
+DRead(dir_file_t fid, int page, struct DirBuffer *entry)
+{
+    return DReadWithErrno(fid, page, entry, NULL);
+}
+
 
 static int
 FixupBucket(struct buffer *ap)
diff --git a/src/dir/dir.c b/src/dir/dir.c
index bc5bb046d0..364117fceb 100644
--- a/src/dir/dir.c
+++ b/src/dir/dir.c
@@ -72,8 +72,6 @@ extern int DNew(struct dcache *adc, int page, struct DirBuffer *);
 # include "dir.h"
 #endif /* KERNEL */
 
-afs_int32 DErrno;
-
 /* Local static prototypes */
 static int FindBlobs(dir_file_t, int);
 static void AddPage(dir_file_t, int);
@@ -99,7 +97,7 @@ afs_dir_Create(dir_file_t dir, char *entry, void *voidfid)
     int blobs, firstelt;
     int i;
     struct DirBuffer entrybuf, prevbuf, headerbuf;
-    struct DirEntry *ep;
+    struct DirEntryFlex *ep;
     struct DirHeader *dhp;
     int code;
     size_t rlen;
@@ -127,7 +125,7 @@ afs_dir_Create(dir_file_t dir, char *entry, void *voidfid)
     /* First, we fill in the directory entry. */
     if (afs_dir_GetBlob(dir, firstelt, &entrybuf) != 0)
 	return EIO;
-    ep = (struct DirEntry *)entrybuf.data;
+    ep = entrybuf.data;
 
     ep->flag = FFIRST;
     ep->fid.vnode = htonl(vfid[1]);
@@ -518,11 +516,14 @@ afs_dir_IsEmpty(dir_file_t dir)
 /* Return a pointer to an entry, given its number. Also return the maximum
  * size of the entry, which is determined by its position within the directory
  * page.
+ *
+ * If physerr is supplied by caller, it will be set to:
+ *      0       for logical errors
+ *      errno   for physical errors
  */
-
 static int
 GetBlobWithLimit(dir_file_t dir, afs_int32 blobno,
-	         struct DirBuffer *buffer, afs_size_t *maxlen)
+		struct DirBuffer *buffer, afs_size_t *maxlen, int *physerr)
 {
     afs_size_t pos;
     int code;
@@ -530,7 +531,7 @@ GetBlobWithLimit(dir_file_t dir, afs_int32 blobno,
     *maxlen = 0;
     memset(buffer, 0, sizeof(struct DirBuffer));
 
-    code = DRead(dir, blobno >> LEPP, buffer);
+    code = DReadWithErrno(dir, blobno >> LEPP, buffer, physerr);
     if (code)
 	return code;
 
@@ -543,12 +544,26 @@ GetBlobWithLimit(dir_file_t dir, afs_int32 blobno,
     return 0;
 }
 
+/*
+ * Given an entry's number, return a pointer to that entry.
+ * If physerr is supplied by caller, it will be set to:
+ *      0       for logical errors
+ *      errno   for physical errors
+ */
+int
+afs_dir_GetBlobWithErrno(dir_file_t dir, afs_int32 blobno, struct DirBuffer *buffer,
+			int *physerr)
+{
+    afs_size_t maxlen = 0;
+    return GetBlobWithLimit(dir, blobno, buffer, &maxlen, physerr);
+}
+
 /* Given an entries number, return a pointer to that entry */
 int
 afs_dir_GetBlob(dir_file_t dir, afs_int32 blobno, struct DirBuffer *buffer)
 {
     afs_size_t maxlen = 0;
-    return GetBlobWithLimit(dir, blobno, buffer, &maxlen);
+    return GetBlobWithLimit(dir, blobno, buffer, &maxlen, NULL);
 }
 
 /* Return an entry, having verified that the name held within the entry
@@ -566,7 +581,7 @@ afs_dir_GetVerifiedBlob(dir_file_t file, afs_int32 blobno,
     int code;
     char *cp;
 
-    code = GetBlobWithLimit(file, blobno, &buffer, &maxlen);
+    code = GetBlobWithLimit(file, blobno, &buffer, &maxlen, NULL);
     if (code)
 	return code;
 
diff --git a/src/dir/dir.h b/src/dir/dir.h
index f5c8eef422..25c450eb9f 100644
--- a/src/dir/dir.h
+++ b/src/dir/dir.h
@@ -51,6 +51,32 @@ struct DirHeader {
     unsigned short hashTable[NHASHENT];
 };
 
+/*
+ * This struct is just a copy of DirEntry, but with name defined as a flexible
+ * array if possible.
+ *
+ * Using this helps us convince safety-minded string functions (e.g.
+ * _FORTIFY_SOURCE) that an OpenAFS directory entry name really does fit
+ * in the allotted space, and thus avoid undefined behavior.
+ */
+struct DirEntryFlex {
+    char flag;
+    char length;                /* currently unused */
+    unsigned short next;
+    struct MKFid fid;
+#ifdef HAVE_FLEXIBLE_ARRAY
+    char name[];
+#else
+    char name[16];
+#endif
+};
+
+/*
+ * This struct was the original format for directory entries in very early
+ * versions of AFS.  But now it just represents the minimum possible on-disk
+ * representation of a directory entry.  The 16-character limit was relieved by
+ * the introduction of extension struct DirXEntry in AFS-2.
+*/
 struct DirEntry {
     /* A directory entry */
     char flag;
@@ -104,6 +130,8 @@ extern int afs_dir_EnumerateDir(dir_file_t dir,
 extern int afs_dir_IsEmpty(dir_file_t dir);
 extern int afs_dir_GetBlob(dir_file_t dir, afs_int32 blobno,
 			   struct DirBuffer *);
+extern int afs_dir_GetBlobWithErrno(dir_file_t dir, afs_int32 blobno,
+			   struct DirBuffer *, int *physerr);
 extern int afs_dir_GetVerifiedBlob(dir_file_t dir, afs_int32 blobno,
 				   struct DirBuffer *);
 extern int afs_dir_DirHash(char *string);
@@ -119,6 +147,7 @@ extern int afs_dir_ChangeFid(dir_file_t dir, char *entry,
 
 extern void DInit(int abuffers);
 extern int DRead(dir_file_t fid, int page, struct DirBuffer *);
+extern int DReadWithErrno(dir_file_t fid, int page, struct DirBuffer *, int *physerr);
 extern int DFlush(void);
 extern int DFlushVolume(afs_int32);
 extern int DNew(dir_file_t fid, int page, struct DirBuffer *);
diff --git a/src/dir/salvage.c b/src/dir/salvage.c
index a20a67dad3..092c407b44 100644
--- a/src/dir/salvage.c
+++ b/src/dir/salvage.c
@@ -19,20 +19,16 @@
 #include <roken.h>
 
 #include "dir.h"
+#include <afs/afsint.h>	    /* for AFSNAMEMAX */
+
 /* Defined in vol/vol-salvage.c */
 extern void Log(const char *format, ...)
     AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
 
-#define printf	Log		/* To make it work with volume salvager */
-
 /* This routine is called with one parameter, the id (the same thing that is
  * passed to physio or the buffer package) of a directory to check.  It
  * returns 1 if the directory looks good, and 0 otherwise. */
 
-#define MAXENAME 256
-
-extern afs_int32 DErrno;
-
 /* figure out how many pages in use in a directory, given ptr to its (locked)
  * header */
 static int
@@ -82,29 +78,30 @@ DirOK(void *file)
     afs_int32 entcount, maxents;
     unsigned short ne;
     int code;
+    int physerr;
 
     eaSize = BIGMAXPAGES * EPP / 8;
 
     /* Read the directory header */
-    code = DRead(file,0, &headerbuf);
+    code = DReadWithErrno(file, 0, &headerbuf, &physerr);
     if (code) {
-	/* if DErrno is 0, then we know that the read worked, but was short,
+	/* if physerr is 0, then we know that the read worked, but was short,
 	 * and the damage is permanent.  Otherwise, we got an I/O or programming
 	 * error.  Claim the dir is OK, but log something.
 	 */
-	if (DErrno != 0) {
-	    printf("Could not read first page in directory (%d)\n", DErrno);
+	if (physerr != 0) {
+	    Log("Could not read first page in directory (%d)\n", physerr);
 	    Die("dirok1");
 	    return 1;
 	}
-	printf("First page in directory does not exist.\n");
+	Log("First page in directory does not exist.\n");
 	return 0;
     }
     dhp = (struct DirHeader *)headerbuf.data;
 
     /* Check magic number for first page */
     if (dhp->header.tag != htons(1234)) {
-	printf("Bad first pageheader magic number.\n");
+	Log("Bad first pageheader magic number.\n");
 	DRelease(&headerbuf, 0);
 	return 0;
     }
@@ -125,13 +122,13 @@ DirOK(void *file)
 		/* First page's dirheader uses 13 entries and at least
 		 * two must exist for "." and ".."
 		 */
-		printf("The dir header alloc map for page %d is bad.\n", i);
+		Log("The dir header alloc map for page %d is bad.\n", i);
 		DRelease(&headerbuf, 0);
 		return 0;
 	    }
 	} else {
 	    if ((j < 0) || (j > EPP)) {
-		printf("The dir header alloc map for page %d is bad.\n", i);
+		Log("The dir header alloc map for page %d is bad.\n", i);
 		DRelease(&headerbuf, 0);
 		return 0;
 	    }
@@ -140,9 +137,7 @@ DirOK(void *file)
 	/* Check if contiguous */
 	if (k) {		/* last page found */
 	    if (j != EPP) {	/* remaining entries must be EPP */
-		printf
-		    ("A partially-full page occurs in slot %d, after the dir end.\n",
-		     i);
+		Log("A partially-full page occurs in slot %d, after the dir end.\n", i);
 		DRelease(&headerbuf, 0);
 		return 0;
 	    }
@@ -159,8 +154,7 @@ DirOK(void *file)
      ** not exists for pages between MAXPAGES and BIGMAXPAGES */
     usedPages = ComputeUsedPages(dhp);
     if (usedPages < up) {
-	printf
-	    ("Count of used directory pages does not match count in directory header\n");
+	Log("Count of used directory pages does not match count in directory header\n");
 	DRelease(&headerbuf, 0);
 	return 0;
     }
@@ -171,23 +165,23 @@ DirOK(void *file)
      */
     for (i = 0; i < usedPages; i++) {
 	/* Read the page header */
-	code = DRead(file, i, &pagebuf);
+	code = DReadWithErrno(file, i, &pagebuf, &physerr);
 	if (code) {
 	    DRelease(&headerbuf, 0);
-	    if (DErrno != 0) {
+	    if (physerr != 0) {
 		/* couldn't read page, but not because it wasn't there permanently */
-		printf("Failed to read dir page %d (errno %d)\n", i, DErrno);
+		Log("Failed to read dir page %d (errno %d)\n", i, physerr);
 		Die("dirok2");
 		return 1;
 	    }
-	    printf("Directory shorter than alloMap indicates (page %d)\n", i);
+	    Log("Directory shorter than alloMap indicates (page %d)\n", i);
 	    return 0;
 	}
 	pp = (struct PageHeader *)pagebuf.data;
 
 	/* check the tag field */
 	if (pp->tag != htons(1234)) {
-	    printf("Directory page %d has a bad magic number.\n", i);
+	    Log("Directory page %d has a bad magic number.\n", i);
 	    DRelease(&pagebuf, 0);
 	    DRelease(&headerbuf, 0);
 	    return 0;
@@ -220,9 +214,8 @@ DirOK(void *file)
 
 	/* Now check that the count of free entries matches the count in the alloMap */
 	if ((i < MAXPAGES) && ((count & 0xff) != (dhp->alloMap[i] & 0xff))) {
-	    printf
-		("Header alloMap count doesn't match count in freebitmap for page %d.\n",
-		 i);
+	    Log("Header alloMap count doesn't match count in freebitmap for page %d.\n",
+		i);
 	    DRelease(&pagebuf, 0);
 	    DRelease(&headerbuf, 0);
 	    return 0;
@@ -255,25 +248,23 @@ DirOK(void *file)
 	for (entry = ntohs(dhp->hashTable[i]); entry; entry = ne) {
 	    /* Verify that the entry is within range */
 	    if (entry < 0 || entry >= maxents) {
-		printf("Out-of-range hash id %d in chain %d.\n", entry, i);
+		Log("Out-of-range hash id %d in chain %d.\n", entry, i);
 		DRelease(&headerbuf, 0);
 		return 0;
 	    }
 
 	    /* Read the directory entry */
-	    DErrno = 0;
-	    code = afs_dir_GetBlob(file, entry, &entrybuf);
+	    code = afs_dir_GetBlobWithErrno(file, entry, &entrybuf, &physerr);
 	    if (code) {
-		if (DErrno != 0) {
+		if (physerr != 0) {
 		    /* something went wrong reading the page, but it wasn't
 		     * really something wrong with the dir that we can fix.
 		     */
-		    printf("Could not get dir blob %d (errno %d)\n", entry,
-			   DErrno);
+		    Log("Could not get dir blob %d (errno %d)\n", entry, physerr);
 		    DRelease(&headerbuf, 0);
 		    Die("dirok3");
 		}
-		printf("Invalid hash id %d in chain %d.\n", entry, i);
+		Log("Invalid hash id %d in chain %d.\n", entry, i);
 		DRelease(&headerbuf, 0);
 		return 0;
 	    }
@@ -283,7 +274,7 @@ DirOK(void *file)
 
 	    /* There can't be more than maxents entries */
 	    if (++entcount >= maxents) {
-		printf("Directory's hash chain %d is circular.\n", i);
+		Log("Directory's hash chain %d is circular.\n", i);
 		DRelease(&entrybuf, 0);
 		DRelease(&headerbuf, 0);
 		return 0;
@@ -291,8 +282,7 @@ DirOK(void *file)
 
 	    /* A null name is no good */
 	    if (ep->name[0] == '\000') {
-		printf("Dir entry %"AFS_PTR_FMT
-		       " in chain %d has bogus (null) name.\n", ep, i);
+		Log("Dir entry %p in chain %d has bogus (null) name.\n", ep, i);
 		DRelease(&entrybuf, 0);
 		DRelease(&headerbuf, 0);
 		return 0;
@@ -300,8 +290,7 @@ DirOK(void *file)
 
 	    /* The entry flag better be FFIRST */
 	    if (ep->flag != FFIRST) {
-		printf("Dir entry %"AFS_PTR_FMT
-		       " in chain %d has bogus flag field.\n", ep, i);
+		Log("Dir entry %p in chain %d has bogus flag field.\n", ep, i);
 		DRelease(&entrybuf, 0);
 		DRelease(&headerbuf, 0);
 		return 0;
@@ -309,9 +298,8 @@ DirOK(void *file)
 
 	    /* Check the size of the name */
 	    j = strlen(ep->name);
-	    if (j >= MAXENAME) {	/* MAXENAME counts the null */
-		printf("Dir entry %"AFS_PTR_FMT
-		       " in chain %d has too-long name.\n", ep, i);
+	    if (j > AFSNAMEMAX) {	    /* does not include the nul */
+		Log("Dir entry %p in chain %d has too-long name.\n", ep, i);
 		DRelease(&entrybuf, 0);
 		DRelease(&headerbuf, 0);
 		return 0;
@@ -327,9 +315,8 @@ DirOK(void *file)
 
 	    /* Hash the name and make sure it is in the correct name hash */
 	    if ((j = afs_dir_DirHash(ep->name)) != i) {
-		printf("Dir entry %"AFS_PTR_FMT
-		       " should be in hash bucket %d but IS in %d.\n",
-		       ep, j, i);
+		Log("Dir entry %p should be in hash bucket %d but IS in %d.\n",
+		    ep, j, i);
 		DRelease(&entrybuf, 0);
 		DRelease(&headerbuf, 0);
 		return 0;
@@ -340,10 +327,8 @@ DirOK(void *file)
 		if (strcmp(ep->name, ".") == 0) {
 		    havedot = 1;
 		} else {
-		    printf
-			("Dir entry %"AFS_PTR_FMT
-			 ", index 13 has name '%s' should be '.'\n",
-			 ep, ep->name);
+		    Log("Dir entry %p, index 13 has name '%s' should be '.'\n",
+			ep, ep->name);
 		    DRelease(&entrybuf, 0);
 		    DRelease(&headerbuf, 0);
 		    return 0;
@@ -355,10 +340,8 @@ DirOK(void *file)
 		if (strcmp(ep->name, "..") == 0) {
 		    havedotdot = 1;
 		} else {
-		    printf
-			("Dir entry %"AFS_PTR_FMT
-			 ", index 14 has name '%s' should be '..'\n",
-			 ep, ep->name);
+		    Log("Dir entry %p, index 14 has name '%s' should be '..'\n",
+			ep, ep->name);
 		    DRelease(&entrybuf, 0);
 		    DRelease(&headerbuf, 0);
 		    return 0;
@@ -373,8 +356,7 @@ DirOK(void *file)
 
     /* Verify that we found '.' and '..' in the correct place */
     if (!havedot || !havedotdot) {
-	printf
-	    ("Directory entry '.' or '..' does not exist or is in the wrong index.\n");
+	Log("Directory entry '.' or '..' does not exist or is in the wrong index.\n");
 	DRelease(&headerbuf, 0);
 	return 0;
     }
@@ -384,17 +366,17 @@ DirOK(void *file)
      * Note that if this matches, alloMap has already been checked against it.
      */
     for (i = 0; i < usedPages; i++) {
-	code = DRead(file, i, &pagebuf);
+	code = DReadWithErrno(file, i, &pagebuf, &physerr);
 	if (code) {
-	    printf
-		("Failed on second attempt to read dir page %d (errno %d)\n",
-		 i, DErrno);
+	    Log("Failed on second attempt to read dir page %d (errno %d)\n",
+		i, physerr);
 	    DRelease(&headerbuf, 0);
-	    /* if DErrno is 0, then the dir is really bad, and we return dir *not* OK.
-	     * otherwise, we want to return true (1), meaning the dir isn't known
-	     * to be bad (we can't tell, since I/Os are failing.
+	    /* if physerr is 0, then the dir is really bad, and we return dir
+	     * *not* OK.  Otherwise, we Die instead of returning true (1),
+	     * becauase the dir isn't known to be bad (we can't tell, since
+	     * I/Os are failing).
 	     */
-	    if (DErrno != 0)
+	    if (physerr != 0)
 		Die("dirok4");
 	    else
 		return 0;	/* dir is really shorter */
@@ -404,9 +386,8 @@ DirOK(void *file)
 	count = i * (EPP / 8);
 	for (j = 0; j < EPP / 8; j++) {
 	    if (eaMap[count + j] != pp->freebitmap[j]) {
-		printf
-		    ("Entry freebitmap error, page %d, map offset %d, %x should be %x.\n",
-		     i, j, pp->freebitmap[j], eaMap[count + j]);
+		Log("Entry freebitmap error, page %d, map offset %d, %x should be %x.\n",
+		    i, j, pp->freebitmap[j], eaMap[count + j]);
 		DRelease(&pagebuf, 0);
 		DRelease(&headerbuf, 0);
 		return 0;
@@ -438,16 +419,17 @@ int
 DirSalvage(void *fromFile, void *toFile, afs_int32 vn, afs_int32 vu,
 	   afs_int32 pvn, afs_int32 pvu)
 {
-    /* First do a MakeDir on the target. */
     afs_int32 dot[3], dotdot[3], lfid[3], code, usedPages;
-    char tname[256];
+    char tname[AFSNAMEMAX+1];
     int i;
     char *tp;
     struct DirBuffer headerbuf, entrybuf;
     struct DirHeader *dhp;
     struct DirEntry *ep;
     int entry;
+    int physerr;
 
+    /* First do a MakeDir on the target. */
     memset(dot, 0, sizeof(dot));
     memset(dotdot, 0, sizeof(dotdot));
     dot[1] = vn;
@@ -455,19 +437,21 @@ DirSalvage(void *fromFile, void *toFile, afs_int32 vn, afs_int32 vu,
     dotdot[1] = pvn;
     dotdot[2] = pvu;
 
-    afs_dir_MakeDir(toFile, dot, dotdot);	/* Returns no error code. */
+    code = afs_dir_MakeDir(toFile, dot, dotdot);
+    if (code) {
+	Log("Failed to create target directory\n");
+	return code;
+    }
 
-    /* Find out how many pages are valid, using stupid heuristic since DRead
-     * never returns null.
-     */
-    code = DRead(fromFile, 0, &headerbuf);
+    /* Find out how many pages are valid. */
+    code = DReadWithErrno(fromFile, 0, &headerbuf, &physerr);
     if (code) {
-	printf("Failed to read first page of fromDir!\n");
-	/* if DErrno != 0, then our call failed and we should let our
+	Log("Failed to read first page of fromDir!\n");
+	/* if physerr != 0, then our call failed and we should let our
 	 * caller know that there's something wrong with the new dir.  If not,
 	 * then we return here anyway, with an empty, but at least good, directory.
 	 */
-	return DErrno;
+	return physerr;
     }
     dhp = (struct DirHeader *)headerbuf.data;
 
@@ -480,29 +464,25 @@ DirSalvage(void *fromFile, void *toFile, afs_int32 vn, afs_int32 vu,
 	    if (!entry)
 		break;
 	    if (entry < 0 || entry >= usedPages * EPP) {
-		printf
-		    ("Warning: bogus hash table entry encountered, ignoring.\n");
+		Log("Warning: bogus hash table entry encountered, ignoring.\n");
 		break;
 	    }
 
-	    DErrno = 0;
-	    code = afs_dir_GetBlob(fromFile, entry, &entrybuf);
+	    code = afs_dir_GetBlobWithErrno(fromFile, entry, &entrybuf, &physerr);
 	    if (code) {
-		if (DErrno) {
-		    printf
-			("can't continue down hash chain (entry %d, errno %d)\n",
-			 entry, DErrno);
+		if (physerr != 0) {
+		    Log("can't continue down hash chain (entry %d, errno %d)\n",
+			entry, physerr);
 		    DRelease(&headerbuf, 0);
-		    return DErrno;
+		    return physerr;
 		}
-		printf
-		    ("Warning: bogus hash chain encountered, switching to next.\n");
+		Log("Warning: bogus hash chain encountered, switching to next.\n");
 		break;
 	    }
 	    ep = (struct DirEntry *)entrybuf.data;
 
-	    strncpy(tname, ep->name, MAXENAME);
-	    tname[MAXENAME - 1] = '\000';	/* just in case */
+	    strncpy(tname, ep->name, sizeof(tname));
+	    tname[sizeof(tname) - 1] = '\0';	/* just in case */
 	    tp = tname;
 
 	    entry = ntohs(ep->next);
@@ -512,9 +492,8 @@ DirSalvage(void *fromFile, void *toFile, afs_int32 vn, afs_int32 vu,
 		lfid[2] = ntohl(ep->fid.vunique);
 		code = afs_dir_Create(toFile, tname, lfid);
 		if (code) {
-		    printf
-			("Create of %s returned code %d, skipping to next hash chain.\n",
-			 tname, code);
+		    Log("Create of %s returned code %d, skipping to next hash chain.\n",
+			tname, code);
 		    DRelease(&entrybuf, 0);
 		    break;
 		}
diff --git a/src/dir/test/dtest.c b/src/dir/test/dtest.c
index d2d3d38556..0dd166036a 100644
--- a/src/dir/test/dtest.c
+++ b/src/dir/test/dtest.c
@@ -186,18 +186,46 @@ CreateDir(char *name, dirhandle *dir)
     }
 }
 
+/*
+ * Read the specified page from a directory object
+ *
+ * \parm[in] dir	handle to the directory object
+ * \parm[in] block	requested page from the directory object
+ * \parm[out] data	buffer for the returned page
+ * \parm[out] physerr	(optional) pointer to errno if physical error
+ *
+ * \retval 0   success
+ * \retval EIO physical or logical error;
+ *             if physerr is supplied by caller, it will be set to:
+ *                 0       for logical errors
+ *                 errno   for physical errors
+ */
 int
-ReallyRead(dirhandle *dir, int block, char *data)
+ReallyRead(dirhandle *dir, int block, char *data, int *physerr)
 {
-    int code;
-    if (lseek(dir->fd, block * PAGESIZE, 0) == -1)
-	return errno;
+    int code = 0;
+
+    if (lseek(dir->fd, block * PAGESIZE, 0) == -1) {
+	code = EIO;
+	goto done;
+    }
     code = read(dir->fd, data, PAGESIZE);
-    if (code < 0)
-	return errno;
-    if (code != PAGESIZE)
-	return EIO;
-    return 0;
+    if (code < 0) {
+	code = EIO;
+	goto done;
+    }
+    if (code != PAGESIZE) {
+	errno = 0;	/* logical error - short read */
+	code = EIO;
+	goto done;
+    }
+
+    errno = 0;
+
+ done:
+    if (physerr != NULL)
+	*physerr = errno;
+    return code;
 }
 
 int
diff --git a/src/libafs/afs.arm_darwin_230.plist.in b/src/libafs/afs.arm_darwin_230.plist.in
new file mode 100644
index 0000000000..a1385718c5
--- /dev/null
+++ b/src/libafs/afs.arm_darwin_230.plist.in
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>afs</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.openafs.filesystems.afs</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>8.0</string>
+	<key>CFBundleName</key>
+	<string>afs</string>
+	<key>CFBundlePackageType</key>
+	<string>KEXT</string>
+	<key>CFBundleShortVersionString</key>
+	<string>@MACOS_VERSION@</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>@MACOS_VERSION@</string>
+	<key>OSBundleLibraries</key>
+	<dict>
+		<key>com.apple.kpi.bsd</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.mach</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.libkern</key>
+		<string>8.0</string>
+	</dict>
+</dict>
+</plist>
diff --git a/src/libafs/afs.x86_darwin_230.plist.in b/src/libafs/afs.x86_darwin_230.plist.in
new file mode 100644
index 0000000000..a1385718c5
--- /dev/null
+++ b/src/libafs/afs.x86_darwin_230.plist.in
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>afs</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.openafs.filesystems.afs</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>8.0</string>
+	<key>CFBundleName</key>
+	<string>afs</string>
+	<key>CFBundlePackageType</key>
+	<string>KEXT</string>
+	<key>CFBundleShortVersionString</key>
+	<string>@MACOS_VERSION@</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>@MACOS_VERSION@</string>
+	<key>OSBundleLibraries</key>
+	<dict>
+		<key>com.apple.kpi.bsd</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.mach</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.libkern</key>
+		<string>8.0</string>
+	</dict>
+</dict>
+</plist>
diff --git a/src/libuafs/Makefile.common.in b/src/libuafs/Makefile.common.in
index 1f79e69b71..9416050271 100644
--- a/src/libuafs/Makefile.common.in
+++ b/src/libuafs/Makefile.common.in
@@ -216,7 +216,7 @@ ${TOP_LIBDIR}/perl/AFS/ukernel.pm: setup_perllib PERLUAFS/ukernel.pm
 LIBUAFS_BUILD_PERL: ${TOP_LIBDIR}/perl/ukernel.so ${TOP_LIBDIR}/perl/AFS/ukernel.pm
 
 linktest: libuafs.a
-	$(CC) $(CFLAGS) $(TEST_CFLAGS) $(TEST_LDFLAGS) \
+	$(CC) $(COMMON_CFLAGS) $(TEST_CFLAGS) $(TEST_LDFLAGS) \
 		$(LDFLAGS_roken) $(LDFLAGS_hcrypto) -o linktest \
 		${srcdir}/linktest.c $(MODULE_INCLUDE) -DUKERNEL \
 		libuafs.a ${TOP_LIBDIR}/libcmd.a \
diff --git a/src/lwp/lwp.c b/src/lwp/lwp.c
index f5e98c8eb1..d554fa7b0c 100644
--- a/src/lwp/lwp.c
+++ b/src/lwp/lwp.c
@@ -920,7 +920,7 @@ Dispatcher(void)
 #endif
 	printf("stackcheck = %u: stack = %u \n", lwp_cpptr->stackcheck,
 	       *(int *)lwp_cpptr->stack);
-	printf("topstack = 0x%" AFS_PTR_FMT ": stackptr = 0x%" AFS_PTR_FMT ": stacksize = 0x%x\n",
+	printf("topstack = %p: stackptr = %p: stacksize = 0x%x\n",
 	       (void *)(uintptr_t)lwp_cpptr->context.topstack,
 	       (void *)(uintptr_t)lwp_cpptr->stack,
 	       lwp_cpptr->stacksize);
diff --git a/src/packaging/MacOS/ReadMe.rtf.23 b/src/packaging/MacOS/ReadMe.rtf.23
new file mode 100644
index 0000000000..b8d18b896a
--- /dev/null
+++ b/src/packaging/MacOS/ReadMe.rtf.23
@@ -0,0 +1,7 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\margl1440\margr1440\vieww9000\viewh9000\viewkind0
+\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
+
+\f0\fs24 \cf0 This release of OpenAFS is targeted at MacOS 14.X (Sonoma) and is not recommended for use with any other version.}
diff --git a/src/packaging/MacOS/pkgbuild.sh.in b/src/packaging/MacOS/pkgbuild.sh.in
index 225cbf520b..edaa7212d6 100644
--- a/src/packaging/MacOS/pkgbuild.sh.in
+++ b/src/packaging/MacOS/pkgbuild.sh.in
@@ -177,6 +177,10 @@ elif [ x"$majorvers" = x22 ]; then
     RELNAME="Ventura"
     THISREL=18
     OSVER=13
+elif [ x"$majorvers" = x23 ]; then
+    RELNAME="Sonoma"
+    THISREL=19
+    OSVER=14
 
 
 elif [ x"$majorvers" = x ] ; then
diff --git a/src/packaging/RedHat/makesrpm.pl b/src/packaging/RedHat/makesrpm.pl
index 7744d5dc24..7d6e1a96f9 100755
--- a/src/packaging/RedHat/makesrpm.pl
+++ b/src/packaging/RedHat/makesrpm.pl
@@ -3,24 +3,39 @@
 use strict;
 use warnings;
 
+use Getopt::Long;
+use Pod::Usage;
 use IO::Dir;
 use IO::File;
 use File::Path;
 use File::Copy;
 use File::Temp;
+use File::Basename;
+use File::Spec;
 
 # Build an SRPM for OpenAFS, given a src and doc tarball, release notes,
 # and ChangeLog.
 
+my $help = 0;
+my $man = 0;
+my $dir = ".";
+
+GetOptions(
+    "help|?" => \$help,
+    "man" => \$man,
+    "dir=s" => \$dir,
+) or pod2usage(-exitval => 1, -verbose => 1);
+pod2usage(-exitval => 0, -verbose => 1) if $help;
+pod2usage(-exitval => 0, -verbose => 2, -noperldoc => 1) if $man;
+
 my $srcball = shift;
 my $docball = shift;
 my $relnotes = shift;
 my $changelog = shift;
 my $cellservdb = shift;
 
-if (!$srcball && !$docball) {
-  printf "Usage:  makesrpm <src.tar.bz2> <doc.tar.bz2> [<relnotes> [<changelog> [<cellservdb>]]]\n";
-  exit(1);
+if (!defined($srcball) || !defined($docball)) {
+    pod2usage(-exitval => 1, -verbose => 1);
 }
 
 if (! -f $srcball) {
@@ -77,15 +92,12 @@ if ($afsversion=~m/(.*)-([0-9]+)-(g[a-f0-9]+)$/) {
     $linuxrel.=".$2.$3";
 }
 
-print "Linux release is $linuxrel\n";
-print "Linux version is $linuxver\n";
+# Avoid illegal characters in RPM package version and release strings.
+$linuxver =~ s/-/_/g;
+$linuxrel =~ s/-/_/g;
 
-# Figure out a major, minor and release so that we know which version we're
-# building, and therefore what the srpm is going to be called
-$linuxver=~/([0-9]+)\.([0-9]+)\.([0-9]+)/;
-my $major = $1;
-my $minor = $2;
-my $patchlevel = $3;
+print "Package version is $linuxver\n";
+print "Package release is $linuxrel\n";
 
 # Build the RPM root
 
@@ -165,18 +177,49 @@ system("rpmbuild -bs --nodeps --define \"dist %undefined\" ".
   or die "rpmbuild failed : $!\n";
 
 # Copy it out to somewhere useful
-if (!defined($major) || $major > 1 || ($major == 1 && $minor >= 6)) {
-  File::Copy::copy("$tmpdir/rpmdir/SRPMS/openafs-$linuxver-$linuxrel.src.rpm",
-	           "openafs-$linuxver-$linuxrel.src.rpm")
-    or die "Unable to copy output RPM : $!\n";
+my @srpms = glob("$tmpdir/rpmdir/SRPMS/*.src.rpm");
+if (scalar(@srpms) != 1) {
+    die "Generated SRPM file not found.\n";
+}
+my $filename = File::Basename::fileparse($srpms[0]);
+my $srpm = File::Spec->rel2abs("$dir/$filename");
+File::Path::make_path($dir);
+File::Copy::copy($srpms[0], $srpm)
+    or die "Failed to copy '$srpms[0]' to '$srpm': $!\n";
+print "SRPM is $srpm\n";
 
-  print "SRPM is openafs-$linuxver-$linuxrel.src.rpm\n";
-} else {
-  File::Copy::copy("$tmpdir/rpmdir/SRPMS/openafs-$linuxver-1.$linuxrel.src.rpm",
-	           "openafs-$linuxver-1.$linuxrel.src.rpm")
-    or die "Unable to copy output RPM : $!\n";
+__END__
 
-  print "SRPM is openafs-$linuxver-1.$linuxrel.src.rpm\n";
-}
+=head1 NAME
+
+makesrpm.pl - Build the SRPM for OpenAFS from source distibution files
+
+=head1 SYNOPSIS
+
+makesrpm.pl [options] <src.tar.bz2> <doc.tar.bz2> [<relnotes> [<changelog> [<cellservdb>]]]
+
+=head1 DESCRIPTION
+
+Build the SRPM for OpenAFS from source distibution files. Generate empty RELNOTES
+and ChangeLog files if not provided. Download the CellServDB file from
+grand.central.org if one is not provided.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--help>
+
+Print help message and exit.
+
+=item B<--man>
+
+Print full man page and exit.
+
+=item B<--dir> I<path>
+
+Place the generated SRPM file in I<path> instead of the current directory.
 
+=back
 
+=cut
diff --git a/src/packaging/RedHat/openafs.spec.in b/src/packaging/RedHat/openafs.spec.in
index 7f03a0c35b..6481358a8c 100644
--- a/src/packaging/RedHat/openafs.spec.in
+++ b/src/packaging/RedHat/openafs.spec.in
@@ -115,7 +115,7 @@ Source1: http://www.openafs.org/dl/openafs/%{afsvers}/openafs-%{afsvers}-doc.tar
 Source10: http://www.openafs.org/dl/openafs/%{afsvers}/RELNOTES-%{afsvers}
 Source11: http://www.openafs.org/dl/openafs/%{afsvers}/ChangeLog
 
-Source20: https://www.central.org/dl/cellservdb/CellServDB.2022-05-09
+Source20: https://www.central.org/dl/cellservdb/CellServDB.2023-10-31
 
 Source996: openafs-kvers-is.sh
 Source997: openafs-buildfedora.pl
diff --git a/src/ptserver/pts.c b/src/ptserver/pts.c
index 3c5fc6d35f..c97307bdf1 100644
--- a/src/ptserver/pts.c
+++ b/src/ptserver/pts.c
@@ -45,10 +45,28 @@ struct sourcestack {
 
 struct authstate {
     int sec;
-    const char *confdir;
+    int initialized;
     char cell[MAXCELLCHARS];
 };
 
+/*
+ * Constants for add_std_args() global parameters. Start at offset 16, to try
+ * to avoid conflicting with any subcommand-specific parameters. If any
+ * subcommand uses more than 16 params, these constants will probably need to
+ * change.
+ */
+enum {
+    OPT_cell	    = 16,
+    OPT_noauth	    = 17,
+    OPT_test	    = 18,
+    OPT_force	    = 19,
+    OPT_localauth   = 20,
+    OPT_auth	    = 21,
+    OPT_encrypt	    = 22,
+    OPT_config	    = 23,
+    OPT_rxgk	    = 24,
+};
+
 static int CleanUp(struct cmd_syndesc *as, void *arock);
 
 static int
@@ -167,6 +185,7 @@ GetGlobals(struct cmd_syndesc *as, void *arock)
     afs_int32 sec;
     int changed = 0;
     const char* confdir;
+    const char* retry_confdir;
 
     whoami = as->a0name;
 
@@ -178,27 +197,27 @@ GetGlobals(struct cmd_syndesc *as, void *arock)
     }
     sec = state->sec;
 
-    if (state->confdir == NULL) {
+    if (state->initialized == 0) {
 	changed = 1;
     }
 
-    if (as->parms[16].items) {
+    if (as->parms[OPT_cell].items) {
 	changed = 1;
-	cell = as->parms[16].items->data;
+	cell = as->parms[OPT_cell].items->data;
     }
-    if (as->parms[17].items) { /* -noauth */
+    if (as->parms[OPT_noauth].items) {
 	changed = 1;
 	sec = 0;
     }
-    if (as->parms[20].items) { /* -localauth */
+    if (as->parms[OPT_localauth].items) {
 	changed = 1;
 	sec = 2;
     }
-    if (as->parms[21].items) { /* -auth */
+    if (as->parms[OPT_auth].items) {
 	changed = 1;
 	sec = 1;
     }
-    if (as->parms[22].items    /* -encrypt */
+    if (as->parms[OPT_encrypt].items
 #ifdef AFS_NT40_ENV
         || win32_enableCrypt()
 #endif /* AFS_NT40_ENV */
@@ -206,24 +225,34 @@ GetGlobals(struct cmd_syndesc *as, void *arock)
 	changed = 1;
 	sec = 3;
     }
-    if (as->parms[18].items || as->parms[20].items) { /* -test, -localauth */
+    if (as->parms[OPT_test].items || as->parms[OPT_localauth].items) {
 	changed = 1;
 	confdir = AFSDIR_SERVER_ETC_DIRPATH;
+	retry_confdir = NULL;
     } else {
-	if (sec == 2)
+	if (sec == 2) {
 	    confdir = AFSDIR_SERVER_ETC_DIRPATH;
-	else
+	    retry_confdir = NULL;
+	} else {
 	    confdir = AFSDIR_CLIENT_ETC_DIRPATH;
+	    retry_confdir = AFSDIR_SERVER_ETC_DIRPATH;
+	}
     }
 
-    if (as->parms[23].items) { /* -config */
+    if (as->parms[OPT_config].items) { /* -config */
 	changed = 1;
-	confdir = as->parms[23].items->data;
+	confdir = as->parms[OPT_config].items->data;
+	retry_confdir = NULL;
     }
 
     if (changed) {
 	CleanUp(as, arock);
 	code = pr_Initialize(sec, confdir, cell);
+	if (code != 0 && retry_confdir != NULL) {
+	    fprintf(stderr, "pts: Retrying initialization with directory %s\n",
+		    retry_confdir);
+	    code = pr_Initialize(sec, retry_confdir, cell);
+	}
     } else {
 	code = 0;
     }
@@ -232,12 +261,12 @@ GetGlobals(struct cmd_syndesc *as, void *arock)
 	return code;
     }
     state->sec = sec;
-    state->confdir = confdir;
+    state->initialized = 1;
     if (cell && cell != state->cell)
         strncpy(state->cell, cell, MAXCELLCHARS-1);
 
     force = 0;
-    if (as->parms[19].items)
+    if (as->parms[OPT_force].items)
 	force = 1;
 
     return code;
@@ -989,19 +1018,22 @@ add_std_args(struct cmd_syndesc *ts)
 	test_help = strdup("use server config file");
     }
 
-    cmd_Seek(ts, 16);
-    cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
-    cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "run unauthenticated");
-    cmd_AddParm(ts, "-test", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE, test_help);
-    cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
-		"Continue oper despite reasonable errors");
-    cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL,
-		"use local authentication");
-    cmd_AddParm(ts, "-auth", CMD_FLAG, CMD_OPTIONAL,
-		"use user's authentication (default)");
-    cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL,
-		"encrypt commands");
-    cmd_AddParm(ts, "-config", CMD_SINGLE, CMD_OPTIONAL, "config location");
+    cmd_AddParmAtOffset(ts, OPT_cell, "-cell", CMD_SINGLE, CMD_OPTIONAL,
+			"cell name");
+    cmd_AddParmAtOffset(ts, OPT_noauth, "-noauth", CMD_FLAG, CMD_OPTIONAL,
+			"run unauthenticated");
+    cmd_AddParmAtOffset(ts, OPT_test, "-test", CMD_FLAG,
+			CMD_OPTIONAL | CMD_HIDE, test_help);
+    cmd_AddParmAtOffset(ts, OPT_force, "-force", CMD_FLAG, CMD_OPTIONAL,
+			"Continue oper despite reasonable errors");
+    cmd_AddParmAtOffset(ts, OPT_localauth, "-localauth", CMD_FLAG,
+			CMD_OPTIONAL, "use local authentication");
+    cmd_AddParmAtOffset(ts, OPT_auth, "-auth", CMD_FLAG, CMD_OPTIONAL,
+			"use user's authentication (default)");
+    cmd_AddParmAtOffset(ts, OPT_encrypt, "-encrypt", CMD_FLAG, CMD_OPTIONAL,
+			"encrypt commands");
+    cmd_AddParmAtOffset(ts, OPT_config, "-config", CMD_SINGLE, CMD_OPTIONAL,
+			"config location");
     free(test_help);
 }
 
diff --git a/src/roken/Makefile.in b/src/roken/Makefile.in
index 8a61b19a66..e6daa6f5f5 100644
--- a/src/roken/Makefile.in
+++ b/src/roken/Makefile.in
@@ -75,7 +75,7 @@ err.h: ${UPSTREAM}/err.hin
 	$(INSTALL_DATA) $? $@
 
 roken.h: $(UPSTREAM)/roken.h.in roken-post.h
-	cat $(UPSTREAM)/roken.h.in roken-post.h >$@
+	cat $(UPSTREAM)/roken.h.in $(srcdir)/roken-post.h >$@
 
 # Here we have explicit rules for all the libtool objects we might need to
 # build.  The implicit rules don't work since the sources are in a different
diff --git a/src/rx/UKERNEL/rx_knet.c b/src/rx/UKERNEL/rx_knet.c
index 2f7c6c5450..66f6f01695 100644
--- a/src/rx/UKERNEL/rx_knet.c
+++ b/src/rx/UKERNEL/rx_knet.c
@@ -155,7 +155,6 @@ rx_ServerProc(void *unused)
      * number of threads handling incoming calls */
     threadID = rxi_availProcs++;
 
-    AFS_GUNLOCK();
     while (1) {
 	sock = OSI_NULLSOCKET;
 	rxi_ServerProc(threadID, newcall, &sock);
@@ -168,7 +167,6 @@ rx_ServerProc(void *unused)
 	/* assert(threadID != -1); */
 	/* assert(newcall != NULL); */
     }
-    AFS_GLOCK();
     return NULL;
 }
 
diff --git a/src/rx/rx.c b/src/rx/rx.c
index 3e8954e358..aaec609075 100644
--- a/src/rx/rx.c
+++ b/src/rx/rx.c
@@ -1417,7 +1417,7 @@ static void
 rxi_WakeUpTransmitQueue(struct rx_call *call)
 {
     if (call->tqWaiters || (call->flags & RX_CALL_TQ_WAIT)) {
-	dpf(("call %"AFS_PTR_FMT" has %d waiters and flags %d\n",
+	dpf(("call %p has %d waiters and flags %d\n",
 	     call, call->tqWaiters, call->flags));
 #ifdef RX_ENABLE_LOCKS
 	MUTEX_ASSERT(&call->lock);
@@ -1447,7 +1447,7 @@ rx_NewCall(struct rx_connection *conn)
     SPLVAR;
 
     clock_NewTime();
-    dpf(("rx_NewCall(conn %"AFS_PTR_FMT")\n", conn));
+    dpf(("rx_NewCall(conn %p)\n", conn));
 
     NETPRI;
     clock_GetTime(&queueTime);
@@ -1661,7 +1661,7 @@ rx_NewCall(struct rx_connection *conn)
     MUTEX_EXIT(&call->lock);
     USERPRI;
 
-    dpf(("rx_NewCall(call %"AFS_PTR_FMT")\n", call));
+    dpf(("rx_NewCall(call %p)\n", call));
     return call;
 }
 
@@ -2165,7 +2165,7 @@ rx_GetCall(int tno, struct rx_service *cur_service, osi_socket * socketp)
 #endif
 
 	rxi_calltrace(RX_CALL_START, call);
-	dpf(("rx_GetCall(port=%d, service=%d) ==> call %"AFS_PTR_FMT"\n",
+	dpf(("rx_GetCall(port=%d, service=%d) ==> call %p\n",
 	     call->conn->service->servicePort, call->conn->service->serviceId,
 	     call));
 
@@ -2373,7 +2373,7 @@ rx_EndCall(struct rx_call *call, afs_int32 rc)
     afs_int32 error;
     SPLVAR;
 
-    dpf(("rx_EndCall(call %"AFS_PTR_FMT" rc %d error %d abortCode %d)\n",
+    dpf(("rx_EndCall(call %p rc %d error %d abortCode %d)\n",
           call, rc, call->error, call->abortCode));
 
     NETPRI;
@@ -2639,7 +2639,7 @@ rxi_NewCall(struct rx_connection *conn, int channel)
     struct opr_queue *cursor;
 #endif
 
-    dpf(("rxi_NewCall(conn %"AFS_PTR_FMT", channel %d)\n", conn, channel));
+    dpf(("rxi_NewCall(conn %p, channel %d)\n", conn, channel));
 
     /* Grab an existing call structure, or allocate a new one.
      * Existing call structures are assumed to have been left reset by
@@ -3270,9 +3270,17 @@ rxi_ReceiveServerCall(osi_socket socket, struct rx_packet *np,
     struct rx_call *call;
 
     channel = np->header.cid & RX_CHANNELMASK;
+
     MUTEX_ENTER(&conn->conn_call_lock);
-    call = conn->call[channel];
 
+    if (np->header.callNumber < conn->callNumber[channel]) {
+	MUTEX_EXIT(&conn->conn_call_lock);
+	if (rx_stats_active)
+	    rx_atomic_inc(&rx_stats.spuriousPacketsRead);
+	return NULL;
+    }
+
+    call = conn->call[channel];
     if (!call) {
 	if (np->header.type != RX_PACKET_TYPE_DATA) {
 	    /*
@@ -3328,13 +3336,6 @@ rxi_ReceiveServerCall(osi_socket socket, struct rx_packet *np,
 	return call;
     }
 
-    if (np->header.callNumber < conn->callNumber[channel]) {
-	MUTEX_EXIT(&conn->conn_call_lock);
-	if (rx_stats_active)
-	    rx_atomic_inc(&rx_stats.spuriousPacketsRead);
-	return NULL;
-    }
-
     MUTEX_ENTER(&call->lock);
     MUTEX_EXIT(&conn->conn_call_lock);
 
@@ -3428,7 +3429,7 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket,
  * this is the first time the packet has been seen */
     packetType = (np->header.type > 0 && np->header.type < RX_N_PACKET_TYPES)
 	? rx_packetTypes[np->header.type - 1] : "*UNKNOWN*";
-    dpf(("R %d %s: %x.%d.%d.%d.%d.%d.%d flags %d, packet %"AFS_PTR_FMT"\n",
+    dpf(("R %d %s: %x.%d.%d.%d.%d.%d.%d flags %d, packet %p\n",
 	 np->header.serial, packetType, ntohl(host), ntohs(port), np->header.serviceId,
 	 np->header.epoch, np->header.cid, np->header.callNumber,
 	 np->header.seq, np->header.flags, np));
@@ -3901,7 +3902,7 @@ rxi_ReceiveDataPacket(struct rx_call *call,
         if (rx_stats_active)
             rx_atomic_inc(&rx_stats.noPacketBuffersOnRead);
 	rxi_calltrace(RX_TRACE_DROP, call);
-	dpf(("packet %"AFS_PTR_FMT" dropped on receipt - quota problems\n", np));
+	dpf(("packet %p dropped on receipt - quota problems\n", np));
         /* We used to clear the receive queue here, in an attempt to free
          * packets. However this is unsafe if the queue has received a
          * soft ACK for the final packet */
@@ -3955,7 +3956,7 @@ rxi_ReceiveDataPacket(struct rx_call *call,
 		&& opr_queue_First(&call->rq, struct rx_packet, entry)->header.seq == seq) {
                 if (rx_stats_active)
                     rx_atomic_inc(&rx_stats.dupPacketsRead);
-		dpf(("packet %"AFS_PTR_FMT" dropped on receipt - duplicate\n", np));
+		dpf(("packet %p dropped on receipt - duplicate\n", np));
 		rxi_CancelDelayedAckEvent(call);
 		np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE, istack);
 		ackNeeded = 0;
@@ -5196,7 +5197,7 @@ rxi_ClearReceiveQueue(struct rx_call *call)
 #ifdef RXDEBUG_PACKET
         call->rqc -= count;
         if ( call->rqc != 0 )
-            dpf(("rxi_ClearReceiveQueue call %"AFS_PTR_FMT" rqc %u != 0\n", call, call->rqc));
+	  dpf(("rxi_ClearReceiveQueue call %p rqc %u != 0\n", call, call->rqc));
 #endif
 	call->flags &= ~(RX_CALL_RECEIVE_DONE | RX_CALL_HAVE_LAST);
     }
@@ -5313,7 +5314,7 @@ rxi_ConnectionError(struct rx_connection *conn,
     if (error) {
 	int i;
 
-	dpf(("rxi_ConnectionError conn %"AFS_PTR_FMT" error %d\n", conn, error));
+	dpf(("rxi_ConnectionError conn %p error %d\n", conn, error));
 
 	MUTEX_ENTER(&conn->conn_data_lock);
 	if (rxevent_Cancel(&conn->challengeEvent))
@@ -5358,7 +5359,7 @@ void
 rxi_CallError(struct rx_call *call, afs_int32 error)
 {
     MUTEX_ASSERT(&call->lock);
-    dpf(("rxi_CallError call %"AFS_PTR_FMT" error %d call->error %d\n", call, error, call->error));
+    dpf(("rxi_CallError call %p error %d call->error %d\n", call, error, call->error));
     if (call->error)
 	error = call->error;
 
@@ -5387,7 +5388,7 @@ rxi_ResetCall(struct rx_call *call, int newcall)
     struct rx_packet *packet;
 
     MUTEX_ASSERT(&call->lock);
-    dpf(("rxi_ResetCall(call %"AFS_PTR_FMT", newcall %d)\n", call, newcall));
+    dpf(("rxi_ResetCall(call %p, newcall %d)\n", call, newcall));
 
     /* Notify anyone who is waiting for asynchronous packet arrival */
     if (call->arrivalProc) {
@@ -5448,7 +5449,7 @@ rxi_ResetCall(struct rx_call *call, int newcall)
 
     rxi_ClearTransmitQueue(call, 1);
     if (call->tqWaiters || (flags & RX_CALL_TQ_WAIT)) {
-        dpf(("rcall %"AFS_PTR_FMT" has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
+	dpf(("rcall %p has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
     }
     call->flags = 0;
 
@@ -6241,7 +6242,7 @@ rxi_Start(struct rx_call *call, int istack)
 					     nXmitPackets, istack);
 			    goto restart;
 			}
-                        dpf(("call %d xmit packet %"AFS_PTR_FMT"\n",
+		       dpf(("call %d xmit packet %p\n",
                               *(call->callNumber), p));
 			call->xmitList[nXmitPackets++] = p;
 		    }
@@ -7010,7 +7011,7 @@ rxi_ComputeRoundTripTime(struct rx_packet *p,
 	return;			/* somebody set the clock back, don't count this time. */
 
     clock_Sub(&thisRtt, sentp);
-    dpf(("rxi_ComputeRoundTripTime(call=%d packet=%"AFS_PTR_FMT" rttp=%d.%06d sec)\n",
+    dpf(("rxi_ComputeRoundTripTime(call=%d packet=%p rttp=%d.%06d sec)\n",
           p->header.callNumber, p, thisRtt.sec, thisRtt.usec));
 
     if (clock_IsZero(&thisRtt)) {
@@ -7109,8 +7110,10 @@ rxi_ComputeRoundTripTime(struct rx_packet *p,
     peer->rtt_dev = call->rtt_dev;
     peer->rtt = call->rtt;
 
-    dpf(("rxi_ComputeRoundTripTime(call=%d packet=%"AFS_PTR_FMT" rtt=%d ms, srtt=%d ms, rtt_dev=%d ms, timeout=%d.%06d sec)\n",
-          p->header.callNumber, p, MSEC(&thisRtt), call->rtt >> 3, call->rtt_dev >> 2, (call->rto.sec), (call->rto.usec)));
+    dpf(("rxi_ComputeRoundTripTime(call=%d packet=%p rtt=%d ms, srtt=%d ms, "
+	 "rtt_dev=%d ms, timeout=%d.%06d sec)\n",
+	 p->header.callNumber, p, MSEC(&thisRtt), call->rtt >> 3,
+	 call->rtt_dev >> 2, (call->rto.sec), (call->rto.usec)));
 }
 
 
diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c
index 4d6407bc28..2898da1899 100644
--- a/src/rx/rx_packet.c
+++ b/src/rx/rx_packet.c
@@ -871,7 +871,7 @@ rx_CheckPackets(void)
 static void
 rxi_FreePacketNoLock(struct rx_packet *p)
 {
-    dpf(("Free %"AFS_PTR_FMT"\n", p));
+    dpf(("Free %p\n", p));
 
     RX_FPQ_MARK_FREE(p);
     rx_nFreePackets++;
@@ -884,7 +884,7 @@ static void
 rxi_FreePacketTSFPQ(struct rx_packet *p, int flush_global)
 {
     struct rx_ts_info_t * rx_ts_info;
-    dpf(("Free %"AFS_PTR_FMT"\n", p));
+    dpf(("Free %p\n", p));
 
     RX_TS_INFO_GET(rx_ts_info);
     RX_TS_FPQ_CHECKIN(rx_ts_info,p);
@@ -1183,7 +1183,7 @@ rxi_AllocPacketNoLock(int class)
 
     RX_TS_FPQ_CHECKOUT(rx_ts_info,p);
 
-    dpf(("Alloc %"AFS_PTR_FMT", class %d\n", p, class));
+    dpf(("Alloc %p, class %d\n", p, class));
 
 
     /* have to do this here because rx_FlushWrite fiddles with the iovs in
@@ -1241,7 +1241,7 @@ rxi_AllocPacketNoLock(int class)
     opr_queue_Remove(&p->entry);
     RX_FPQ_MARK_USED(p);
 
-    dpf(("Alloc %"AFS_PTR_FMT", class %d\n", p, class));
+    dpf(("Alloc %p, class %d\n", p, class));
 
 
     /* have to do this here because rx_FlushWrite fiddles with the iovs in
@@ -1279,7 +1279,7 @@ rxi_AllocPacketTSFPQ(int class, int pull_global)
 
     RX_TS_FPQ_CHECKOUT(rx_ts_info,p);
 
-    dpf(("Alloc %"AFS_PTR_FMT", class %d\n", p, class));
+    dpf(("Alloc %p, class %d\n", p, class));
 
     /* have to do this here because rx_FlushWrite fiddles with the iovs in
      * order to truncate outbound packets.  In the near future, may need
@@ -2352,7 +2352,7 @@ rxi_SendPacket(struct rx_call *call, struct rx_connection *conn,
 #endif
 #ifdef RXDEBUG
     }
-    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" len %d\n",
+    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %p len %d\n",
           deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host),
           ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber,
           p->header.seq, p->header.flags, p, p->length));
@@ -2545,7 +2545,7 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
 
     osi_Assert(p != NULL);
 
-    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" len %d\n",
+    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %p len %d\n",
           deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host),
           ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber,
           p->header.seq, p->header.flags, p, p->length));
diff --git a/src/rxkad/ticket5.c b/src/rxkad/ticket5.c
index 3fd508208e..114517d020 100644
--- a/src/rxkad/ticket5.c
+++ b/src/rxkad/ticket5.c
@@ -672,6 +672,7 @@ rxkad_derive_des_key(const void *in, size_t insize,
 	HMAC_Update(&mctx, Lbuf, 4);
 	mdsize = sizeof(tmp);
 	HMAC_Final(&mctx, tmp, &mdsize);
+	HMAC_CTX_cleanup(&mctx);
 	memcpy(ktmp, tmp, 8);
 	DES_set_odd_parity(&ktmp);
 	if (!DES_is_weak_key(&ktmp)) {
diff --git a/src/util/pthread_glock.c b/src/util/pthread_glock.c
index 93f9ee68cd..542428e237 100644
--- a/src/util/pthread_glock.c
+++ b/src/util/pthread_glock.c
@@ -74,6 +74,7 @@ pthread_recursive_mutex_unlock(pthread_recursive_mutex_t * mut)
 	mut->times_inside--;
 	if (mut->times_inside == 0) {
 	    mut->locked = 0;
+	    mut->owner = 0;
 	    rc = pthread_mutex_unlock(&mut->mut);
 	}
     } else {
diff --git a/src/viced/host.c b/src/viced/host.c
index a832187898..f2ce790ba3 100644
--- a/src/viced/host.c
+++ b/src/viced/host.c
@@ -829,7 +829,7 @@ h_TossStuff_r(struct host *host)
 	char hoststr[16];
 	if (wasdeleted) {
 	    /* someone locked the host while HOSTDELETED was set; that is bad */
-	    ViceLog(0, ("Warning:  h_TossStuff_r failed; Host %" AFS_PTR_FMT
+	    ViceLog(0, ("Warning:  h_TossStuff_r failed; Host %p"
 			" (%s:%d flags 0x%x) was locked.\n",
 			host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port),
 			(unsigned)host->z.hostFlags));
@@ -846,7 +846,7 @@ h_TossStuff_r(struct host *host)
 	char hoststr[16];
 	if (wasdeleted) {
 	    /* someone grabbed a ref while HOSTDELETED was set; that is bad */
-	    ViceLog(0, ("Warning:  h_TossStuff_r failed; Host %" AFS_PTR_FMT
+	    ViceLog(0, ("Warning:  h_TossStuff_r failed; Host %p"
 			" (%s:%d flags 0x%x) was held.\n",
 			host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port),
 			(unsigned)host->z.hostFlags));
@@ -1132,7 +1132,7 @@ h_AddHostToUuidHashTable_r(struct afsUUID *uuid, struct host *host)
 		afsUUID_to_string(&chain->hostPtr->z.interface->uuid, uuid1,
 				  127);
 		afsUUID_to_string(uuid, uuid2, 127);
-		ViceLog(125, ("h_AddHostToUuidHashTable_r: host %" AFS_PTR_FMT " (uuid %s) exists as %s:%d (uuid %s)\n",
+		ViceLog(125, ("h_AddHostToUuidHashTable_r: host %p (uuid %s) exists as %s:%d (uuid %s)\n",
 			      host, uuid1,
 			      afs_inet_ntoa_r(chain->hostPtr->z.host, hoststr),
 			      ntohs(chain->hostPtr->z.port), uuid2));
@@ -1179,7 +1179,7 @@ h_DeleteHostFromUuidHashTable_r(struct host *host)
          opr_Assert(uth->hostPtr);
 	 if (uth->hostPtr == host) {
 	     ViceLog(125,
-		     ("h_DeleteHostFromUuidHashTable_r: host %" AFS_PTR_FMT " (uuid %s %s:%d)\n",
+		     ("h_DeleteHostFromUuidHashTable_r: host %p (uuid %s %s:%d)\n",
 		      host, uuid1, afs_inet_ntoa_r(host->z.host, hoststr),
 		      ntohs(host->z.port)));
 	     *uhp = uth->next;
@@ -1188,7 +1188,7 @@ h_DeleteHostFromUuidHashTable_r(struct host *host)
 	 }
      }
      ViceLog(125,
-	     ("h_DeleteHostFromUuidHashTable_r: host %" AFS_PTR_FMT " (uuid %s %s:%d) not found\n",
+	     ("h_DeleteHostFromUuidHashTable_r: host %p (uuid %s %s:%d) not found\n",
 	      host, uuid1, afs_inet_ntoa_r(host->z.host, hoststr),
 	      ntohs(host->z.port)));
      return 0;
@@ -1210,7 +1210,7 @@ invalidateInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port)
     opr_Assert(host);
     opr_Assert(host->z.interface);
 
-    ViceLog(125, ("invalidateInterfaceAddr : host %" AFS_PTR_FMT " (%s:%d) addr %s:%d\n",
+    ViceLog(125, ("invalidateInterfaceAddr : host %p (%s:%d) addr %s:%d\n",
 		  host, afs_inet_ntoa_r(host->z.host, hoststr),
 		  ntohs(host->z.port), afs_inet_ntoa_r(addr, hoststr2),
 		  ntohs(port)));
@@ -1255,7 +1255,7 @@ removeAddress_r(struct host *host, afs_uint32 addr, afs_uint16 port)
     if (!host->z.interface || host->z.interface->numberOfInterfaces == 1) {
 	if (host->z.host == addr && host->z.port == port) {
 	    ViceLog(25,
-		    ("Removing only address for host %" AFS_PTR_FMT " (%s:%d), deleting host.\n",
+		    ("Removing only address for host %p (%s:%d), deleting host.\n",
 		     host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port)));
 	    host->z.hostFlags |= HOSTDELETED;
             /*
@@ -1267,7 +1267,7 @@ removeAddress_r(struct host *host, afs_uint32 addr, afs_uint16 port)
              */
         } else {
 	    ViceLog(0,
-		    ("Removing address that does not belong to host %" AFS_PTR_FMT " (%s:%d).\n",
+		    ("Removing address that does not belong to host %p (%s:%d).\n",
 		     host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port)));
         }
     } else {
@@ -1277,7 +1277,7 @@ removeAddress_r(struct host *host, afs_uint32 addr, afs_uint16 port)
 	    for (i=0; i < host->z.interface->numberOfInterfaces; i++) {
 		if (host->z.interface->interface[i].valid) {
 		    ViceLog(25,
-			     ("Removed address for host %" AFS_PTR_FMT " (%s:%d), new primary interface %s:%d.\n",
+			     ("Removed address for host %p (%s:%d), new primary interface %s:%d.\n",
 			       host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port),
 			       afs_inet_ntoa_r(host->z.interface->interface[i].addr, hoststr2),
 			       ntohs(host->z.interface->interface[i].port)));
@@ -1290,7 +1290,7 @@ removeAddress_r(struct host *host, afs_uint32 addr, afs_uint16 port)
 
 	    if (i == host->z.interface->numberOfInterfaces) {
                 ViceLog(25,
-                         ("Removed only address for host %" AFS_PTR_FMT " (%s:%d), no valid alternate interfaces, deleting host.\n",
+			 ("Removed only address for host %p (%s:%d), no valid alternate interfaces, deleting host.\n",
 			   host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port)));
 		host->z.hostFlags |= HOSTDELETED;
                 /* addr/port was removed from the hash table */
@@ -1332,7 +1332,7 @@ createHostAddrHashChain_r(int index, afs_uint32 addr, afs_uint16 port, struct ho
     chain->addr = addr;
     chain->port = port;
     hostAddrHashTable[index] = chain;
-    ViceLog(125, ("h_AddHostToAddrHashTable_r: host %" AFS_PTR_FMT " added as %s:%d\n",
+    ViceLog(125, ("h_AddHostToAddrHashTable_r: host %p added as %s:%d\n",
 		  host, afs_inet_ntoa_r(addr, hoststr), ntohs(port)));
 }
 
@@ -1357,8 +1357,8 @@ reconcileHosts_r(afs_uint32 addr, afs_uint16 port, struct host *newHost,
     char hoststr[16];
 
     ViceLog(125,
-	    ("reconcileHosts_r: addr %s:%d newHost %" AFS_PTR_FMT " oldHost %"
-	     AFS_PTR_FMT "\n", afs_inet_ntoa_r(addr, hoststr), ntohs(port),
+	    ("reconcileHosts_r: addr %s:%d newHost %p oldHost %p\n",
+	     afs_inet_ntoa_r(addr, hoststr), ntohs(port),
 	     newHost, oldHost));
 
     opr_Assert(oldHost != newHost);
@@ -1481,7 +1481,7 @@ h_AddHostToAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host)
 	if (chain->addr == addr && chain->port == port) {
 	    if (chain->hostPtr == host) {
 	        ViceLog(125,
-	                ("h_AddHostToAddrHashTable_r: host %" AFS_PTR_FMT " (%s:%d) already hashed\n",
+			("h_AddHostToAddrHashTable_r: host %p (%s:%d) already hashed\n",
 	                  host, afs_inet_ntoa_r(chain->addr, hoststr),
 	                  ntohs(chain->port)));
 	        return;
@@ -1523,7 +1523,7 @@ addInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port)
 	if (host->z.interface->interface[i].addr == addr &&
 	     host->z.interface->interface[i].port == port) {
 	    ViceLog(125,
-		    ("addInterfaceAddr : found host %" AFS_PTR_FMT " (%s:%d) adding %s:%d%s\n",
+		    ("addInterfaceAddr : found host %p (%s:%d) adding %s:%d%s\n",
 		     host, afs_inet_ntoa_r(host->z.host, hoststr),
 		     ntohs(host->z.port), afs_inet_ntoa_r(addr, hoststr2),
 		     ntohs(port), host->z.interface->interface[i].valid ? "" :
@@ -1537,7 +1537,7 @@ addInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port)
         }
     }
 
-    ViceLog(125, ("addInterfaceAddr : host %" AFS_PTR_FMT " (%s:%d) adding %s:%d\n",
+    ViceLog(125, ("addInterfaceAddr : host %p (%s:%d) adding %s:%d\n",
 		  host, afs_inet_ntoa_r(host->z.host, hoststr),
 		  ntohs(host->z.port), afs_inet_ntoa_r(addr, hoststr2),
 		  ntohs(port)));
@@ -1580,7 +1580,7 @@ removeInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port)
     opr_Assert(host);
     opr_Assert(host->z.interface);
 
-    ViceLog(125, ("removeInterfaceAddr : host %" AFS_PTR_FMT " (%s:%d) addr %s:%d\n",
+    ViceLog(125, ("removeInterfaceAddr : host %p (%s:%d) addr %s:%d\n",
 		  host, afs_inet_ntoa_r(host->z.host, hoststr),
 		  ntohs(host->z.port), afs_inet_ntoa_r(addr, hoststr2),
 		  ntohs(port)));
@@ -1888,7 +1888,7 @@ h_GetHost_r(struct rx_connection *tcon)
              * waited for the lock. */
 	    h_Unlock_r(host);
 	    ViceLog(125,
-		    ("Host %" AFS_PTR_FMT " (%s:%d) starting h_Lookup again\n",
+		    ("Host %p (%s:%d) starting h_Lookup again\n",
 		     host, afs_inet_ntoa_r(host->z.host, hoststr),
 		     ntohs(host->z.port)));
 	    h_Release_r(host);
@@ -1970,7 +1970,7 @@ h_GetHost_r(struct rx_connection *tcon)
 		 * that we maintain some extra callback state information */
 		if (host->z.interface) {
 		    ViceLog(0,
-			    ("Host %" AFS_PTR_FMT " (%s:%d) used to support WhoAreYou, deleting.\n",
+			    ("Host %p (%s:%d) used to support WhoAreYou, deleting.\n",
 			     host,
 			     afs_inet_ntoa_r(host->z.host, hoststr),
 			     ntohs(host->z.port)));
@@ -2017,7 +2017,7 @@ h_GetHost_r(struct rx_connection *tcon)
 			removeAddress_r(host, haddr, hport);
 		} else {
 		    ViceLog(25,
-			    ("Uuid doesn't match host %" AFS_PTR_FMT " (%s:%d).\n",
+			    ("Uuid doesn't match host %p (%s:%d).\n",
 			     host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port)));
 
 		    removeAddress_r(host, host->z.host, host->z.port);
@@ -2054,7 +2054,7 @@ h_GetHost_r(struct rx_connection *tcon)
                      * callback connection, and destroy the old one.
                      */
                     struct rx_connection *rxconn;
-                    ViceLog(0,("CB: ProbeUuid for host %" AFS_PTR_FMT " (%s:%d) failed %d\n",
+		    ViceLog(0,("CB: ProbeUuid for host %p (%s:%d) failed %d\n",
 			       host,
 			       afs_inet_ntoa_r(host->z.host, hoststr),
 			       ntohs(host->z.port),code2));
@@ -2104,7 +2104,7 @@ h_GetHost_r(struct rx_connection *tcon)
 		goto gethost_out;
 	    } else {
 		ViceLog(0,
-			("CB: WhoAreYou failed for host %" AFS_PTR_FMT " (%s:%d), error %d\n",
+			("CB: WhoAreYou failed for host %p (%s:%d), error %d\n",
 			 host, afs_inet_ntoa_r(host->z.host, hoststr),
 			 ntohs(host->z.port), code));
 		host->z.hostFlags |= VENUSDOWN;
@@ -2122,13 +2122,13 @@ h_GetHost_r(struct rx_connection *tcon)
 	if (!(host->z.hostFlags & ALTADDR)) {
 	    /* another thread is doing the initialisation */
 	    ViceLog(125,
-		    ("Host %" AFS_PTR_FMT " (%s:%d) waiting for host-init to complete\n",
+		    ("Host %p (%s:%d) waiting for host-init to complete\n",
 		     host, afs_inet_ntoa_r(host->z.host, hoststr),
 		     ntohs(host->z.port)));
 	    h_Lock_r(host);
 	    h_Unlock_r(host);
 	    ViceLog(125,
-		    ("Host %" AFS_PTR_FMT " (%s:%d) starting h_Lookup again\n",
+		    ("Host %p (%s:%d) starting h_Lookup again\n",
 		     host, afs_inet_ntoa_r(host->z.host, hoststr),
 		     ntohs(host->z.port)));
 	    h_Release_r(host);
@@ -2195,7 +2195,7 @@ h_GetHost_r(struct rx_connection *tcon)
 		if (!pident)
 		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
 		ViceLog(25,
-			("Host %" AFS_PTR_FMT " (%s:%d) does not support WhoAreYou.\n",
+			("Host %p (%s:%d) does not support WhoAreYou.\n",
 			 host, afs_inet_ntoa_r(host->z.host, hoststr),
 			 ntohs(host->z.port)));
 		code = 0;
@@ -2214,7 +2214,7 @@ h_GetHost_r(struct rx_connection *tcon)
 		if (!pident)
 		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
 		ViceLog(25,
-			("WhoAreYou success on host %" AFS_PTR_FMT " (%s:%d)\n",
+			("WhoAreYou success on host %p (%s:%d)\n",
 			 host, afs_inet_ntoa_r(host->z.host, hoststr),
 			 ntohs(host->z.port)));
 	    }
@@ -2275,7 +2275,7 @@ h_GetHost_r(struct rx_connection *tcon)
 			     * MultiProbeAlternateAddress_r() will remove the
 			     * alternate interfaces that do not have the same
 			     * Uuid. */
-			    ViceLog(0,("CB: ProbeUuid for host %" AFS_PTR_FMT " (%s:%d) failed %d\n",
+			    ViceLog(0,("CB: ProbeUuid for host %p (%s:%d) failed %d\n",
 					 oldHost,
 					 afs_inet_ntoa_r(oldHost->z.host, hoststr),
 					 ntohs(oldHost->z.port),code2));
@@ -2299,7 +2299,7 @@ h_GetHost_r(struct rx_connection *tcon)
 			struct rx_connection *rxconn;
 
 			ViceLog(25,
-				 ("CB: Host %" AFS_PTR_FMT " (%s:%d) has new addr %s:%d\n",
+				 ("CB: Host %p (%s:%d) has new addr %s:%d\n",
 				   oldHost,
 				   afs_inet_ntoa_r(oldHost->z.host, hoststr2),
 				   ntohs(oldHost->z.port),
@@ -2369,7 +2369,7 @@ h_GetHost_r(struct rx_connection *tcon)
 		    H_LOCK;
 		    if (code == 0) {
 			ViceLog(25,
-				("InitCallBackState3 success on host %" AFS_PTR_FMT " (%s:%d)\n",
+				("InitCallBackState3 success on host %p (%s:%d)\n",
 				 host, afs_inet_ntoa_r(host->z.host, hoststr),
 				 ntohs(host->z.port)));
 		    }
@@ -2377,12 +2377,12 @@ h_GetHost_r(struct rx_connection *tcon)
 	    }
 	    if (code) {
 		ViceLog(0,
-			("CB: RCallBackConnectBack failed for %" AFS_PTR_FMT " (%s:%d)\n",
+			("CB: RCallBackConnectBack failed for %p (%s:%d)\n",
 			 host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port)));
 		host->z.hostFlags |= VENUSDOWN;
 	    } else {
 		ViceLog(125,
-			("CB: RCallBackConnectBack succeeded for %" AFS_PTR_FMT " (%s:%d)\n",
+			("CB: RCallBackConnectBack succeeded for %p (%s:%d)\n",
 			 host, afs_inet_ntoa_r(host->z.host, hoststr), ntohs(host->z.port)));
 		host->z.hostFlags |= RESETDONE;
 	    }
@@ -2734,7 +2734,7 @@ h_FindClient_r(struct rx_connection *tcon, afs_int32 *a_viceid)
 	    if (code) {
 		char hoststr[16];
 		ViceLog(0,
-			("pr_GetCPS failed(%d) for user %d, host %" AFS_PTR_FMT " (%s:%d)\n",
+			("pr_GetCPS failed(%d) for user %d, host %p (%s:%d)\n",
 			 code, viceid, client->z.host,
 			 afs_inet_ntoa_r(client->z.host->z.host,hoststr),
 			 ntohs(client->z.host->z.port)));
@@ -3294,6 +3294,10 @@ h_stateVerifyHost(struct host * h, void* rock)
 	return H_ENUMERATE_BAIL(0);
     }
 
+    if (h_stateVerifyAddrHash(state, h, h->z.host, h->z.port, 1)) {
+	state->bail = 1;
+    }
+
     if (h->z.interface) {
 	for (i = h->z.interface->numberOfInterfaces-1; i >= 0; i--) {
 	    if (h_stateVerifyAddrHash(state, h, h->z.interface->interface[i].addr,
@@ -3305,8 +3309,6 @@ h_stateVerifyHost(struct host * h, void* rock)
 	if (h_stateVerifyUuidHash(state, h)) {
 	    state->bail = 1;
 	}
-    } else if (h_stateVerifyAddrHash(state, h, h->z.host, h->z.port, 1)) {
-	state->bail = 1;
     }
 
     if (cb_stateVerifyHCBList(state, h)) {
@@ -4288,7 +4290,7 @@ h_DeleteHostFromAddrHashTable_r(afs_uint32 addr, afs_uint16 port,
 	 hp = &th->next) {
         opr_Assert(th->hostPtr);
         if (th->hostPtr == host && th->addr == addr && th->port == port) {
-	    ViceLog(125, ("h_DeleteHostFromAddrHashTable_r: host %" AFS_PTR_FMT " (%s:%d)\n",
+	    ViceLog(125, ("h_DeleteHostFromAddrHashTable_r: host %p (%s:%d)\n",
 			  host, afs_inet_ntoa_r(host->z.host, hoststr),
 			  ntohs(host->z.port)));
             *hp = th->next;
@@ -4297,7 +4299,7 @@ h_DeleteHostFromAddrHashTable_r(afs_uint32 addr, afs_uint16 port,
         }
     }
     ViceLog(125,
-	    ("h_DeleteHostFromAddrHashTable_r: host %" AFS_PTR_FMT " (%s:%d) not found\n",
+	    ("h_DeleteHostFromAddrHashTable_r: host %p (%s:%d) not found\n",
 	     host, afs_inet_ntoa_r(host->z.host, hoststr),
 	     ntohs(host->z.port)));
     return 0;
diff --git a/src/viced/physio.c b/src/viced/physio.c
index 345c23d745..4f0dfe2d62 100644
--- a/src/viced/physio.c
+++ b/src/viced/physio.c
@@ -39,43 +39,63 @@
 
 afs_int32 lpErrno, lpCount;
 
-/* returns 0 on success, errno on failure */
+/*
+ * Read the specified page from a directory object
+ *
+ * \parm[in] file      handle to the directory object
+ * \parm[in] block     requested page from the directory object
+ * \parm[out] data     buffer for the returned page
+ * \parm[out] physerr  (optional) pointer to errno if physical error
+ *
+ * \retval 0   success
+ * \retval EIO physical or logical error;
+ *             if physerr is supplied by caller, it will be set to:
+ *                 0       for logical errors
+ *                 errno   for physical errors
+ */
 int
-ReallyRead(DirHandle * file, int block, char *data)
+ReallyRead(DirHandle *file, int block, char *data, int *physerr)
 {
-    int code;
+    int saverr = 0;
+    int code = 0;
     ssize_t rdlen;
     FdHandle_t *fdP;
     afs_ino_str_t stmp;
 
     fdP = IH_OPEN(file->dirh_handle);
     if (fdP == NULL) {
-	code = errno;
+	saverr = errno;
+	code = EIO;
 	ViceLog(0,
 		("ReallyRead(): open failed device %X inode %s (volume=%" AFS_VOLID_FMT ") errno %d\n",
 		 file->dirh_handle->ih_dev, PrintInode(stmp,
 						       file->dirh_handle->
 						       ih_ino), 
-		 afs_printable_VolumeId_lu(file->dirh_handle->ih_vid), code));
-	return code;
+		 afs_printable_VolumeId_lu(file->dirh_handle->ih_vid), saverr));
+	goto done;
     }
     rdlen = FDH_PREAD(fdP, data, PAGESIZE, ((afs_foff_t)block) * PAGESIZE);
     if (rdlen != PAGESIZE) {
 	if (rdlen < 0)
-	    code = errno;
+	    saverr = errno;
 	else
-	    code = EIO;
+	    saverr = 0;	    /* logical error: short read */
+	code = EIO;
 	ViceLog(0,
 		("ReallyRead(): read failed device %X inode %s (volume=%" AFS_VOLID_FMT ") errno %d\n",
 		 file->dirh_handle->ih_dev, PrintInode(stmp,
 						       file->dirh_handle->
 						       ih_ino),
-		 afs_printable_VolumeId_lu(file->dirh_handle->ih_vid), code));
+		 afs_printable_VolumeId_lu(file->dirh_handle->ih_vid), saverr));
 	FDH_REALLYCLOSE(fdP);
-	return code;
+	goto done;
     }
     FDH_CLOSE(fdP);
-    return 0;
+
+ done:
+    if (physerr != NULL)
+	*physerr = saverr;
+    return code;
 
 }
 
diff --git a/src/viced/state_analyzer.c b/src/viced/state_analyzer.c
index 10974fd528..d5b8dbbaaf 100644
--- a/src/viced/state_analyzer.c
+++ b/src/viced/state_analyzer.c
@@ -259,7 +259,7 @@ openFile(char * path)
 	goto done;
     }
 
-    printf("mapped %lu bytes at %"AFS_PTR_FMT"\n", (unsigned long)map_len, map);
+    printf("mapped %lu bytes at %p\n", (unsigned long)map_len, map);
 
  done:
     if (ret) {
@@ -700,7 +700,7 @@ print_cb_help(void)
     do { \
         char * _p = (char *)addr; \
         char * _m = (char *)map; \
-        printf("loading structure from address %"AFS_PTR_FMT" (offset %ld)\n", \
+	printf("loading structure from address %p (offset %ld)\n", \
                addr, (long)(_p-_m)); \
     } while (0)
 
diff --git a/src/vlserver/vlutils.c b/src/vlserver/vlutils.c
index 68abcc5aa2..c47bcb78db 100644
--- a/src/vlserver/vlutils.c
+++ b/src/vlserver/vlutils.c
@@ -696,15 +696,25 @@ FindByName(struct vl_ctx *ctx, char *volname, struct nvlentry *tentry,
     hashindex = strlen(volname);	/* really string length */
     if (hashindex >= 8 && strcmp(volname + hashindex - 7, ".backup") == 0) {
 	/* this is a backup volume */
-	strcpy(tname, volname);
+	if (strlcpy(tname, volname, sizeof(tname)) >= sizeof(tname)) {
+	    *error = VL_BADNAME;
+	    return 0;
+	}
 	tname[hashindex - 7] = 0;	/* zap extension */
     } else if (hashindex >= 10
 	       && strcmp(volname + hashindex - 9, ".readonly") == 0) {
 	/* this is a readonly volume */
-	strcpy(tname, volname);
+	if (strlcpy(tname, volname, sizeof(tname)) >= sizeof(tname)) {
+	    *error = VL_BADNAME;
+	    return 0;
+	}
 	tname[hashindex - 9] = 0;	/* zap extension */
-    } else
-	strcpy(tname, volname);
+    } else {
+	if (strlcpy(tname, volname, sizeof(tname)) >= sizeof(tname)) {
+	    *error = VL_BADNAME;
+	    return 0;
+	}
+    }
 
     *error = 0;
     hashindex = NameHash(tname);
diff --git a/src/vol/clone.c b/src/vol/clone.c
index dfe67cad24..deaa079c51 100644
--- a/src/vol/clone.c
+++ b/src/vol/clone.c
@@ -256,7 +256,7 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
 	    } else if (rwinode) {
 		if (IH_INC(V_linkHandle(rwvp), rwinode, V_parentId(rwvp)) ==
 		    -1) {
-		    Log("IH_INC failed: %"AFS_PTR_FMT", %s, %" AFS_VOLID_FMT " errno %d\n",
+		    Log("IH_INC failed: %p, %s, %" AFS_VOLID_FMT " errno %d\n",
 			V_linkHandle(rwvp), PrintInode(stmp, rwinode),
 			afs_printable_VolumeId_lu(V_parentId(rwvp)), errno);
 		    VForceOffline(rwvp);
@@ -309,7 +309,7 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
 	    if (inodeinced) {
 		if (IH_DEC(V_linkHandle(rwvp), rwinode, V_parentId(rwvp)) ==
 		    -1) {
-		    Log("IH_DEC failed: %"AFS_PTR_FMT", %s, %" AFS_VOLID_FMT " errno %d\n",
+		    Log("IH_DEC failed: %p, %s, %" AFS_VOLID_FMT " errno %d\n",
 			V_linkHandle(rwvp), PrintInode(stmp, rwinode),
 			afs_printable_VolumeId_lu(V_parentId(rwvp)), errno);
 		    VForceOffline(rwvp);
diff --git a/src/vol/physio.c b/src/vol/physio.c
index 170c9c79db..37afe78d09 100644
--- a/src/vol/physio.c
+++ b/src/vol/physio.c
@@ -32,31 +32,52 @@
 #include <afs/dir.h>
 #include "vol_internal.h"
 
-/* returns 0 on success, errno on failure */
+/*
+ * Read the specified page from a directory object
+ *
+ * \parm[in] file	handle to the directory object
+ * \parm[in] block	requested page from the directory object
+ * \parm[out] data	buffer for the returned page
+ * \parm[out] physerr	(optional) pointer to errno if physical error
+ *
+ * \retval 0	success
+ * \retval EIO	physical or logical error;
+ *		if physerr is supplied by caller, it will be set to:
+ *		    0	    for logical errors
+ *		    errno   for physical errors
+ */
 int
-ReallyRead(DirHandle * file, int block, char *data)
+ReallyRead(DirHandle *file, int block, char *data, int *physerr)
 {
     FdHandle_t *fdP;
-    int code;
+    int code = 0;
+    int saverr = 0;
     ssize_t nBytes;
+
     errno = 0;
     fdP = IH_OPEN(file->dirh_handle);
     if (fdP == NULL) {
-	code = errno;
-	return code;
+	saverr = errno;
+	code = EIO;
+	goto done;
     }
     nBytes = FDH_PREAD(fdP, data, (afs_fsize_t) AFS_PAGESIZE,
                        ((afs_foff_t)block) * AFS_PAGESIZE);
     if (nBytes != AFS_PAGESIZE) {
 	if (nBytes < 0)
-	    code = errno;
+	    saverr = errno;
 	else
-	    code = EIO;
+	    saverr = 0;	    /* logical error: short read */
+	code = EIO;
 	FDH_REALLYCLOSE(fdP);
-	return code;
+	goto done;
     }
     FDH_CLOSE(fdP);
-    return 0;
+
+ done:
+    if (physerr != NULL)
+	*physerr = saverr;
+    return code;
 }
 
 /* returns 0 on success, errno on failure */
diff --git a/src/vol/vg_cache.c b/src/vol/vg_cache.c
index 5a53a2f578..5e8ca75fa7 100644
--- a/src/vol/vg_cache.c
+++ b/src/vol/vg_cache.c
@@ -508,7 +508,7 @@ _VVGC_hash_entry_add(struct DiskPartition64 * dp,
 	if (ent != nent) {
 	    ViceLog(0, ("_VVGC_hash_entry_add: tried to add a duplicate "
 	                " nonmatching entry for vol %lu: original "
-	                "(%"AFS_PTR_FMT",%lu) new (%"AFS_PTR_FMT",%lu)\n",
+			"(%p,%lu) new (%p,%lu)\n",
 	                afs_printable_uint32_lu(volid),
 	                nent, afs_printable_uint32_lu(nent->rw),
 	                ent, afs_printable_uint32_lu(ent->rw)));
@@ -891,8 +891,8 @@ _VVGC_entry_purge_r(struct DiskPartition64 * dp,
 	if (parent_ent != child_ent) {
 	    ViceLog(0,
 		    ("VVGCache_entry_del: trying to delete vol %lu from VG %lu, "
-		     "but vol %lu points to VGC entry %" AFS_PTR_FMT
-		     " and VG %lu " "points to VGC entry %" AFS_PTR_FMT "\n",
+		     "but vol %lu points to VGC entry %p"
+		     " and VG %lu " "points to VGC entry %p\n",
 		     afs_printable_uint32_lu(child),
 		     afs_printable_uint32_lu(parent),
 		     afs_printable_uint32_lu(child), child_ent,
diff --git a/src/vol/vnode.c b/src/vol/vnode.c
index 472e2e4288..dd50c5f38d 100644
--- a/src/vol/vnode.c
+++ b/src/vol/vnode.c
@@ -1376,7 +1376,7 @@ VPutVnode_r(Error * ec, Vnode * vnp)
 						changed_oldTime) << 1) | vnp->
 	      delete, 0, 0);
 	if (thisProcess != vnp->writer)
-	    Abort("VPutVnode: Vnode at %"AFS_PTR_FMT" locked by another process!\n",
+	    Abort("VPutVnode: Vnode at %p locked by another process!\n",
 		  vnp);
 
 
@@ -1434,7 +1434,7 @@ VPutVnode_r(Error * ec, Vnode * vnp)
 	if (vnp->changed_newTime || vnp->changed_oldTime || vnp->delete)
 	    Abort
 		("VPutVnode: Change or delete flag for vnode "
-		 "%"AFS_PTR_FMT" is set but vnode is not write locked!\n",
+		 "%p is set but vnode is not write locked!\n",
 		 vnp);
 #ifdef AFS_DEMAND_ATTACH_FS
 	VnEndRead_r(vnp);
@@ -1521,8 +1521,7 @@ VVnodeWriteToRead_r(Error * ec, Vnode * vnp)
     LWP_CurrentProcess(&thisProcess);
 #endif /* AFS_PTHREAD_ENV */
     if (thisProcess != vnp->writer)
-	Abort("VPutVnode: Vnode at %"AFS_PTR_FMT
-	      " locked by another process!\n", vnp);
+	Abort("VPutVnode: Vnode at %p locked by another process!\n", vnp);
 
     if (vnp->delete) {
 	return 0;
diff --git a/src/vol/volume.c b/src/vol/volume.c
index af4189e58b..2fa05ca9ac 100644
--- a/src/vol/volume.c
+++ b/src/vol/volume.c
@@ -1031,7 +1031,7 @@ VInitPreAttachVolumes(int nthreads, struct volume_init_queue *vq)
     while (nthreads) {
         /* dequeue next volume */
 	opr_mutex_enter(&vq->mutex);
-        if (queue_IsEmpty(vq)) {
+	while (queue_IsEmpty(vq)) {
 	    opr_cv_wait(&vq->cv, &vq->mutex);
         }
         vb = queue_First(vq, volume_init_batch);
@@ -1201,7 +1201,9 @@ VShutdown_r(void)
     if (VInit < 2) {
         Log("VShutdown:  aborting attach volumes\n");
         vinit_attach_abort = 1;
-        VOL_CV_WAIT(&vol_init_attach_cond);
+	while (VInit < 2) {
+	    VOL_CV_WAIT(&vol_init_attach_cond);
+	}
     }
 
     for (params.n_parts=0, diskP = DiskPartitionList;
@@ -1326,11 +1328,13 @@ VShutdown_r(void)
     if (VInit < 2) {
         Log("VShutdown:  aborting attach volumes\n");
         vinit_attach_abort = 1;
+	while (VInit < 2) {
 #ifdef AFS_PTHREAD_ENV
-        VOL_CV_WAIT(&vol_init_attach_cond);
+	    VOL_CV_WAIT(&vol_init_attach_cond);
 #else
-        LWP_WaitProcess(VInitAttachVolumes);
+	    LWP_WaitProcess(VInitAttachVolumes);
 #endif /* AFS_PTHREAD_ENV */
+	}
     }
 
     Log("VShutdown:  shutting down on-line volumes...\n");
@@ -3367,6 +3371,8 @@ attach2(Error * ec, VolumeId volumeId, char *path, struct DiskPartition64 *partp
 	goto locked_error;
     }
 
+    free(vp->vnodeIndex[vSmall].bitmap);
+    free(vp->vnodeIndex[vLarge].bitmap);
     vp->vnodeIndex[vSmall].bitmap = vp->vnodeIndex[vLarge].bitmap = NULL;
 #ifndef BITMAP_LATER
     if (programType == fileServer && VolumeWriteable(vp)) {
diff --git a/src/volser/dumpstuff.c b/src/volser/dumpstuff.c
index 340b9f9142..2db0d0db8a 100644
--- a/src/volser/dumpstuff.c
+++ b/src/volser/dumpstuff.c
@@ -1178,6 +1178,7 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
     int s1 = 0, s2 = 0, delo = 0, tdelo;
     int tag;
     VolumeDiskData saved_header;
+    afs_uint32 uptime, crtime;
 
     iod_Init(iodp, call);
 
@@ -1265,6 +1266,8 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
 	 * prevent it from getting overwritten. */
 	vol.needsSalvaged = V_needsSalvaged(vp);
     }
+    crtime = V_creationDate(vp);
+    uptime = V_updateDate(vp);
     CopyVolumeHeader(&vol, &V_disk(vp));
     V_destroyMe(vp) = 0;
     VUpdateVolume(&vupdate, vp);
@@ -1272,6 +1275,20 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
 	Log("1 Volser: RestoreVolume: Unable to rewrite volume header; restore aborted\n");
 	error = VOLSERREAD_DUMPERROR;
 	goto out;
+    } else {
+	/*
+	 * If the volume was not a new empty volume and the restored dump was
+	 * older than the volume in question, this is probably a mistake, and
+	 * may mean the resulting volume is corrupted. Log the following message
+	 * to give a clue as to why this volume suddenly looks strange or corrupt.
+	 */
+	if ((crtime != uptime) && (uptime > V_updateDate(vp))) {
+	    Log("1 Volser: RestoreVolume: volume %s (%u) appears to have been partially or "
+		"completely restored to an earlier version (updateDate went from %u to %u). "
+		"This is allowed, but may indicate a mistake in whatever tool is restoring "
+		"this volume. If this volume appears corrupted, this is probably why.\n",
+		V_name(vp), V_id(vp), uptime, V_updateDate(vp));
+	}
     }
   out:
     /* Free the malloced space above */
diff --git a/src/volser/physio.c b/src/volser/physio.c
index 3562cf8284..a1418ad64c 100644
--- a/src/volser/physio.c
+++ b/src/volser/physio.c
@@ -22,30 +22,50 @@
 #include "vol.h"
 #include "physio.h"
 
-/* returns 0 on success, errno on failure */
+/*
+ * Read the specified page from a directory object
+ *
+ * \parm[in] file	handle to the directory object
+ * \parm[in] block	requested page from the directory object
+ * \parm[out] data	buffer for the returned page
+ * \parm[out] physerr	(optional) pointer to errno if physical error
+ *
+ * \retval 0   success
+ * \retval EIO physical or logical error;
+ *             if physerr is supplied by caller, it will be set to:
+ *                 0       for logical errors
+ *                 errno   for physical errors
+ */
 int
-ReallyRead(DirHandle * file, int block, char *data)
+ReallyRead(DirHandle *file, int block, char *data, int *physerr)
 {
     FdHandle_t *fdP;
-    int code;
+    int code = 0;
+    int saverr = 0;
     ssize_t nBytes;
     errno = 0;
     fdP = IH_OPEN(file->dirh_handle);
     if (fdP == NULL) {
-	code = errno;
-	return code;
+	saverr = errno;
+	code = EIO;
+	goto done;;
     }
     nBytes = FDH_PREAD(fdP, data, AFS_PAGESIZE, ((afs_foff_t)block) * AFS_PAGESIZE);
     if (nBytes != AFS_PAGESIZE) {
 	if (nBytes < 0)
-	    code = errno;
+	    saverr = errno;
 	else
-	    code = EIO;
+	    saverr = 0;	    /* logical error: short read */
+	code = EIO;
 	FDH_REALLYCLOSE(fdP);
-	return code;
+	goto done;
     }
     FDH_CLOSE(fdP);
-    return 0;
+
+ done:
+    if (physerr != NULL)
+	*physerr = saverr;
+    return code;
 }
 
 /* returns 0 on success, errno on failure */
diff --git a/src/volser/vos.c b/src/volser/vos.c
index e43e9fb3f8..007bfe5064 100644
--- a/src/volser/vos.c
+++ b/src/volser/vos.c
@@ -106,7 +106,6 @@ cmd_AddParmAtOffset(ts, COMMONPARM_OFFSET_CONFIG, \
 
 int rxInitDone = 0;
 extern struct ubik_client *cstruct;
-const char *confdir;
 
 static struct tqHead busyHead, notokHead;
 
@@ -5829,6 +5828,8 @@ MyBeforeProc(struct cmd_syndesc *as, void *arock)
     char *tcell;
     afs_int32 code;
     int secFlags;
+    const char *confdir = AFSDIR_CLIENT_ETC_DIRPATH;
+    const char *retry_confdir = AFSDIR_SERVER_ETC_DIRPATH;
 
     /* Initialize the ubik_client connection */
     rx_SetRxDeadTime(90);
@@ -5845,6 +5846,7 @@ MyBeforeProc(struct cmd_syndesc *as, void *arock)
     if (as->parms[COMMONPARM_OFFSET_LOCALAUTH].items) {	/* -localauth specified */
 	secFlags |= AFSCONF_SECOPTS_LOCALAUTH;
 	confdir = AFSDIR_SERVER_ETC_DIRPATH;
+	retry_confdir = NULL;
     }
 
     if (as->parms[COMMONPARM_OFFSET_ENCRYPT].items     /* -encrypt specified */
@@ -5854,11 +5856,19 @@ MyBeforeProc(struct cmd_syndesc *as, void *arock)
 	 )
 	secFlags |= AFSCONF_SECOPTS_ALWAYSENCRYPT;
 
-    if (as->parms[COMMONPARM_OFFSET_CONFIG].items)   /* -config flag set */
+    if (as->parms[COMMONPARM_OFFSET_CONFIG].items) {  /* -config flag set */
 	confdir = as->parms[COMMONPARM_OFFSET_CONFIG].items->data;
+	retry_confdir = NULL;
+    }
 
-    if ((code = vsu_ClientInit(confdir, tcell, secFlags, UV_SetSecurity,
-			       &cstruct))) {
+    code = vsu_ClientInit(confdir, tcell, secFlags, UV_SetSecurity, &cstruct);
+    if (code != 0 && retry_confdir != NULL) {
+	fprintf(STDERR, "vos: Retrying initialization with directory %s\n",
+		retry_confdir);
+	code = vsu_ClientInit(retry_confdir, tcell, secFlags, UV_SetSecurity,
+			      &cstruct);
+    }
+    if (code != 0) {
 	fprintf(STDERR, "could not initialize VLDB library (code=%lu) \n",
 		(unsigned long)code);
 	exit(1);
@@ -5900,8 +5910,6 @@ main(int argc, char **argv)
     sigaction(SIGSEGV, &nsa, NULL);
 #endif
 
-    confdir = AFSDIR_CLIENT_ETC_DIRPATH;
-
     cmd_SetBeforeProc(MyBeforeProc, NULL);
 
     ts = cmd_CreateSyntax("create", CreateVolume, NULL, 0, "create a new volume");
diff --git a/src/xstat/xstat_cm.c b/src/xstat/xstat_cm.c
index 3f5bfc843c..d2302e077b 100644
--- a/src/xstat/xstat_cm.c
+++ b/src/xstat/xstat_cm.c
@@ -256,12 +256,12 @@ xstat_cm_LWP(void *unused)
 
 		    if (xstat_cm_debug) {
 			printf
-			    ("%s: Calling RXAFSCB_GetXStats, conn=%" AFS_PTR_FMT ", clientVersionNumber=%d, collectionNumber=%d, srvVersionNumberP=%" AFS_PTR_FMT ", timeP=%" AFS_PTR_FMT ", dataP=%" AFS_PTR_FMT "\n",
+			    ("%s: Calling RXAFSCB_GetXStats, conn=%p, clientVersionNumber=%d, collectionNumber=%d, srvVersionNumberP=%p, timeP=%p, dataP=%p\n",
 			     rn, curr_conn->rxconn, clientVersionNumber,
 			     *currCollIDP, &srvVersionNumber,
 			     &(xstat_cm_Results.probeTime),
 			     &(xstat_cm_Results.data));
-			printf("%s: [bufflen=%d, buffer at %" AFS_PTR_FMT "]\n", rn,
+			printf("%s: [bufflen=%d, buffer at %p]\n", rn,
 			       xstat_cm_Results.data.AFSCB_CollData_len,
 			       xstat_cm_Results.data.AFSCB_CollData_val);
 		    }
@@ -313,7 +313,7 @@ xstat_cm_LWP(void *unused)
 	     * that we've finished our collection round.
 	     */
 	    if (xstat_cm_debug)
-		printf("[%s] Signalling main process at %" AFS_PTR_FMT "\n", rn,
+		printf("[%s] Signalling main process at %p\n", rn,
 		       &cm_terminationEvent);
 	    oneShotCode = LWP_SignalProcess(&cm_terminationEvent);
 	    if (oneShotCode)
@@ -558,7 +558,7 @@ xstat_cm_Init(int a_numServers, struct sockaddr_in *a_socketArray,
 	    conn_err = 1;
 	}
 	if (xstat_cm_debug)
-	    printf("[%s] New connection at %" AFS_PTR_FMT "\n", rn, curr_conn->rxconn);
+	    printf("[%s] New connection at %p\n", rn, curr_conn->rxconn);
 
 	/*
 	 * Bump the current xstat_cm connection to set up.
@@ -585,7 +585,7 @@ xstat_cm_Init(int a_numServers, struct sockaddr_in *a_socketArray,
 	return (code);
     }
     if (xstat_cm_debug)
-	printf("[%s] Probe LWP process structure located at %" AFS_PTR_FMT "\n", rn,
+	printf("[%s] Probe LWP process structure located at %p\n", rn,
 	       probeLWP_ID);
 
     /*
diff --git a/src/xstat/xstat_cm_test.c b/src/xstat/xstat_cm_test.c
index 7c5e56864f..cf4d9bbda1 100644
--- a/src/xstat/xstat_cm_test.c
+++ b/src/xstat/xstat_cm_test.c
@@ -880,8 +880,8 @@ RunTheTest(struct cmd_syndesc *a_s, void *arock)
 	 * One-shot operation; just wait for the collection to be done.
 	 */
 	if (debugging_on)
-	    printf("[%s] Calling LWP_WaitProcess() on event %" AFS_PTR_FMT
-		   "\n", rn, &cm_terminationEvent);
+	    printf("[%s] Calling LWP_WaitProcess() on event %p\n",
+		   rn, &cm_terminationEvent);
 	waitCode = LWP_WaitProcess(&cm_terminationEvent);
 	if (debugging_on)
 	    printf("[%s] Returned from LWP_WaitProcess()\n", rn);
diff --git a/src/xstat/xstat_fs.c b/src/xstat/xstat_fs.c
index dff9304724..0175d3f3e1 100644
--- a/src/xstat/xstat_fs.c
+++ b/src/xstat/xstat_fs.c
@@ -275,12 +275,12 @@ xstat_fs_LWP(void *unused)
 
 		    if (xstat_fs_debug) {
 			printf
-			    ("%s: Calling RXAFS_GetXStats, conn=%" AFS_PTR_FMT ", clientVersionNumber=%d, collectionNumber=%d, srvVersionNumberP=%" AFS_PTR_FMT ", timeP=%" AFS_PTR_FMT ", dataP=%" AFS_PTR_FMT "\n",
+			    ("%s: Calling RXAFS_GetXStats, conn=%p, clientVersionNumber=%d, collectionNumber=%d, srvVersionNumberP=%p, timeP=%p, dataP=%p\n",
 			     rn, curr_conn->rxconn, clientVersionNumber,
 			     *currCollIDP, &srvVersionNumber,
 			     &(xstat_fs_Results.probeTime),
 			     &(xstat_fs_Results.data));
-			printf("%s: [bufflen=%d, buffer at %" AFS_PTR_FMT "]\n", rn,
+			printf("%s: [bufflen=%d, buffer at %p]\n", rn,
 			       xstat_fs_Results.data.AFS_CollData_len,
 			       xstat_fs_Results.data.AFS_CollData_val);
 		    }
@@ -332,7 +332,7 @@ xstat_fs_LWP(void *unused)
 	     * that we've finished our collection round.
 	     */
 	    if (xstat_fs_debug)
-		printf("[%s] Signalling main process at %" AFS_PTR_FMT "\n", rn,
+		printf("[%s] Signalling main process at %p\n", rn,
 		       &fs_terminationEvent);
 	    oneShotCode = LWP_SignalProcess(&fs_terminationEvent);
 	    if (oneShotCode)
@@ -595,7 +595,7 @@ xstat_fs_Init(int a_numServers, struct sockaddr_in *a_socketArray,
 	    conn_err = 1;
 	}
 	if (xstat_fs_debug)
-	    printf("[%s] New connection at %" AFS_PTR_FMT "\n", rn, curr_conn->rxconn);
+	    printf("[%s] New connection at %p\n", rn, curr_conn->rxconn);
 
 	/*
 	 * Bump the current xstat_fs connection to set up.
@@ -649,7 +649,7 @@ xstat_fs_Init(int a_numServers, struct sockaddr_in *a_socketArray,
 	return (code);
     }
     if (xstat_fs_debug)
-	printf("[%s] Probe LWP process structure located at %" AFS_PTR_FMT "\n", rn,
+	printf("[%s] Probe LWP process structure located at %p\n", rn,
 	       probeLWP_ID);
 
     /*
diff --git a/src/xstat/xstat_fs_test.c b/src/xstat/xstat_fs_test.c
index d58ecf0144..53e46f9b2b 100644
--- a/src/xstat/xstat_fs_test.c
+++ b/src/xstat/xstat_fs_test.c
@@ -122,7 +122,7 @@ PrintCallInfo(void)
 	   printableTime);
 
     if (debugging_on)
-	printf("\n[%u entries returned at %" AFS_PTR_FMT "]\n\n", numInt32s, currInt32);
+	printf("\n[%u entries returned at %p]\n\n", numInt32s, currInt32);
 
     for (i = 0; i < numInt32s; i++)
 	printf("%u ", *currInt32++);
@@ -777,7 +777,7 @@ RunTheTest(struct cmd_syndesc *a_s, void *dummy)
 	 * One-shot operation; just wait for the collection to be done.
 	 */
 	if (debugging_on)
-	    printf("[%s] Calling LWP_WaitProcess() on event %" AFS_PTR_FMT "\n", rn,
+	    printf("[%s] Calling LWP_WaitProcess() on event %p\n", rn,
 		   &fs_terminationEvent);
 	waitCode = LWP_WaitProcess(&fs_terminationEvent);
 	if (debugging_on)
