diff --git a/rhizome.c b/rhizome.c index a1178412..fda7971a 100644 --- a/rhizome.c +++ b/rhizome.c @@ -702,6 +702,7 @@ const char *rhizome_payload_status_message(enum rhizome_payload_status status) case RHIZOME_PAYLOAD_STATUS_WRONG_HASH: return "Payload hash contradicts manifest"; case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL: return "Incorrect bundle secret"; case RHIZOME_PAYLOAD_STATUS_ERROR: return "Internal error"; + case RHIZOME_PAYLOAD_STATUS_BUSY: return "busy storage"; } return NULL; } diff --git a/rhizome.h b/rhizome.h index 7abf63fd..3e2791f1 100644 --- a/rhizome.h +++ b/rhizome.h @@ -448,6 +448,7 @@ enum rhizome_payload_status { RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL = 5, // cannot encrypt/decrypt (payload key unknown) RHIZOME_PAYLOAD_STATUS_TOO_BIG = 6, // payload will never fit in our store RHIZOME_PAYLOAD_STATUS_EVICTED = 7, // other payloads in our store are more important + RHIZOME_PAYLOAD_STATUS_BUSY = 8, // storage is currently busy, you may try again at a later time }; // Useful for initialising a variable then checking later that it was set to a diff --git a/rhizome_cli.c b/rhizome_cli.c index 259483cb..125bb331 100644 --- a/rhizome_cli.c +++ b/rhizome_cli.c @@ -267,6 +267,10 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont result.status = RHIZOME_BUNDLE_STATUS_NO_ROOM; INFO("Insufficient space to store payload"); break; + case RHIZOME_PAYLOAD_STATUS_BUSY: + pstatus_valid = 1; + result.status = RHIZOME_BUNDLE_STATUS_BUSY; + break; case RHIZOME_PAYLOAD_STATUS_ERROR: pstatus_valid = 1; result.status = RHIZOME_BUNDLE_STATUS_ERROR; diff --git a/rhizome_direct_http.c b/rhizome_direct_http.c index a22a76b2..5b948071 100644 --- a/rhizome_direct_http.c +++ b/rhizome_direct_http.c @@ -716,6 +716,7 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r) goto pstatus_ok; case RHIZOME_PAYLOAD_STATUS_NEW: case RHIZOME_PAYLOAD_STATUS_ERROR: + case RHIZOME_PAYLOAD_STATUS_BUSY: case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE: case RHIZOME_PAYLOAD_STATUS_WRONG_HASH: case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL: diff --git a/rhizome_fetch.c b/rhizome_fetch.c index 35b8d38a..37deb5e3 100644 --- a/rhizome_fetch.c +++ b/rhizome_fetch.c @@ -548,6 +548,7 @@ schedule_fetch(struct rhizome_fetch_slot *slot) RETURN(DONOTWANT); case RHIZOME_PAYLOAD_STATUS_NEW: goto status_ok; + case RHIZOME_PAYLOAD_STATUS_BUSY: case RHIZOME_PAYLOAD_STATUS_ERROR: RETURN(WHY("error writing new payload")); case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE: diff --git a/rhizome_restful.c b/rhizome_restful.c index 928ae4a4..9e7e3cd6 100644 --- a/rhizome_restful.c +++ b/rhizome_restful.c @@ -156,6 +156,7 @@ static int http_request_rhizome_response(struct httpd_request *r, uint16_t http_ case RHIZOME_PAYLOAD_STATUS_WRONG_HASH: rhizome_http_status = 422; // Unprocessable Entity break; + case RHIZOME_PAYLOAD_STATUS_BUSY: case RHIZOME_PAYLOAD_STATUS_ERROR: rhizome_http_status = 500; break; @@ -749,6 +750,9 @@ static int restful_rhizome_insert_end(struct http_request *hr) case RHIZOME_PAYLOAD_STATUS_EVICTED: r->bundle_result = rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_NO_ROOM); return http_request_rhizome_response(r, 0, NULL); + case RHIZOME_PAYLOAD_STATUS_BUSY: + r->bundle_result = rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_BUSY); + return http_request_rhizome_response(r, 0, NULL); case RHIZOME_PAYLOAD_STATUS_ERROR: return http_request_rhizome_response(r, 500, "Payload store error"); } @@ -944,6 +948,7 @@ int rhizome_response_content_init_filehash(httpd_request *r, const rhizome_fileh case RHIZOME_PAYLOAD_STATUS_NEW: return http_request_rhizome_response(r, 404, "Payload not found"); case RHIZOME_PAYLOAD_STATUS_ERROR: + case RHIZOME_PAYLOAD_STATUS_BUSY: case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE: case RHIZOME_PAYLOAD_STATUS_WRONG_HASH: case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL: @@ -969,6 +974,7 @@ int rhizome_response_content_init_payload(httpd_request *r, rhizome_manifest *m) return http_request_rhizome_response(r, 404, "Payload not found"); case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL: return http_request_rhizome_response(r, 419, "Payload decryption error"); // Authentication Timeout + case RHIZOME_PAYLOAD_STATUS_BUSY: case RHIZOME_PAYLOAD_STATUS_ERROR: case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE: case RHIZOME_PAYLOAD_STATUS_WRONG_HASH: diff --git a/rhizome_store.c b/rhizome_store.c index 22b5ce86..7f907bf0 100644 --- a/rhizome_store.c +++ b/rhizome_store.c @@ -734,9 +734,8 @@ enum rhizome_payload_status rhizome_finish_write(struct rhizome_write *write) // flush out any remaining buffered pieces to disk if (write->buffer_list){ if (rhizome_random_write(write, 0, NULL, 0) || write->buffer_list) { - // TODO return busy? - WHYF("Failed to flush write buffer"); - status = RHIZOME_PAYLOAD_STATUS_ERROR; + INFOF("Failed to flush write buffer"); + status = RHIZOME_PAYLOAD_STATUS_BUSY; goto failure; } } @@ -879,7 +878,8 @@ dbfailure: sqlite_exec_void_retry(&retry, "ROLLBACK;", END); status = RHIZOME_PAYLOAD_STATUS_ERROR; failure: - rhizome_fail_write(write); + if (status != RHIZOME_PAYLOAD_STATUS_BUSY) + rhizome_fail_write(write); return status; } @@ -1017,6 +1017,7 @@ enum rhizome_payload_status rhizome_store_payload_file(rhizome_manifest *m, cons case RHIZOME_PAYLOAD_STATUS_NEW: status_ok = 1; break; + case RHIZOME_PAYLOAD_STATUS_BUSY: case RHIZOME_PAYLOAD_STATUS_STORED: case RHIZOME_PAYLOAD_STATUS_TOO_BIG: case RHIZOME_PAYLOAD_STATUS_EVICTED: @@ -1721,6 +1722,7 @@ enum rhizome_payload_status rhizome_write_open_journal(struct rhizome_write *wri case RHIZOME_PAYLOAD_STATUS_STORED: rstatus_valid = 1; break; + case RHIZOME_PAYLOAD_STATUS_BUSY: case RHIZOME_PAYLOAD_STATUS_ERROR: case RHIZOME_PAYLOAD_STATUS_TOO_BIG: rstatus_valid = 1; @@ -1778,6 +1780,7 @@ enum rhizome_payload_status rhizome_finish_store(struct rhizome_write *write, rh case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL: case RHIZOME_PAYLOAD_STATUS_EVICTED: case RHIZOME_PAYLOAD_STATUS_ERROR: + case RHIZOME_PAYLOAD_STATUS_BUSY: status_valid = 1; rhizome_fail_write(write); return status;