lib/repo: Enforce min-free-space-* size check for regfiles in deltas
authorUmang Jain <umang@endlessm.com>
Tue, 19 Jun 2018 20:52:12 +0000 (02:22 +0530)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 22 Jun 2018 21:01:56 +0000 (21:01 +0000)
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

index 7e1d707b36a830b3e5e337fe7dcfe44a9c29e568..2516ba3d5c81ab6ece56159c8926dd75f9b853bf 100644 (file)
@@ -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 &&