From 6ba1ff2b94f737b64aaecd75aa50557008ef8df2 Mon Sep 17 00:00:00 2001
From: Cerdic <cedric@yterium.com>
Date: Tue, 26 Jul 2022 10:11:23 +0200
Subject: [PATCH] =?UTF-8?q?fix:=20le=20refactoring=20echoue=20l=C3=A0=20ou?=
 =?UTF-8?q?=20la=20precedente=20version=20bien=20crade=20marchait,=20essay?=
 =?UTF-8?q?ons=20de=20comprendre=20pourquoi?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ecrire/inc/flock.php | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/ecrire/inc/flock.php b/ecrire/inc/flock.php
index 754f4174ba..634ac56b6a 100644
--- a/ecrire/inc/flock.php
+++ b/ecrire/inc/flock.php
@@ -242,8 +242,10 @@ function ecrire_fichier($fichier, $contenu, $ignorer_echec = false, $truncate =
 				spip_fclose_unlock($fp);
 				$fp = null;
 				// on rename vers la cible, ce qui est atomique quand on est pas sous windows
-				// au pire on arrive en second en cas de concurance, et le rename echoue
+				// au pire on arrive en second en cas de concurence, et le rename echoue
 				// --> on a la version de l'autre process qui doit etre identique
+				// sur certains fs lent, il semble que le rename echoue parce que notre propre lock est pas libéré assez vite...
+				// ce cas sera traité par le fallback avec eventuellement une tempo si besoin
 				if (@rename("$fichier.$id", $fichier)) {
 					$ok = file_exists($fichier);
 				}
@@ -260,10 +262,21 @@ function ecrire_fichier($fichier, $contenu, $ignorer_echec = false, $truncate =
 		// sinon ou si methode precedente a echoueee
 		// on se rabat sur file_put_contents direct sur le fichier
 		if (!$ok) {
+			clearstatcache();
 			$l = file_put_contents($fichier, $contenu, $truncate ? LOCK_EX : LOCK_EX | FILE_APPEND);
 			$ok = ($l === $longueur_a_ecrire);
 			if ($truncate) {
-				spip_logger('flock')->notice("ecrire_fichier: operation atomique via rename() impossible, fallback non atomique via file_put_contents");
+				spip_logger('flock')->notice("ecrire_fichier: operation atomique via rename() impossible, fallback non atomique via file_put_contents" . ($ok ? 'OK' : 'Fail'));
+			}
+			if (!$ok) {
+				// derniere tentative : on sait que file_put_contents marche dans le dossier considere
+				// c'est peut etre un probleme de tempo avant que le lock qu'on a nous meme posé soit libéré (fs lent)
+				usleep(250000);
+				$l = file_put_contents($fichier, $contenu, $truncate ? LOCK_EX : LOCK_EX | FILE_APPEND);
+				$ok = ($l === $longueur_a_ecrire);
+				if ($truncate) {
+					spip_logger('flock')->notice("ecrire_fichier: operation atomique via rename() impossible, fallback non atomique via tempo + file_put_contents : " . ($ok ? 'OK' : 'Fail'));
+				}
 			}
 		}
 
-- 
GitLab