diff --git a/rhizome.h b/rhizome.h index 6c73c5a5..9d24ce8a 100644 --- a/rhizome.h +++ b/rhizome.h @@ -262,6 +262,7 @@ rhizome_manifest *_rhizome_new_manifest(struct __sourceloc __whence); #define rhizome_new_manifest() _rhizome_new_manifest(__WHENCE__) int rhizome_manifest_pack_variables(rhizome_manifest *m); int rhizome_store_bundle(rhizome_manifest *m); +int rhizome_remove_file_datainvalid(sqlite_retry_state *retry, const char *fileid); int rhizome_manifest_add_group(rhizome_manifest *m,char *groupid); int rhizome_clean_payload(const char *fileidhex); int rhizome_store_file(rhizome_manifest *m,const unsigned char *key); diff --git a/rhizome_database.c b/rhizome_database.c index bf536dde..3b28ec44 100644 --- a/rhizome_database.c +++ b/rhizome_database.c @@ -718,7 +718,6 @@ int64_t rhizome_database_used_bytes() int rhizome_database_filehash_from_id(const char *id, uint64_t version, char hash[SHA512_DIGEST_STRING_LENGTH]) { IN(); - strbuf hash_sb = strbuf_local(hash, SHA512_DIGEST_STRING_LENGTH); RETURN(sqlite_exec_strbuf(hash_sb, "SELECT filehash FROM MANIFESTS WHERE manifests.version=%lld AND manifests.id='%s';", version,id)); @@ -739,6 +738,16 @@ static int rhizome_delete_orphan_fileblobs_retry(sqlite_retry_state *retry) return sqlite_exec_void_retry_loglevel(LOG_LEVEL_WARN, retry, "DELETE FROM FILEBLOBS WHERE NOT EXISTS( SELECT 1 FROM FILES WHERE FILES.id = FILEBLOBS.id );"); } +int rhizome_remove_file_datainvalid(sqlite_retry_state *retry, const char *fileid) +{ + int ret = 0; + if (sqlite_exec_void_retry_loglevel(LOG_LEVEL_WARN, retry, "DELETE FROM FILES WHERE id='%s' and datavalid=0;", fileid) == -1) + ret = -1; + if (sqlite_exec_void_retry_loglevel(LOG_LEVEL_WARN, retry, "DELETE FROM FILEBLOBS WHERE id='%s' AND NOT EXISTS( SELECT 1 FROM FILES WHERE FILES.id=FILEBLOBS.id );", fileid) == -1) + ret = -1; + return ret; +} + int rhizome_cleanup(struct rhizome_cleanup_report *report) { IN(); diff --git a/rhizome_store.c b/rhizome_store.c index 839f56d9..e4a96ccd 100644 --- a/rhizome_store.c +++ b/rhizome_store.c @@ -462,23 +462,26 @@ int rhizome_finish_write(struct rhizome_write *write) char hash_out[SHA512_DIGEST_STRING_LENGTH + 1]; SHA512_End(&write->sha512_context, hash_out); - - sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT; - str_toupper_inplace(hash_out); - if (write->id_known){ - if (strcasecmp(write->id, hash_out)){ - WHYF("Expected hash=%s, got %s", write->id, hash_out); + + if (write->id_known) { + if (strcasecmp(write->id, hash_out) != 0) { + WHYF("expected filehash=%s, got %s", write->id, hash_out); goto failure; } } else { strlcpy(write->id, hash_out, SHA512_DIGEST_STRING_LENGTH); } - if (rhizome_exists(hash_out)){ - // ooops, we've already got that file, delete the new copy. - rhizome_fail_write(write); - }else{ + sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT; + rhizome_remove_file_datainvalid(&retry, write->id); + if (rhizome_exists(write->id)) { + // we've already got that payload, delete the new copy + sqlite_exec_void_retry_loglevel(LOG_LEVEL_WARN, &retry,"DELETE FROM FILEBLOBS WHERE id='%"PRId64"';", write->temp_id); + sqlite_exec_void_retry_loglevel(LOG_LEVEL_WARN, &retry,"DELETE FROM FILES WHERE id='%"PRId64"';", write->temp_id); + if (config.debug.rhizome) + DEBUGF("File id='%s' already present, removed id='%"PRId64"'", write->id, write->temp_id); + } else { if (sqlite_exec_void_retry(&retry, "BEGIN TRANSACTION;") == -1) goto dbfailure; @@ -517,12 +520,10 @@ int rhizome_finish_write(struct rhizome_write *write) } if (sqlite_exec_void_retry(&retry, "COMMIT;") == -1) goto dbfailure; + if (config.debug.rhizome) + DEBUGF("Stored file %s", write->id); } - write->blob_rowid=-1; - - if (config.debug.rhizome) - DEBUGF("Stored file %s", hash_out); return 0; dbfailure: