Skip to content

Commit

Permalink
repo/checkout: Verify early if src/destination are on same device
Browse files Browse the repository at this point in the history
At least in all Linux kernels up to today, one can never `link()` across
devices, so we might as well verify that up front. This will help for a future
patch to add a new type of union-add checkout, since Linux checks for `EEXIST`
before `EXDEV`.
  • Loading branch information
cgwalters committed Mar 6, 2017
1 parent 3219a5d commit 1aaf7d5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
21 changes: 21 additions & 0 deletions src/libostree/ostree-repo-checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,8 @@ checkout_tree_at (OstreeRepo *self,
gboolean did_exist = FALSE;
glnx_fd_close int destination_dfd = -1;
int res;
struct stat repo_dfd_stat;
struct stat destination_stat;
g_autoptr(GVariant) xattrs = NULL;
g_autoptr(GFileEnumerator) dir_enum = NULL;

Expand All @@ -666,6 +668,25 @@ checkout_tree_at (OstreeRepo *self,
&destination_dfd, error))
goto out;

if (fstat (self->repo_dir_fd, &repo_dfd_stat) < 0)
{
glnx_set_error_from_errno (error);
goto out;
}
if (fstat (destination_dfd, &destination_stat) < 0)
{
glnx_set_error_from_errno (error);
goto out;
}

if (options->no_copy_fallback && repo_dfd_stat.st_dev != destination_stat.st_dev)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Unable to do hardlink checkout across devices (src=%lu destination=%lu)",
repo_dfd_stat.st_dev, destination_stat.st_dev);
goto out;
}

/* Set the xattrs now, so any derived labeling works */
if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
{
Expand Down
2 changes: 1 addition & 1 deletion tests/test-rofiles-fuse.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ assert_file_has_content mnt/test2-checkout-copy-fallback/anewfile-for-fuse anewf
if ${CMD_PREFIX} ostree --repo=repo checkout -UH test2 mnt/test2-checkout-copy-hardlinked 2>err.txt; then
assert_not_reached "Checking out via hardlinks across mountpoint unexpectedly succeeded!"
fi
assert_file_has_content err.txt "Invalid cross-device link"
assert_file_has_content err.txt "Unable to do hardlink checkout across devices"

echo "ok checkout copy fallback"

0 comments on commit 1aaf7d5

Please sign in to comment.