mirror of
https://github.com/ostreedev/ostree.git
synced 2025-03-19 22:50:35 +03:00
lib/repo: Separate min-free-space-* calculation from transaction codepath
Earlier, the actual reserved space (in blocks) were calculated inside the transaction codepath ostree_repo_prepare_transaction(). However, while reworking on ostree_repo_get_min_free_space_bytes() API, it was realized that this calculation can be done independently from the transaction's codepaths, hence enabling the usage for ostree_repo_get_min_free_space_bytes() API irrespective of whether there is an ongoing transaction or not. https://github.com/ostreedev/ostree/issues/1720 Closes: #1722 Approved by: pwithnall
This commit is contained in:
parent
fc84fb402c
commit
a0937b6cf0
@ -1536,30 +1536,6 @@ devino_cache_lookup (OstreeRepo *self,
|
||||
return dev_ino_val->checksum;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
min_free_space_calculate_reserved_blocks (OstreeRepo *self, struct statvfs *stvfsbuf, GError **error)
|
||||
{
|
||||
self->reserved_blocks = 0;
|
||||
|
||||
if (self->min_free_space_mb > 0)
|
||||
{
|
||||
if (self->min_free_space_mb > (G_MAXUINT64 >> 20) ||
|
||||
self->txn.blocksize > (1 << 20))
|
||||
return glnx_throw (error, "min-free-space value is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes",
|
||||
G_MAXUINT64 / stvfsbuf->f_bsize);
|
||||
|
||||
self->reserved_blocks = (self->min_free_space_mb << 20) / self->txn.blocksize;
|
||||
}
|
||||
else if (self->min_free_space_percent > 0)
|
||||
{
|
||||
/* Convert fragment to blocks to compute the total */
|
||||
guint64 total_blocks = (stvfsbuf->f_frsize * stvfsbuf->f_blocks) / stvfsbuf->f_bsize;
|
||||
self->reserved_blocks = ((double)total_blocks) * (self->min_free_space_percent/100.0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_scan_hardlinks:
|
||||
* @self: An #OstreeRepo
|
||||
@ -1631,6 +1607,7 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(_OstreeRepoAutoTransaction) txn = NULL;
|
||||
guint64 reserved_bytes = 0;
|
||||
|
||||
g_return_val_if_fail (self->in_transaction == FALSE, FALSE);
|
||||
|
||||
@ -1655,11 +1632,12 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
|
||||
|
||||
g_mutex_lock (&self->txn_lock);
|
||||
self->txn.blocksize = stvfsbuf.f_bsize;
|
||||
if (!min_free_space_calculate_reserved_blocks (self, &stvfsbuf, error))
|
||||
if (!ostree_repo_get_min_free_space_bytes (self, &reserved_bytes, error))
|
||||
{
|
||||
g_mutex_unlock (&self->txn_lock);
|
||||
return FALSE;
|
||||
}
|
||||
self->reserved_blocks = reserved_bytes / self->txn.blocksize;
|
||||
|
||||
/* Use the appropriate free block count if we're unprivileged */
|
||||
guint64 bfree = (getuid () != 0 ? stvfsbuf.f_bavail : stvfsbuf.f_bfree);
|
||||
|
@ -2655,6 +2655,37 @@ get_remotes_d_dir (OstreeRepo *self,
|
||||
return g_file_resolve_relative_path (sysroot, SYSCONF_REMOTES);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
min_free_space_calculate_reserved_bytes (OstreeRepo *self, guint64 *bytes, GError **error)
|
||||
{
|
||||
guint64 reserved_bytes = 0;
|
||||
|
||||
struct statvfs stvfsbuf;
|
||||
if (TEMP_FAILURE_RETRY (fstatvfs (self->repo_dir_fd, &stvfsbuf)) < 0)
|
||||
return glnx_throw_errno_prefix (error, "fstatvfs");
|
||||
|
||||
if (self->min_free_space_mb > 0)
|
||||
{
|
||||
if (self->min_free_space_mb > (G_MAXUINT64 >> 20))
|
||||
return glnx_throw (error, "min-free-space value is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes",
|
||||
(G_MAXUINT64 >> 20));
|
||||
|
||||
reserved_bytes = self->min_free_space_mb << 20;
|
||||
}
|
||||
else if (self->min_free_space_percent > 0)
|
||||
{
|
||||
if (stvfsbuf.f_frsize > (G_MAXUINT64 / stvfsbuf.f_blocks))
|
||||
return glnx_throw (error, "Filesystem's size is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes",
|
||||
(G_MAXUINT64 / stvfsbuf.f_blocks));
|
||||
|
||||
guint64 total_bytes = (stvfsbuf.f_frsize * stvfsbuf.f_blocks);
|
||||
reserved_bytes = ((double)total_bytes) * (self->min_free_space_percent/100.0);
|
||||
}
|
||||
|
||||
*bytes = reserved_bytes;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
min_free_space_size_validate_and_convert (OstreeRepo *self,
|
||||
const char *min_free_space_size_str,
|
||||
@ -3297,21 +3328,25 @@ ostree_repo_get_mode (OstreeRepo *self)
|
||||
/**
|
||||
* ostree_repo_get_min_free_space:
|
||||
* @self: Repo
|
||||
* @out_reserved_bytes: (out): Location to store the result
|
||||
* @error: Return location for a #GError
|
||||
*
|
||||
* It should be noted that this function should be used only if there
|
||||
* is a transaction active. It is a programmer error to request it
|
||||
* otherwise.
|
||||
* It can be used to query the value (in bytes) of min-free-space-* config option.
|
||||
*
|
||||
* Returns: Value (in bytes) of min-free-space-* config option
|
||||
* Returns: %TRUE on success, %FALSE otherwise.
|
||||
* Since: 2018.9
|
||||
*/
|
||||
guint64
|
||||
ostree_repo_get_min_free_space_bytes (OstreeRepo *self)
|
||||
gboolean
|
||||
ostree_repo_get_min_free_space_bytes (OstreeRepo *self, guint64 *out_reserved_bytes, GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_REPO (self), 0);
|
||||
g_return_val_if_fail (self->in_transaction == TRUE, 0);
|
||||
g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE);
|
||||
g_return_val_if_fail (out_reserved_bytes != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
return self->reserved_blocks * self->txn.blocksize;
|
||||
if (!min_free_space_calculate_reserved_bytes (self, out_reserved_bytes, error))
|
||||
return glnx_prefix_error (error, "Error calculating min-free-space bytes");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +128,9 @@ _OSTREE_PUBLIC
|
||||
OstreeRepoMode ostree_repo_get_mode (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
guint64 ostree_repo_get_min_free_space_bytes (OstreeRepo *self);
|
||||
gboolean ostree_repo_get_min_free_space_bytes (OstreeRepo *self,
|
||||
guint64 *out_reserved_bytes,
|
||||
GError **error);
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile * ostree_repo_get_config (OstreeRepo *self);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user