D6867: transaction: detect an attempt to truncate-to-extend on playback, raise error
spectral (Kyle Lippincott)
phabricator at mercurial-scm.org
Tue Sep 17 18:58:40 EDT 2019
spectral created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
On some networked filesystems, writes can have delayed finalization/confirmation
and write races can occur such that a remote modification will "win" and
modifications will be lost. There is no functionality for providing this
feedback to userspace programs (in fact, there's not even functionality for
providing this information to the Linux kernel...), so these programs may see
the files suddenly change.
We've noticed that there have been cases where Mercurial has detected something
has gone wrong and attempts to abort (rolling back the transaction), which is
good. However, when rolling back the transaction, for the append-only files,
we attempt to "truncate" the file back to the size it was in before the hg
transaction started, but end up *extending* it. This may be harmless, but if
this happens to the 00changelog.i file, we get a bunch of nulls on the end of
the file and this causes hg to become *really* confused. :)
If we detect that some modification of the file outside of this Mercurial
process has caused the file to be smaller than the size we are attempting to
truncate to, let's just exit and stop trying to clean up the repository -
continuing will likely just cause more damage.
diff --git a/mercurial/transaction.py b/mercurial/transaction.py
@@ -54,6 +54,10 @@
checkambig = checkambigfiles and (f, '') in checkambigfiles
fp = opener(f, 'a', checkambig=checkambig)
+ if fp.tell() < o:
+ raise error.Abort(_(
+ "attempted to truncate %s to %d bytes, but it was "
+ "already %d bytes\n") % (f, o, fp.tell()))
To: spectral, #hg-reviewers
More information about the Mercurial-devel