mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-23 21:35:26 +03:00
lib/repo: Always look in staging directory for objects
Its often the case that we want to look at objects inside a commit,
before the objects the transaction is finished. For instance:
https://github.com/flatpak/flatpak/pull/837
Which tries to verify the file permissions before committing the
transaction.
And:
1e5ffa926a
Which collects the storage size of the objects so that we can
put the total download size in the commit metadata.
I tried to find all the places where we did reads from the
object directories, and in particular this fixes:
- `ostree_repo_load_file()` for `bare` repos (`archive` was already working).
- `ostree_repo_query_object_storage_size()`
- Applying deltas that reference not-yet-commited objects
Closes: #916
Approved by: cgwalters
This commit is contained in:
parent
848b7c0201
commit
7159bed8e1
@ -2501,19 +2501,33 @@ load_metadata_internal (OstreeRepo *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Basically fstatat(), but also looks in both the committed and staging
|
||||
* directories, and returns *out_dfd for where we found the object.
|
||||
*/
|
||||
static gboolean
|
||||
query_info_for_bare_content_object (OstreeRepo *self,
|
||||
const char *loose_path_buf,
|
||||
GFileInfo **out_info,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
stat_bare_content_object (OstreeRepo *self,
|
||||
const char *loose_path_buf,
|
||||
int *out_dfd,
|
||||
GFileInfo **out_info,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
struct stat stbuf;
|
||||
int res;
|
||||
int dirfd;
|
||||
|
||||
if (TEMP_FAILURE_RETRY (fstatat (self->objects_dir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW)) < 0)
|
||||
dirfd = self->objects_dir_fd;
|
||||
res = TEMP_FAILURE_RETRY (fstatat (dirfd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW));
|
||||
if (res < 0 && errno == ENOENT && self->commit_stagedir_fd != -1)
|
||||
{
|
||||
dirfd = self->commit_stagedir_fd;
|
||||
res = TEMP_FAILURE_RETRY (fstatat (dirfd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW));
|
||||
}
|
||||
if (res < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
*out_dfd = -1;
|
||||
*out_info = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
@ -2528,13 +2542,14 @@ query_info_for_bare_content_object (OstreeRepo *self,
|
||||
}
|
||||
else if (S_ISLNK (stbuf.st_mode))
|
||||
{
|
||||
if (!ot_readlinkat_gfile_info (self->objects_dir_fd, loose_path_buf,
|
||||
if (!ot_readlinkat_gfile_info (dirfd, loose_path_buf,
|
||||
ret_info, cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return glnx_throw (error, "Not a regular file or symlink: %s", loose_path_buf);
|
||||
|
||||
*out_dfd = dirfd;
|
||||
ot_transfer_out_value (out_info, &ret_info);
|
||||
return TRUE;
|
||||
}
|
||||
@ -2575,6 +2590,12 @@ _ostree_repo_read_bare_fd (OstreeRepo *self,
|
||||
if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, out_fd, error))
|
||||
return FALSE;
|
||||
|
||||
if (*out_fd == -1 && self->commit_stagedir_fd != -1)
|
||||
{
|
||||
if (!ot_openat_ignore_enoent (self->commit_stagedir_fd, loose_path_buf, out_fd, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*out_fd == -1)
|
||||
{
|
||||
if (self->parent_repo)
|
||||
@ -2661,9 +2682,11 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!query_info_for_bare_content_object (self, loose_path_buf,
|
||||
&ret_file_info,
|
||||
cancellable, error))
|
||||
int objdir_fd; /* referenced */
|
||||
if (!stat_bare_content_object (self, loose_path_buf,
|
||||
&objdir_fd,
|
||||
&ret_file_info,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (ret_file_info)
|
||||
@ -2681,7 +2704,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||
* always do an open, then query the user.ostreemeta xattr for
|
||||
* more information.
|
||||
*/
|
||||
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||
fd = openat (objdir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return glnx_throw_errno (error);
|
||||
|
||||
@ -2735,7 +2758,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||
if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR &&
|
||||
out_input)
|
||||
{
|
||||
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||
fd = openat (objdir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return glnx_throw_errno (error);
|
||||
|
||||
@ -2759,7 +2782,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||
{
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||
fd = openat (objdir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return glnx_throw_errno (error);
|
||||
|
||||
@ -2783,7 +2806,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||
{
|
||||
if (self->disable_xattrs)
|
||||
ret_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0));
|
||||
else if (!glnx_dfd_name_get_all_xattrs (self->objects_dir_fd, loose_path_buf,
|
||||
else if (!glnx_dfd_name_get_all_xattrs (objdir_fd, loose_path_buf,
|
||||
&ret_xattrs,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
@ -3260,9 +3283,14 @@ ostree_repo_query_object_storage_size (OstreeRepo *self,
|
||||
{
|
||||
char loose_path[_OSTREE_LOOSE_PATH_MAX];
|
||||
_ostree_loose_path (loose_path, sha256, objtype, self->mode);
|
||||
int res;
|
||||
|
||||
struct stat stbuf;
|
||||
if (TEMP_FAILURE_RETRY (fstatat (self->objects_dir_fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW)) < 0)
|
||||
res = TEMP_FAILURE_RETRY (fstatat (self->objects_dir_fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW));
|
||||
if (res < 0 && errno == ENOENT && self->commit_stagedir_fd != -1)
|
||||
res = TEMP_FAILURE_RETRY (fstatat (self->commit_stagedir_fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW));
|
||||
|
||||
if (res < 0)
|
||||
return glnx_throw_errno_prefix (error, "Querying object %s.%s", sha256, ostree_object_type_to_string (objtype));
|
||||
|
||||
*out_size = stbuf.st_size;
|
||||
|
Loading…
Reference in New Issue
Block a user