diff options
author | Simon Rettberg | 2018-06-25 15:57:50 +0200 |
---|---|---|
committer | Simon Rettberg | 2018-06-25 15:57:50 +0200 |
commit | b4c1fe882758c077fc9bd48599653b147dae3c8a (patch) | |
tree | 7c6aa29e51523069e52cd3f255acb3fe3777ce8b /src/server/uplink.c | |
parent | [SERVER] Make sure image has read fd before reading (diff) | |
download | dnbd3-b4c1fe882758c077fc9bd48599653b147dae3c8a.tar.gz dnbd3-b4c1fe882758c077fc9bd48599653b147dae3c8a.tar.xz dnbd3-b4c1fe882758c077fc9bd48599653b147dae3c8a.zip |
[SERVER] Try to re-open cacheFd if writing fails
In scenarios where the proxy is using an NFS server as
storage (for whatever crazy reason) or when the cacheFd
goes bad through e.g. a switchroot, try to re-open it
instead of just disabling caching forever.
Diffstat (limited to 'src/server/uplink.c')
-rw-r--r-- | src/server/uplink.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/server/uplink.c b/src/server/uplink.c index debd091..8a6a33a 100644 --- a/src/server/uplink.c +++ b/src/server/uplink.c @@ -594,9 +594,12 @@ static void uplink_handleReceive(dnbd3_connection_t *link) link->bytesReceived += inReply.size; spin_unlock( &link->image->lock ); // 1) Write to cache file + if ( link->image->cacheFd == -1 ) { + image_reopenCacheFd( link->image, false ); + } if ( link->image->cacheFd != -1 ) { int err = 0; - bool tryFree = true; + bool tryAgain = true; // Allow one retry in case we run out of space or the write fd became invalid uint32_t done = 0; ret = 0; while ( done < inReply.size ) { @@ -606,10 +609,16 @@ static void uplink_handleReceive(dnbd3_connection_t *link) if ( err == EINTR ) continue; if ( err == ENOSPC || err == EDQUOT ) { // try to free 256MiB - if ( !tryFree || !image_ensureDiskSpaceLocked( 256ull * 1024 * 1024, true ) ) break; - tryFree = false; + if ( !tryAgain || !image_ensureDiskSpaceLocked( 256ull * 1024 * 1024, true ) ) break; + tryAgain = false; continue; // Success, retry write } + if ( err == EBADF || err == EINVAL || err == EIO ) { + if ( !tryAgain || !image_reopenCacheFd( link->image, true ) ) + break; + tryAgain = false; + continue; // Write handle to image successfully re-opened, try again + } logadd( LOG_DEBUG1, "Error trying to cache data for %s:%d -- errno=%d", link->image->name, (int)link->image->rid, err ); break; } @@ -624,9 +633,6 @@ static void uplink_handleReceive(dnbd3_connection_t *link) // Only disable caching if something seems severely wrong, not on ENOSPC since that might get better logadd( LOG_WARNING, "Error writing received data for %s:%d; disabling caching.", link->image->name, (int)link->image->rid ); - const int fd = link->image->cacheFd; - link->image->cacheFd = -1; - close( fd ); } } // 2) Figure out which clients are interested in it |