From c6eff5889000ceadaa1d0c6c3a4359cd8a839b8f Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 15 May 2023 01:31:02 +0100 Subject: [PATCH] OFW be like rEnAmE = cOpY + dElEtE, bro stfu :/ --- .../storage/filesystem_api_internal.h | 1 + .../services/storage/storage_external_api.c | 17 ++++--- .../services/storage/storage_message.h | 8 ++++ .../services/storage/storage_processing.c | 44 +++++++++++++++++++ .../services/storage/storages/storage_ext.c | 13 ++++++ .../services/storage/storages/storage_int.c | 8 ++++ 6 files changed, 84 insertions(+), 7 deletions(-) diff --git a/applications/services/storage/filesystem_api_internal.h b/applications/services/storage/filesystem_api_internal.h index 967d3bb41..47214f21a 100644 --- a/applications/services/storage/filesystem_api_internal.h +++ b/applications/services/storage/filesystem_api_internal.h @@ -169,6 +169,7 @@ typedef struct { typedef struct { FS_Error (*const stat)(void* context, const char* path, FileInfo* fileinfo); FS_Error (*const remove)(void* context, const char* path); + FS_Error (*const rename)(void* context, const char* old, const char* new); FS_Error (*const mkdir)(void* context, const char* path); FS_Error (*const fs_info)( void* context, diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index bf474bc9d..d5d9a41a5 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -422,14 +422,17 @@ FS_Error storage_common_remove(Storage* storage, const char* path) { } FS_Error storage_common_rename(Storage* storage, const char* old_path, const char* new_path) { - FS_Error error = storage_common_copy(storage, old_path, new_path); - if(error == FSE_OK) { - if(!storage_simply_remove_recursive(storage, old_path)) { - error = FSE_INTERNAL; - } - } + S_API_PROLOGUE; + SAData data = { + .rename = { + .old = old_path, + .new = new_path, + .thread_id = furi_thread_get_current_id(), + }}; - return error; + S_API_MESSAGE(StorageCommandCommonRename); + S_API_EPILOGUE; + return S_RETURN_ERROR; } static FS_Error diff --git a/applications/services/storage/storage_message.h b/applications/services/storage/storage_message.h index 9e13bf83d..e77bad6ee 100644 --- a/applications/services/storage/storage_message.h +++ b/applications/services/storage/storage_message.h @@ -78,6 +78,12 @@ typedef struct { FuriThreadId thread_id; } SADataPath; +typedef struct { + const char* old; + const char* new; + FuriThreadId thread_id; +} SADataRename; + typedef struct { File* file; } SADataFile; @@ -104,6 +110,7 @@ typedef union { SADataFile file; SADataPath path; + SADataRename rename; SAInfo sdinfo; } SAData; @@ -134,6 +141,7 @@ typedef enum { StorageCommandCommonTimestamp, StorageCommandCommonStat, StorageCommandCommonRemove, + StorageCommandCommonRename, StorageCommandCommonMkDir, StorageCommandCommonFSInfo, StorageCommandSDFormat, diff --git a/applications/services/storage/storage_processing.c b/applications/services/storage/storage_processing.c index b2a00b2c2..523400184 100644 --- a/applications/services/storage/storage_processing.c +++ b/applications/services/storage/storage_processing.c @@ -369,6 +369,39 @@ static FS_Error storage_process_common_remove(Storage* app, FuriString* path) { return ret; } +static FS_Error storage_process_common_rename(Storage* app, FuriString* old, FuriString* new) { + FS_Error ret; + // Paths are already resolved, no aliases + if(strncmp(furi_string_get_cstr(old), furi_string_get_cstr(new), STORAGE_PATH_PREFIX_LEN)) { + // Different filesystems, use copy + remove + ret = storage_common_copy(app, furi_string_get_cstr(old), furi_string_get_cstr(new)); + if(ret == FSE_OK) { + if(!storage_simply_remove_recursive(app, furi_string_get_cstr(old))) { + ret = FSE_INTERNAL; + } + } + } else { + // Same filesystem, use rename + StorageData* storage; + ret = storage_get_data(app, old, &storage); + + do { + if(storage_path_already_open(old, storage)) { + ret = FSE_ALREADY_OPEN; + break; + } + + storage_data_timestamp(storage); + FS_CALL( + storage, + common.rename( + storage, cstr_path_without_vfs_prefix(old), cstr_path_without_vfs_prefix(new))); + } while(false); + } + + return ret; +} + static FS_Error storage_process_common_mkdir(Storage* app, FuriString* path) { StorageData* storage; FS_Error ret = storage_get_data(app, path, &storage); @@ -514,6 +547,7 @@ void storage_process_alias( void storage_process_message_internal(Storage* app, StorageMessage* message) { FuriString* path = NULL; + FuriString* opath = NULL; switch(message->command) { // File operations @@ -614,6 +648,13 @@ void storage_process_message_internal(Storage* app, StorageMessage* message) { storage_process_alias(app, path, message->data->path.thread_id, false); message->return_data->error_value = storage_process_common_remove(app, path); break; + case StorageCommandCommonRename: + opath = furi_string_alloc_set(message->data->rename.old); + storage_process_alias(app, opath, message->data->rename.thread_id, false); + path = furi_string_alloc_set(message->data->rename.new); + storage_process_alias(app, path, message->data->rename.thread_id, false); + message->return_data->error_value = storage_process_common_rename(app, opath, path); + break; case StorageCommandCommonMkDir: path = furi_string_alloc_set(message->data->path.path); storage_process_alias(app, path, message->data->path.thread_id, true); @@ -649,6 +690,9 @@ void storage_process_message_internal(Storage* app, StorageMessage* message) { if(path != NULL) { //-V547 furi_string_free(path); } + if(opath != NULL) { //-V547 + furi_string_free(opath); + } api_lock_unlock(message->lock); } diff --git a/applications/services/storage/storages/storage_ext.c b/applications/services/storage/storages/storage_ext.c index 15a355dc2..4fd06df73 100644 --- a/applications/services/storage/storages/storage_ext.c +++ b/applications/services/storage/storages/storage_ext.c @@ -535,6 +535,18 @@ static FS_Error storage_ext_common_remove(void* ctx, const char* path) { #endif } +static FS_Error storage_ext_common_rename(void* ctx, const char* old, const char* new) { + UNUSED(ctx); +#ifdef FURI_RAM_EXEC + UNUSED(old); + UNUSED(new); + return FSE_NOT_READY; +#else + SDError result = f_rename(old, new); + return storage_ext_parse_error(result); +#endif +} + static FS_Error storage_ext_common_mkdir(void* ctx, const char* path) { UNUSED(ctx); #ifdef FURI_RAM_EXEC @@ -614,6 +626,7 @@ static const FS_Api fs_api = { .stat = storage_ext_common_stat, .mkdir = storage_ext_common_mkdir, .remove = storage_ext_common_remove, + .rename = storage_ext_common_rename, .fs_info = storage_ext_common_fs_info, }, }; diff --git a/applications/services/storage/storages/storage_int.c b/applications/services/storage/storages/storage_int.c index 8a2fef53b..25faef8a3 100644 --- a/applications/services/storage/storages/storage_int.c +++ b/applications/services/storage/storages/storage_int.c @@ -689,6 +689,13 @@ static FS_Error storage_int_common_remove(void* ctx, const char* path) { return storage_int_parse_error(result); } +static FS_Error storage_int_common_rename(void* ctx, const char* old, const char* new) { // FIXME + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + int result = lfs_rename(lfs, old, new); + return storage_int_parse_error(result); +} + static FS_Error storage_int_common_mkdir(void* ctx, const char* path) { StorageData* storage = ctx; lfs_t* lfs = lfs_get_from_storage(storage); @@ -746,6 +753,7 @@ static const FS_Api fs_api = { .stat = storage_int_common_stat, .mkdir = storage_int_common_mkdir, .remove = storage_int_common_remove, + .rename = storage_int_common_rename, .fs_info = storage_int_common_fs_info, }, };