Repository navigation
create: do not archive an atime we caused ourselves, fixes #6194 (1.4-maint) - #10577
Merged
ThomasWaldmann merged 2 commits intoNov 3, 2026
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 1.4-maint #10577 +/- ##
=============================================
+ Coverage 82.07% 82.19% +0.12%
=============================================
Files 38 38
Lines 11485 11524 +39
Branches 1810 1817 +7
=============================================
+ Hits 9426 9472 +46
+ Misses 1470 1467 -3
+ Partials 589 585 -4 ☔ View full report in Codecov by Harness. |
…#6194 borg has to open() a fs item before it can fstat() it. On platforms without O_NOATIME support (or when we are not allowed to use it), that open() may already have updated the atime - and then we would archive that atime instead of the one the item had before borg touched it. stat_update_check() now returns a stat result look-alike that has the atime from the stat we did before opening the item, if the atime changed between the two stat calls. If it did not change (e.g. O_NOATIME worked), the fd-based stat result is returned as before. (cherry picked from commit 51cc27e) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_test_files creates input/hardlink as a hard link to input/file1, so both share one inode and anything touching one of them also changes the atime of the other. That is not what test_atime is about, but it made the test fail on cygwin: At extraction time, borg creates the hard link via os.link(). On cygwin, os.link() updates the atime of the file it links to (at least if that file has the x bit set, as input/file1 has here). So it overwrote the atime borg had correctly restored for input/file1 just before and the test then saw "now" instead of the expected atime. Also, while backing up, borg has to open() input/file1 and that updates the atime of the shared inode. When borg then gets to input/hardlink, that already changed atime is what the stat before the open sees, so stat_update_check() can not recognize it as one we caused ourselves and archives it. The test does not look at input/hardlink, so this did not make it fail, but it is another reason why hardlinks and atime testing do not mix well. On cygwin, test_atime failed reliably before this and passes now. (cherry picked from commit 00fd667) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ThomasWaldmann
force-pushed
the
atime-open-6194-14
branch
from
November 3, 2026 20:50
11175a4 to
a70ccd1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #10111 to 1.4-maint, fixes #6194.
borg has to
open()a fs item before it canfstat()it. On platforms withoutO_NOATIMEsupport (or when we are not allowed to use it), that
open()may already have updated theatime - and then we archive an atime that we caused ourselves, instead of the one the item
had before borg touched it.
stat_update_check()now returns aos.stat_resultlook-alike (StatOrigAtime) that haseverything from the fd-based stat, but the atime from the stat done before opening the item.
This is only done if the atime actually changed between the two stat calls; otherwise the
plain stat result is returned as before.
2nd commit:
test_atimeno longer creates the hardlink (it shares the inode withinput/file1,which made the test fail on cygwin).
Differences from the master PR (1.4 test layout):
ArchiverTestCasemethods intestsuite/archiver.py;test_atime_open_updates_atimeis skipped inArchiverTestCaseBinary(it patches objects).stat_update_check()are intestsuite/archive.py, checkingst_birthtimeinstead of
st_birthtime_ns(not present on older Pythons).Testing (macOS, py3.14): the new tests fail without the fix and pass with it. Full suite:
1468 passed, 382 skipped, 2 failed (
test_unix_socket: "AF_UNIX path too long", caused by thelong tmp path of the local test setup, unrelated).
🤖 Generated with Claude Code