From 09dbfb968c4ef469f4a43dad3b9818fd2ed4ef82 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 15 Mar 2018 22:03:36 +0100 Subject: [SERVER] Experimental support for sparse files in proxy mode Will not preallocate images in this mode. Old images are only deleted if the disk is full, determined by write() calls to the cache file yielding ENOSPC or EDQUOT. In such a case, the least recently used image(s) will be deleted to free up at least 256MiB, and then the write() call will be repeated. This *should* work somewhat reliably unless the cache partition is ridiculously small. Performance might suffer a little, and disk fragmentation might occur much faster than in prealloc mode. Testing is needed. --- src/server/uplink.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/server/uplink.c') diff --git a/src/server/uplink.c b/src/server/uplink.c index aec47cb..b166c6d 100644 --- a/src/server/uplink.c +++ b/src/server/uplink.c @@ -592,10 +592,19 @@ static void uplink_handleReceive(dnbd3_connection_t *link) spin_unlock( &link->image->lock ); // 1) Write to cache file if ( link->image->cacheFd != -1 ) { + bool tryFree = true; uint32_t done = 0; while ( done < inReply.size ) { ret = (int)pwrite( link->image->cacheFd, link->recvBuffer + done, inReply.size - done, start + done ); - if ( ret == -1 && errno == EINTR ) continue; + if ( ret == -1 ) { + if ( errno == EINTR ) continue; + if ( errno == ENOSPC || errno == EDQUOT ) { + // try to free 256MiB + if ( !tryFree || !image_ensureDiskSpaceLocked( 256ull * 1024 * 1024, true ) ) break; + tryFree = false; + continue; // Success, retry write + } + } if ( ret <= 0 ) break; done += (uint32_t)ret; } -- cgit v1.2.3-55-g7522