repo: Port hardlink-scanning code to fd-relative calls
Continuing the migration.
This commit is contained in:
parent
6e0d92db00
commit
488efac728
2
libglnx
2
libglnx
|
|
@ -1 +1 @@
|
||||||
Subproject commit c1ae7ce1bf9c9175b26d1d933757503a0cc368e3
|
Subproject commit 162d1f6b58c9b501f47080e99aa1fd36864a89f9
|
||||||
|
|
@ -842,65 +842,58 @@ devino_equal (gconstpointer a,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
scan_loose_devino (OstreeRepo *self,
|
scan_one_loose_devino (OstreeRepo *self,
|
||||||
|
int object_dir_fd,
|
||||||
GHashTable *devino_cache,
|
GHashTable *devino_cache,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
guint i;
|
int res;
|
||||||
OstreeRepoMode repo_mode;
|
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||||
gs_unref_ptrarray GPtrArray *object_dirs = NULL;
|
|
||||||
|
|
||||||
if (self->parent_repo)
|
if (!glnx_dirfd_iterator_init_at (object_dir_fd, ".", FALSE,
|
||||||
{
|
&dfd_iter, error))
|
||||||
if (!scan_loose_devino (self->parent_repo, devino_cache, cancellable, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
repo_mode = ostree_repo_get_mode (self);
|
|
||||||
|
|
||||||
if (!_ostree_repo_get_loose_object_dirs (self, &object_dirs, cancellable, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
for (i = 0; i < object_dirs->len; i++)
|
|
||||||
{
|
|
||||||
GFile *objdir = object_dirs->pdata[i];
|
|
||||||
gs_unref_object GFileEnumerator *enumerator = NULL;
|
|
||||||
gs_unref_object GFileInfo *file_info = NULL;
|
|
||||||
const char *dirname;
|
|
||||||
|
|
||||||
enumerator = g_file_enumerate_children (objdir, OSTREE_GIO_FAST_QUERYINFO,
|
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
||||||
cancellable,
|
|
||||||
error);
|
|
||||||
if (!enumerator)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
dirname = gs_file_get_basename_cached (objdir);
|
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
const char *name;
|
struct dirent *dent;
|
||||||
const char *dot;
|
g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, };
|
||||||
guint32 type;
|
|
||||||
OstreeDevIno *key;
|
|
||||||
GString *checksum;
|
|
||||||
gboolean skip;
|
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (enumerator, &file_info, NULL,
|
if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
|
||||||
NULL, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
|
||||||
|
if (dent == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
|
/* All object directories only have two character entries */
|
||||||
type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
|
if (strlen (dent->d_name) != 2)
|
||||||
|
|
||||||
if (type == G_FILE_TYPE_DIRECTORY)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (repo_mode)
|
if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE,
|
||||||
|
&child_dfd_iter, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
OstreeDevIno *key;
|
||||||
|
struct dirent *child_dent;
|
||||||
|
const char *dot;
|
||||||
|
GString *checksum;
|
||||||
|
gboolean skip;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
if (!glnx_dirfd_iterator_next_dent (&child_dfd_iter, &child_dent, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (child_dent == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
name = child_dent->d_name;
|
||||||
|
|
||||||
|
switch (self->mode)
|
||||||
{
|
{
|
||||||
case OSTREE_REPO_MODE_ARCHIVE_Z2:
|
case OSTREE_REPO_MODE_ARCHIVE_Z2:
|
||||||
case OSTREE_REPO_MODE_BARE:
|
case OSTREE_REPO_MODE_BARE:
|
||||||
|
|
@ -916,15 +909,25 @@ scan_loose_devino (OstreeRepo *self,
|
||||||
dot = strrchr (name, '.');
|
dot = strrchr (name, '.');
|
||||||
g_assert (dot);
|
g_assert (dot);
|
||||||
|
|
||||||
|
/* Skip anything that doesn't look like a 64 character checksum */
|
||||||
if ((dot - name) != 62)
|
if ((dot - name) != 62)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
checksum = g_string_new (dirname);
|
do
|
||||||
|
res = fstatat (child_dfd_iter.fd, child_dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW);
|
||||||
|
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||||
|
if (res == -1)
|
||||||
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum = g_string_new (dent->d_name);
|
||||||
g_string_append_len (checksum, name, 62);
|
g_string_append_len (checksum, name, 62);
|
||||||
|
|
||||||
key = g_new (OstreeDevIno, 1);
|
key = g_new (OstreeDevIno, 1);
|
||||||
key->dev = g_file_info_get_attribute_uint32 (file_info, "unix::device");
|
key->dev = stbuf.st_dev;
|
||||||
key->ino = g_file_info_get_attribute_uint64 (file_info, "unix::inode");
|
key->ino = stbuf.st_ino;
|
||||||
|
|
||||||
g_hash_table_replace (devino_cache, key, g_string_free (checksum, FALSE));
|
g_hash_table_replace (devino_cache, key, g_string_free (checksum, FALSE));
|
||||||
}
|
}
|
||||||
|
|
@ -935,6 +938,36 @@ scan_loose_devino (OstreeRepo *self,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
scan_loose_devino (OstreeRepo *self,
|
||||||
|
GHashTable *devino_cache,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
if (self->parent_repo)
|
||||||
|
{
|
||||||
|
if (!scan_loose_devino (self->parent_repo, devino_cache, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
|
||||||
|
{
|
||||||
|
if (!scan_one_loose_devino (self, self->uncompressed_objects_dir_fd, devino_cache,
|
||||||
|
cancellable, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scan_one_loose_devino (self, self->objects_dir_fd,
|
||||||
|
devino_cache, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
devino_cache_lookup (OstreeRepo *self,
|
devino_cache_lookup (OstreeRepo *self,
|
||||||
guint32 device,
|
guint32 device,
|
||||||
|
|
@ -1096,6 +1129,7 @@ rename_pending_loose_objects (OstreeRepo *self,
|
||||||
if (!S_ISDIR (stbuf.st_mode))
|
if (!S_ISDIR (stbuf.st_mode))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* All object directories only have two character entries */
|
||||||
if (strlen (dent->d_name) != 2)
|
if (strlen (dent->d_name) != 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,12 +112,6 @@ _ostree_repo_has_loose_object (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
gboolean
|
|
||||||
_ostree_repo_get_loose_object_dirs (OstreeRepo *self,
|
|
||||||
GPtrArray **out_object_dirs,
|
|
||||||
GCancellable *cancellable,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_write_directory_meta (OstreeRepo *self,
|
_ostree_repo_write_directory_meta (OstreeRepo *self,
|
||||||
GFileInfo *file_info,
|
GFileInfo *file_info,
|
||||||
|
|
|
||||||
|
|
@ -1511,89 +1511,6 @@ ostree_repo_get_parent (OstreeRepo *self)
|
||||||
return self->parent_repo;
|
return self->parent_repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
append_object_dirs_from (OstreeRepo *self,
|
|
||||||
GFile *dir,
|
|
||||||
GPtrArray *object_dirs,
|
|
||||||
GCancellable *cancellable,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
GError *temp_error = NULL;
|
|
||||||
gs_unref_object GFileEnumerator *enumerator = NULL;
|
|
||||||
|
|
||||||
enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
|
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
||||||
cancellable,
|
|
||||||
&temp_error);
|
|
||||||
if (!enumerator)
|
|
||||||
{
|
|
||||||
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
|
||||||
{
|
|
||||||
g_clear_error (&temp_error);
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_propagate_error (error, temp_error);
|
|
||||||
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
GFileInfo *file_info;
|
|
||||||
const char *name;
|
|
||||||
guint32 type;
|
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (enumerator, &file_info, NULL,
|
|
||||||
NULL, error))
|
|
||||||
goto out;
|
|
||||||
if (file_info == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
|
|
||||||
type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
|
|
||||||
|
|
||||||
if (strlen (name) == 2 && type == G_FILE_TYPE_DIRECTORY)
|
|
||||||
{
|
|
||||||
GFile *objdir = g_file_get_child (g_file_enumerator_get_container (enumerator), name);
|
|
||||||
g_ptr_array_add (object_dirs, objdir); /* transfer ownership */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = TRUE;
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
_ostree_repo_get_loose_object_dirs (OstreeRepo *self,
|
|
||||||
GPtrArray **out_object_dirs,
|
|
||||||
GCancellable *cancellable,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
gs_unref_ptrarray GPtrArray *ret_object_dirs = NULL;
|
|
||||||
|
|
||||||
ret_object_dirs = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
|
|
||||||
|
|
||||||
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_ARCHIVE_Z2)
|
|
||||||
{
|
|
||||||
if (!append_object_dirs_from (self, self->uncompressed_objects_dir, ret_object_dirs,
|
|
||||||
cancellable, error))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!append_object_dirs_from (self, self->objects_dir, ret_object_dirs,
|
|
||||||
cancellable, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = TRUE;
|
|
||||||
ot_transfer_out_value (out_object_dirs, &ret_object_dirs);
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
list_loose_objects_at (OstreeRepo *self,
|
list_loose_objects_at (OstreeRepo *self,
|
||||||
GHashTable *inout_objects,
|
GHashTable *inout_objects,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue