Skip to content

Conversation

@ThomasWaldmann
Copy link
Member

A pre-existing directory might be a btrfs subvolume that was created by the user ahead of time when restoring several nested subvolumes from a single archive.

If the archive item to be extracted is a directory and there is already a directory at the destination path, do not remove (and recreate) it, but just use it.

That way, btrfs subvolumes (which look like directories) are not deleted.

Fix originally contributed by @intelfx in #7866, but needed more work, so I thought more about the implications and added a test.

Note:

In the past, we first removed (empty) directories, then created a fresh one, then called restore_attrs for that. That produced correct metadata, but only for the case of an EMPTY exisiting directory. If the existing directory was not empty, the simply os.rmdir we tried did not work anyway and did not remove the existing directory.

Usually we extract to an empty base directory, thus encountering this edge case is mostly limited to continuing a previous extraction. In that case, calling restore_attrs again on a directory that already has existing attrs should be harmless, because they are identical.

@ThomasWaldmann
Copy link
Member Author

ThomasWaldmann commented Feb 8, 2026

TODO: Maybe same_item could be extended to consider directories.

That would avoid any potential issues with calling restore_attrs on directories that already have metadata.

Also it would speed up continuing an extraction.

@ThomasWaldmann ThomasWaldmann force-pushed the directory-extraction-master branch from 03f0347 to fdfb856 Compare February 8, 2026 08:44
@codecov
Copy link

codecov bot commented Feb 8, 2026

Codecov Report

❌ Patch coverage is 70.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.89%. Comparing base (37fbe3f) to head (9a43efa).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/borg/archive.py 70.00% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9288      +/-   ##
==========================================
- Coverage   75.89%   75.89%   -0.01%     
==========================================
  Files          86       86              
  Lines       14761    14767       +6     
  Branches     2198     2200       +2     
==========================================
+ Hits        11203    11207       +4     
- Misses       2884     2885       +1     
- Partials      674      675       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ThomasWaldmann ThomasWaldmann force-pushed the directory-extraction-master branch from 8db7b98 to 73a5241 Compare February 9, 2026 21:03
…up#4233

A pre-existing directory might be a btrfs subvolume that was created by
the user ahead of time when restoring several nested subvolumes from a
single archive.

If the archive item to be extracted is a directory and there is already
a directory at the destination path, do not remove (and recreate) it,
but just use it.

That way, btrfs subvolumes (which look like directories) are not deleted.

Fix originally contributed by @intelfx in borgbackup#7866, but needed more work,
so I thought more about the implications and added a test.

Note:

In the past, we first removed (empty) directories, then created a fresh
one, then called restore_attrs for that. That produced correct metadata,
but only for the case of an EMPTY exisiting directory. If the existing
directory was not empty, the simply os.rmdir we tried did not work
anyway and did not remove the existing directory.

Usually we extract to an empty base directory, thus encountering this
edge case is mostly limited to continuing a previous extraction.
In that case, calling restore_attrs again on a directory that already has
existing attrs should be harmless, because they are identical.
if an already existing fs directory has the correct (as archived) mtime,
we have already extracted it in a previous borg extract run and we do not
need and should not call restore_attrs for it again.

if the directory exists, but does not have the correct mtime, restore_attrs
will be called and its attributes will be extracted (and mtime set to
correct value).
@ThomasWaldmann ThomasWaldmann force-pushed the directory-extraction-master branch from 73a5241 to 9a43efa Compare February 9, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant