From fbe507151fc56ba23f875979b605b35296b95d2c Mon Sep 17 00:00:00 2001 From: Valentin David <valentin.david@codethink.co.uk> Date: Fri, 16 Nov 2018 15:28:45 +0100 Subject: [PATCH] "Fallocate" object disk space to avoid getting NOSPC error when writing This locks the temporary object file so that cleanup does not need to be done for every write. --- buildstream/_artifactcache/casserver.py | 31 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/buildstream/_artifactcache/casserver.py b/buildstream/_artifactcache/casserver.py index 56e61f9150..f636eb6b47 100644 --- a/buildstream/_artifactcache/casserver.py +++ b/buildstream/_artifactcache/casserver.py @@ -24,6 +24,8 @@ import signal import sys import tempfile import uuid +import errno +import ctypes import click import grpc @@ -190,17 +192,34 @@ class _ByteStreamServicer(bytestream_pb2_grpc.ByteStreamServicer): context.set_code(grpc.StatusCode.NOT_FOUND) return response - try: - _clean_up_cache(self.cas, client_digest.size_bytes) - except ArtifactTooLargeException as e: - context.set_code(grpc.StatusCode.RESOURCE_EXHAUSTED) - context.set_details(str(e)) - return response + while True: + if client_digest.size_bytes == 0: + break + try: + _clean_up_cache(self.cas, client_digest.size_bytes) + except ArtifactTooLargeException as e: + context.set_code(grpc.StatusCode.RESOURCE_EXHAUSTED) + context.set_details(str(e)) + return response + + try: + os.unix_fallocate(out.fileno(), 0, client_digest.size_bytes) + break + except OSError as e: + # Multiple upload can happen in the same time + if e.errno != errno.ENOSPC: + raise + elif request.resource_name: # If it is set on subsequent calls, it **must** match the value of the first request. if request.resource_name != resource_name: context.set_code(grpc.StatusCode.FAILED_PRECONDITION) return response + + if (offset + len(request.data)) > client_digest.size_bytes: + context.set_code(grpc.StatusCode.FAILED_PRECONDITION) + return response + out.write(request.data) offset += len(request.data) if request.finish_write: -- GitLab