diff --git a/gitdb/db/loose.py b/gitdb/db/loose.py
index 87cde86..03d387e 100644
--- a/gitdb/db/loose.py
+++ b/gitdb/db/loose.py
@@ -54,6 +54,7 @@
 import tempfile
 import os
 import sys
+import time
 
 
 __all__ = ('LooseObjectDB', )
@@ -205,7 +206,7 @@ def store(self, istream):
             # END assure target stream is closed
         except:
             if tmp_path:
-                os.remove(tmp_path)
+                remove(tmp_path)
             raise
         # END assure tmpfile removal on error
 
@@ -228,9 +229,22 @@ def store(self, istream):
                 rename(tmp_path, obj_path)
             # end rename only if needed
 
-            # make sure its readable for all ! It started out as rw-- tmp file
-            # but needs to be rwrr
-            chmod(obj_path, self.new_objects_mode)
+            # Ensure rename is actually done and file is stable
+            # Retry up to 14 times - exponential wait & retry in ms.
+            # The total maximum wait time is 1000ms, which should be vastly enough for the
+            # OS to return and commit the file to disk.
+            for exp_backoff_ms in [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 181]:
+                with suppress(PermissionError):
+                    # make sure its readable for all ! It started out as rw-- tmp file
+                    # but needs to be rwrr
+                    chmod(obj_path, self.new_objects_mode)
+                    break
+                time.sleep(exp_backoff_ms / 1000.0)
+            else:
+                raise PermissionError(
+                    "Impossible to apply `chmod` to file {}".format(obj_path)
+                )
+
         # END handle dry_run
 
         istream.binsha = hex_to_bin(hexsha)