mirror of
https://github.com/ostreedev/ostree.git
synced 2025-03-19 22:50:35 +03:00
core: pack: Keep loose objects which are referenced externally
By default, don't delete loose objects which have hard links. This has the natural semantics that if you delete all the checkouts, you probably want it packed. Conversely, if it has a hard link, we do want further checkouts to share storage, even if we pack in between them.
This commit is contained in:
parent
d8b97316d9
commit
f33a2f9a08
@ -37,7 +37,8 @@
|
||||
static gboolean opt_analyze_only;
|
||||
static gboolean opt_metadata_only;
|
||||
static gboolean opt_reindex_only;
|
||||
static gboolean opt_keep_loose;
|
||||
static gboolean opt_delete_all_loose;
|
||||
static gboolean opt_keep_all_loose;
|
||||
static char* opt_pack_size;
|
||||
static char* opt_int_compression;
|
||||
static char* opt_ext_compression;
|
||||
@ -55,7 +56,8 @@ static GOptionEntry options[] = {
|
||||
{ "metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_metadata_only, "Only pack metadata objects", NULL },
|
||||
{ "analyze-only", 0, 0, G_OPTION_ARG_NONE, &opt_analyze_only, "Just analyze current state", NULL },
|
||||
{ "reindex-only", 0, 0, G_OPTION_ARG_NONE, &opt_reindex_only, "Regenerate pack index", NULL },
|
||||
{ "keep-loose", 0, 0, G_OPTION_ARG_NONE, &opt_keep_loose, "Don't delete loose objects", NULL },
|
||||
{ "delete-all-loose", 0, 0, G_OPTION_ARG_NONE, &opt_delete_all_loose, "Delete all loose objects (default: delete unreferenced loose)", NULL },
|
||||
{ "keep-all-loose", 0, 0, G_OPTION_ARG_NONE, &opt_keep_all_loose, "Don't delete any loose objects (default: delete unreferenced loose)", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -191,32 +193,74 @@ delete_loose_object (OtRepackData *data,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gboolean do_delete = FALSE;
|
||||
GError *temp_error = NULL;
|
||||
ot_lobj GFile *object_path = NULL;
|
||||
ot_lobj GFile *file_content_object_path = NULL;
|
||||
ot_lvariant GVariant *archive_meta = NULL;
|
||||
ot_lobj GFileInfo *file_info = NULL;
|
||||
ot_lvariant GVariant *xattrs = NULL;
|
||||
|
||||
object_path = ostree_repo_get_object_path (data->repo, checksum, objtype);
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
ot_lobj GFileInfo *file_info = NULL;
|
||||
|
||||
if (ostree_repo_get_mode (data->repo) == OSTREE_REPO_MODE_BARE)
|
||||
{
|
||||
file_info = g_file_query_info (object_path, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, &temp_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
ot_lobj GFile *content_object_path = NULL;
|
||||
|
||||
content_object_path = ostree_repo_get_archive_content_path (data->repo, checksum);
|
||||
|
||||
file_info = g_file_query_info (content_object_path, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, &temp_error);
|
||||
}
|
||||
|
||||
if (!ot_gfile_unlink (object_path, cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "Failed to delete archived file metadata '%s'",
|
||||
ot_gfile_get_path_cached (object_path));
|
||||
goto out;
|
||||
if (!file_info)
|
||||
{
|
||||
if (!g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_propagate_error (error, temp_error);
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_error (&temp_error);
|
||||
}
|
||||
}
|
||||
|
||||
do_delete = opt_delete_all_loose
|
||||
|| (file_info && g_file_info_get_attribute_uint32 (file_info, "unix::nlink") <= 1);
|
||||
}
|
||||
else
|
||||
do_delete = TRUE;
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE
|
||||
&& ostree_repo_get_mode (data->repo) == OSTREE_REPO_MODE_ARCHIVE)
|
||||
if (do_delete)
|
||||
{
|
||||
ot_lobj GFile *content_object_path = NULL;
|
||||
if (!ot_gfile_unlink (object_path, cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "Failed to delete loose object '%s'",
|
||||
ot_gfile_get_path_cached (object_path));
|
||||
goto out;
|
||||
}
|
||||
|
||||
content_object_path = ostree_repo_get_archive_content_path (data->repo, checksum);
|
||||
|
||||
/* Ignoring errors for now; later should only be trying to
|
||||
* delete files with content.
|
||||
*/
|
||||
(void) ot_gfile_unlink (object_path, NULL, NULL);
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE
|
||||
&& ostree_repo_get_mode (data->repo) == OSTREE_REPO_MODE_ARCHIVE)
|
||||
{
|
||||
ot_lobj GFile *content_object_path = NULL;
|
||||
|
||||
content_object_path = ostree_repo_get_archive_content_path (data->repo, checksum);
|
||||
|
||||
/* Ignoring errors for now; later should only be trying to
|
||||
* delete files with content.
|
||||
*/
|
||||
(void) ot_gfile_unlink (content_object_path, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
@ -475,7 +519,7 @@ create_pack_file (OtRepackData *data,
|
||||
|
||||
g_print ("Created pack file '%s' with %u objects\n", g_checksum_get_string (pack_checksum), objects->len);
|
||||
|
||||
if (!opt_keep_loose)
|
||||
if (!opt_keep_all_loose)
|
||||
{
|
||||
for (i = 0; i < objects->len; i++)
|
||||
{
|
||||
@ -484,11 +528,11 @@ create_pack_file (OtRepackData *data,
|
||||
guint32 objtype_u32;
|
||||
OstreeObjectType objtype;
|
||||
guint64 expected_objsize;
|
||||
|
||||
|
||||
g_variant_get (object_data, "(&sut)", &checksum, &objtype_u32, &expected_objsize);
|
||||
|
||||
|
||||
objtype = (OstreeObjectType) objtype_u32;
|
||||
|
||||
|
||||
if (!delete_loose_object (data, checksum, objtype, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user