Skip to content

Commit

Permalink
storage/reflink: start(): use hardlink for snap_on_start volume
Browse files Browse the repository at this point in the history
Now that the _path_clean file is never mutated - not even by resize() -
a hardlink can be used instead of a reflink to store a source volume's
_path_clean file in the consumer volume.

A reflink would take some time for large and/or fragmented volume files,
whereas a hardlink is practically free even in that case. This is also
going to allow a better approach for is_outdated().
  • Loading branch information
rustybird committed Feb 2, 2022
1 parent d9be540 commit 6515cae
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion qubes/storage/reflink.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,9 @@ def start(self): # pylint: disable=invalid-overridden-method
self._remove_incomplete_images()
if not self.is_dirty():
if self.snap_on_start:
_remove_file(self._path_clean)
# pylint: disable=protected-access
_copy_file(self.source._path_clean, self._path_clean)
_hardlink_file(self.source._path_clean, self._path_clean)
if self.snap_on_start or self.save_on_stop:
_copy_file(self._path_clean, self._path_dirty)
else:
Expand Down Expand Up @@ -366,6 +367,13 @@ def _replace_file(dst):
_remove_file = functools.partial(
qubes.utils.remove_file, log_level=logging.INFO)

def _hardlink_file(src, dst):
dst_dir = os.path.dirname(dst)
_create_dir(dst_dir)
os.link(src, dst)
qubes.utils.fsync_path(dst_dir)
LOGGER.info('Hardlinked file: %r -> %r', src, dst)

def _create_dir(path):
try:
created = False
Expand Down

0 comments on commit 6515cae

Please sign in to comment.