diff --git a/GHC/PackageDb.hs b/GHC/PackageDb.hs
--- a/GHC/PackageDb.hs
+++ b/GHC/PackageDb.hs
@@ -239,15 +239,21 @@
   -- DB for reading then we will require that the installer/packaging has
   -- included the lock file.
   --
-  -- Thus the logic here is to first try opening in read-only mode (to handle
-  -- global read-only DBs) and if the file does not exist then try opening in
-  -- read/write mode to create the lock file. If either succeed then lock the
-  -- file. IO exceptions (other than the first open attempt failing due to the
-  -- file not existing) simply propagate.
+  -- Thus the logic here is to first try opening in read-write mode
+  -- and if that fails we try read-only (to handle global read-only DBs).
+  -- If either succeed then lock the file. IO exceptions (other than the first
+  -- open attempt failing due to the file not existing) simply propagate.
+  --
+  -- Note that there is a complexity here which was discovered in #13945: some
+  -- filesystems (e.g. NFS) will only allow exclusive locking if the fd was
+  -- opened for write access. We would previously try opening the lockfile for
+  -- read-only access first, however this failed when run on such filesystems.
+  -- Consequently, we now try read-write access first, falling back to read-only
+  -- if are denied permission (e.g. in the case of a global database).
   catchJust
-    (\e -> if isDoesNotExistError e then Just () else Nothing)
-    (lockFileOpenIn ReadMode)
-    (const $ lockFileOpenIn ReadWriteMode)
+    (\e -> if isPermissionError e then Just () else Nothing)
+    (lockFileOpenIn ReadWriteMode)
+    (const $ lockFileOpenIn ReadMode)
   where
     lock = file <.> "lock"
 
@@ -261,7 +267,11 @@
                    return $ PackageDbLock hnd
 
 lockPackageDb = lockPackageDbWith ExclusiveLock
-unlockPackageDb (PackageDbLock hnd) = hClose hnd
+unlockPackageDb (PackageDbLock hnd) = do
+#if MIN_VERSION_base(4,11,0)
+    hUnlock hnd
+#endif
+    hClose hnd
 
 -- MIN_VERSION_base(4,10,0)
 #else
diff --git a/ghc-boot.cabal b/ghc-boot.cabal
--- a/ghc-boot.cabal
+++ b/ghc-boot.cabal
@@ -1,5 +1,7 @@
+cabal-version:  1.22
 name:           ghc-boot
-version:        8.2.1
+version:        8.2.2
+
 license:        BSD3
 license-file:   LICENSE
 category:       GHC
@@ -12,13 +14,12 @@
                 A note about "GHC.PackageDb": it only deals with the subset of
                 the package database that the compiler cares about: modules
                 paths etc and not package metadata like description, authors
-                etc. It is thus not a library interface to ghc-pkg and is *not*
+                etc. It is thus not a library interface to ghc-pkg and is __not__
                 suitable for modifying GHC package databases.
                 .
                 The package database format and this library are constructed in
                 such a way that while ghc-pkg depends on Cabal, the GHC library
                 and program do not have to depend on Cabal.
-cabal-version:  >=1.22
 build-type:     Simple
 extra-source-files: changelog.md
 
@@ -37,9 +38,9 @@
             GHC.Serialized
             GHC.ForeignSrcLang
 
-    build-depends: base       >= 4.7 && < 4.11,
+    build-depends: base       >= 4.8 && < 4.11,
                    binary     == 0.8.*,
                    bytestring == 0.10.*,
                    directory  >= 1.2 && < 1.4,
                    filepath   >= 1.3 && < 1.5,
-                   ghc-boot-th == 8.2.1
+                   ghc-boot-th == 8.2.2
