comparison mercurial/localrepo.py @ 20883:cd443c7589cc

fncache: move fncache writing to be in a transaction Previously the fncache was written at lock.release time. This meant it was not tracked by a transaction, and if an error occurred during the fncache write it would fail to update the fncache, but would not rollback the transaction, resulting in an fncache that was not in sync with the files on disk (which causes verify to fail, and causes streaming clones to not copy all the revlogs). This uses the new transaction backup mechanism to make the fncache transacted. It also moves the fncache from being written at lock.release time, to being written at transaction.close time.
author Durham Goode <durham@fb.com>
date Mon, 24 Mar 2014 15:42:13 -0700
parents 925c2d604389
children 2efdd186925d
comparison
equal deleted inserted replaced
20882:5dffd06f1e50 20883:cd443c7589cc
821 # abort here if the journal already exists 821 # abort here if the journal already exists
822 if self.svfs.exists("journal"): 822 if self.svfs.exists("journal"):
823 raise error.RepoError( 823 raise error.RepoError(
824 _("abandoned transaction found - run hg recover")) 824 _("abandoned transaction found - run hg recover"))
825 825
826 def onclose():
827 self.store.write(tr)
828
826 self._writejournal(desc) 829 self._writejournal(desc)
827 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()] 830 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
828 rp = report and report or self.ui.warn 831 rp = report and report or self.ui.warn
829 tr = transaction.transaction(rp, self.sopener, 832 tr = transaction.transaction(rp, self.sopener,
830 "journal", 833 "journal",
831 aftertrans(renames), 834 aftertrans(renames),
832 self.store.createmode) 835 self.store.createmode,
836 onclose)
833 self._transref = weakref.ref(tr) 837 self._transref = weakref.ref(tr)
834 return tr 838 return tr
835 839
836 def _journalfiles(self): 840 def _journalfiles(self):
837 return ((self.svfs, 'journal'), 841 return ((self.svfs, 'journal'),
1035 if l is not None and l.held: 1039 if l is not None and l.held:
1036 l.lock() 1040 l.lock()
1037 return l 1041 return l
1038 1042
1039 def unlock(): 1043 def unlock():
1040 self.store.write()
1041 if hasunfilteredcache(self, '_phasecache'): 1044 if hasunfilteredcache(self, '_phasecache'):
1042 self._phasecache.write() 1045 self._phasecache.write()
1043 for k, ce in self._filecache.items(): 1046 for k, ce in self._filecache.items():
1044 if k == 'dirstate' or k not in self.__dict__: 1047 if k == 'dirstate' or k not in self.__dict__:
1045 continue 1048 continue