From 0f42f92febd38218de8950f4a40f2f62edb8d3d4 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 24 Oct 2026 17:44:39 +0200 Subject: [PATCH] fix(member-files): clean up only owned download temporaries --- src/member_files/member_files.h | 1 + src/member_files/transfer.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/member_files/member_files.h b/src/member_files/member_files.h index e00d6e03..14ca5335 100644 --- a/src/member_files/member_files.h +++ b/src/member_files/member_files.h @@ -76,6 +76,7 @@ typedef void (*mf_transfer_fn)(void* arg, const struct mf_transfer_progress* pro // finished приходит ровно один раз после закрытия/публикации; handle уже освобождён до callback. // Прогресс заимствован на время callback. Cancel асинхронно ждёт свой I/O и не затрагивает другие handles. // Request копируется; исходную структуру можно освободить сразу, arg должен жить до finished. +// Download заменяет local только после проверки/закрытия своего temp; отказ/отмена до создания не удаляет чужой temp. struct mf_transfer* member_files_transfer_start(const struct mf_transfer_request* request, mf_transfer_fn callback, void* arg); // Запросить отмену своей передачи; завершение приходит через finished после закрытия её файлового I/O. diff --git a/src/member_files/transfer.c b/src/member_files/transfer.c index 8a741ab3..a3688888 100644 --- a/src/member_files/transfer.c +++ b/src/member_files/transfer.c @@ -36,6 +36,7 @@ struct mf_transfer { EVP_MD_CTX* digest; int fd, server, sending, starting, active, opened, busy, stopping, finished_io, peer_down; int status, work_status, reply_ready, reply_final, verified, committed, end_sent, end_received; + int temp_owned; // Только свой эксклюзивно созданный локальный temp можно публиковать/удалять. enum transfer_work work; uint64_t size, offset, received, read_offset, io_offset, io_bytes, io_size, progress_tb, last_event, last_log, logged_offset; unsigned head, count, io_head, io_count; @@ -129,7 +130,12 @@ static void transfer_work(void* arg) { struct mf_disk_info after; if (!rc) rc = mf_disk_info(t->fd, &after); if (!rc && memcmp(&after, &t->source, sizeof(after))) rc = MF_STALE; - } else rc = mf_disk_local_open(t->temp, 1, &t->fd); + } else { + rc = mf_disk_local_open(t->temp, 1, &t->fd); + if (!rc) t->temp_owned = 1; + DEBUG_DEBUG(DEBUG_CATEGORY_MEDIA, "member_files: download temp id=%llu created=%d status=%s path=%s", + (unsigned long long)t->request.id, t->temp_owned, mf_status_text(rc), t->temp); + } if (!rc && t->request.upload == 0) { t->digest = EVP_MD_CTX_new(); if (!t->digest || EVP_DigestInit_ex(t->digest, EVP_sha256(), NULL) != 1) rc = MF_IO_ERROR; @@ -196,8 +202,13 @@ static void transfer_work(void* arg) { if (!rc) rc = closed; } if (!t->server && !t->sending) { - if (!t->status && !rc) rc = mf_disk_local_publish(t->temp, t->request.local); - if (t->status || rc) mf_disk_local_remove(t->temp); + DEBUG_DEBUG(DEBUG_CATEGORY_MEDIA, "member_files: download cleanup id=%llu owned=%d status=%s io=%s", + (unsigned long long)t->request.id, t->temp_owned, mf_status_text(t->status), mf_status_text(rc)); + if (!t->status && !rc) { + rc = mf_disk_local_publish(t->temp, t->request.local); + if (!rc) t->temp_owned = 0; + } + if ((t->status || rc) && t->temp_owned && !mf_disk_local_remove(t->temp)) t->temp_owned = 0; } EVP_MD_CTX_free(t->digest); t->digest = NULL; }