[PATCH 1 of 6] transaction: add optional flush to transaction

Henrik Stuart hg at hstuart.dk
Wed Apr 22 02:58:43 CDT 2009


# HG changeset patch
# User Henrik Stuart <hg at hstuart.dk>
# Date 1240383276 -7200
# Node ID 610cefac85c02e9053fb0ba66cc0fb607357dced
# Parent  18710802cd4943834441c37420286a98b9a9bba5
transaction: add optional flush to transaction

Without the fsync that ensures the journal is written to the underlying
file system, the transaction caller may believe that the journal is
committed, but it may subsequently be lost if the actual writing to the
file system fails, e.g. since the disk is full. Thus, an incomplete
transaction log may exist on the disk, possibly corrupting state on a
subsequent hg recover, or leaving irrelevant data in revlogs.

Co-contributor: Sune Foldager <cryo at cyanite.org>

diff -r 18710802cd49 -r 610cefac85c0 mercurial/transaction.py
--- a/mercurial/transaction.py	Tue Apr 21 16:02:59 2009 +0200
+++ b/mercurial/transaction.py	Wed Apr 22 08:54:36 2009 +0200
@@ -39,8 +39,14 @@
         if file in self.map: return
         self.entries.append((file, offset, data))
         self.map[file] = len(self.entries) - 1
+        self._write("%s\0%d\n" % (file, offset))
+
+    def flush(self):
+        os.fsync(self.file.fileno())
+
+    def _write(self, data):
         # add enough data to the journal to do the truncate
-        self.file.write("%s\0%d\n" % (file, offset))
+        self.file.write(data)
         self.file.flush()
 
     def find(self, file):
@@ -53,8 +59,7 @@
             raise KeyError(file)
         index = self.map[file]
         self.entries[index] = (file, offset, data)
-        self.file.write("%s\0%d\n" % (file, offset))
-        self.file.flush()
+        self._write("%s\0%d\n" % (file, offset))
 
     def nest(self):
         self.count += 1


More information about the Mercurial-devel mailing list