From 095376efa2ecaf538246cf2e3979a9606afdea5f Mon Sep 17 00:00:00 2001 From: Umang Jain Date: Wed, 20 Jun 2018 02:22:12 +0530 Subject: [PATCH] lib/repo: Enforce min-free-space-* size check for regfiles in deltas During the pull, there is an explicit check for free space on disk vs. the size of uncompressed delta; But while writing the new content objects that are generated, they have to honor min-free-space-* checks too. We enforce this check in _bare_content_commit as that is where we can know the final size of the new content object. Closes: #1614 Approved by: jlebon --- src/libostree/ostree-repo-commit.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 7e1d707b..2516ba3d 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -509,6 +509,33 @@ _ostree_repo_bare_content_commit (OstreeRepo *self, { OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent*) barewrite; g_assert (real->initialized); + + if ((self->min_free_space_percent > 0 || self->min_free_space_mb > 0) && self->in_transaction) + { + struct stat st_buf; + if (!glnx_fstat (real->tmpf.fd, &st_buf, error)) + return FALSE; + + g_mutex_lock (&self->txn_lock); + g_assert_cmpint (self->txn.blocksize, >, 0); + + const fsblkcnt_t object_blocks = (st_buf.st_size / self->txn.blocksize) + 1; + if (object_blocks > self->txn.max_blocks) + { + g_mutex_unlock (&self->txn_lock); + g_autofree char *formatted_required = g_format_size (st_buf.st_size); + if (self->min_free_space_percent > 0) + return glnx_throw (error, "min-free-space-percent '%u%%' would be exceeded, %s more required", + self->min_free_space_percent, formatted_required); + else + return glnx_throw (error, "min-free-space-size %luMB woulid be exceeded, %s more required", + self->min_free_space_mb, formatted_required); + } + /* This is the main bit that needs mutex protection */ + self->txn.max_blocks -= object_blocks; + g_mutex_unlock (&self->txn_lock); + } + ot_checksum_get_hexdigest (&real->checksum, checksum_buf, buflen); if (real->expected_checksum &&