Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 51143:849745d7da89 stable
revlog: avoid wrongly updating the data file location on "divert"
If we are in the inline case, we need to align the location of the "data" file
with the temporary location of the file (i.e. "00changelog.i.a"). However we
should not do that for non-inline case? and before this changeset we had been
doing it. In addition `index_file` is already a property taking care of updating
the "segment file" filename when needed. So we can simply remove all that code.
As a result, code trying to read the diverted data before they were committed
ended deeply confused as the "00changelog.i.a" file is nothing like the
"00changelog.d" file.
However nothing corrupted data as all writing where properly handled outside of
the "segment file".
In "best" cases this small in-memory corruption of the filename when unnoticed
until the transaction was committed or rolled back and in the worse case, some
data reading was failing during the transaction and resulted in the transaction
to be rolled back. However wrong data never reached the disk, so this bug should
be have corrupted any repository.
This is not catch by tests because most test use a small repository and
therefor an inline revlog. In addition the bug only triggers when a
changelog read is done in the following "rare" situation:
- after some delayed write
- after that data have been written in a "divert" file (i.e. `00.changelog.i.a`)
- before transaction commit
- outside of a "writing" context
The issue was introduced in d83d788590a8
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 06 Dec 2023 16:29:43 +0100 |
parents | 66417f55ea33 |
children | 77b86226dde2 dcaa2df1f688 |
comparison
equal
deleted
inserted
replaced
51142:66417f55ea33 | 51143:849745d7da89 |
---|---|
1164 # delay or divert already in place | 1164 # delay or divert already in place |
1165 return None | 1165 return None |
1166 elif len(self.index) == 0: | 1166 elif len(self.index) == 0: |
1167 self._orig_index_file = self.index_file | 1167 self._orig_index_file = self.index_file |
1168 self.index_file = self._divert_index() | 1168 self.index_file = self._divert_index() |
1169 self._segmentfile.filename = self.index_file | |
1170 assert self._orig_index_file is not None | 1169 assert self._orig_index_file is not None |
1171 assert self.index_file is not None | 1170 assert self.index_file is not None |
1172 if self.opener.exists(self.index_file): | 1171 if self.opener.exists(self.index_file): |
1173 self.opener.unlink(self.index_file) | 1172 self.opener.unlink(self.index_file) |
1174 return self.index_file | 1173 return self.index_file |
1200 self._segmentfile._delay_buffer = self._delay_buffer | 1199 self._segmentfile._delay_buffer = self._delay_buffer |
1201 else: | 1200 else: |
1202 assert self._segmentfile._delay_buffer is None | 1201 assert self._segmentfile._delay_buffer is None |
1203 self._orig_index_file = self.index_file | 1202 self._orig_index_file = self.index_file |
1204 self.index_file = pending_index_file | 1203 self.index_file = pending_index_file |
1205 self._segmentfile.filename = self.index_file | |
1206 return self.index_file, any_pending | 1204 return self.index_file, any_pending |
1207 | 1205 |
1208 def finalize_pending(self): | 1206 def finalize_pending(self): |
1209 assert not self.is_open | 1207 assert not self.is_open |
1210 | 1208 |
1226 self._orig_index_file, | 1224 self._orig_index_file, |
1227 checkambig=True, | 1225 checkambig=True, |
1228 ) | 1226 ) |
1229 self.index_file = self._orig_index_file | 1227 self.index_file = self._orig_index_file |
1230 self._orig_index_file = None | 1228 self._orig_index_file = None |
1231 self._segmentfile.filename = self.index_file | |
1232 else: | 1229 else: |
1233 msg = b"not delay or divert found on this revlog" | 1230 msg = b"not delay or divert found on this revlog" |
1234 raise error.ProgrammingError(msg) | 1231 raise error.ProgrammingError(msg) |
1235 return self.canonical_index_file | 1232 return self.canonical_index_file |
1236 | 1233 |