From a3744ae7a3d608cb30d9e7f1f239fd336b734ee9 Mon Sep 17 00:00:00 2001 From: d0k3 Date: Wed, 30 Nov 2016 02:01:33 +0100 Subject: [PATCH] Fix corruption on RAMdrive mount / unmount --- source/fs.c | 52 ++++++++++++++++++++++++++++++++++++++---------- source/fs.h | 2 ++ source/godmode.c | 24 ++++++++-------------- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/source/fs.c b/source/fs.c index a1a0549..5aaa37e 100644 --- a/source/fs.c +++ b/source/fs.c @@ -9,6 +9,7 @@ #include "ff.h" #define NORM_FS 10 +#define IMGN_FS 3 // image normal filesystems #define VIRT_FS 8 #define SKIP_CUR (1<<3) @@ -39,27 +40,58 @@ bool InitSDCardFS() { } bool InitExtFS() { - u32 mount_state = GetMountState(); - u32 last_fs = (mount_state == IMG_NAND) ? NORM_FS : - ((mount_state == IMG_FAT) || (mount_state == IMG_RAMDRV)) ? NORM_FS - 2 : NORM_FS - 3; if (!fs_mounted[0]) return false; - for (u32 i = 1; i < last_fs; i++) { + for (u32 i = 1; i < NORM_FS; i++) { char fsname[8]; snprintf(fsname, 7, "%lu:", i); if (fs_mounted[i]) continue; fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); - if ((i == 7) && !fs_mounted[7] && (mount_state == IMG_RAMDRV)) { - f_mkfs("7:", FM_ANY, 0, MAIN_BUFFER, MAIN_BUFFER_SIZE); // format ramdrive if required - f_mount(NULL, fsname, 1); - fs_mounted[7] = (f_mount(fs + 7, "7:", 1) == FR_OK); - } } SetupNandSdDrive("A:", "0:", "1:/private/movable.sed", 0); SetupNandSdDrive("B:", "0:", "4:/private/movable.sed", 1); return true; } +bool InitImgFS(const char* path) { + // deinit image filesystem + for (u32 i = NORM_FS - 1; i >= NORM_FS - IMGN_FS; i--) { + char fsname[8]; + snprintf(fsname, 7, "%lu:", i); + if (!fs_mounted[i]) continue; + f_mount(NULL, fsname, 1); + fs_mounted[i] = false; + } + // (re)mount image, done if path == NULL + MountImage(path); + InitVGameDrive(); + if (!GetMountState()) return false; + // reinit image filesystem + for (u32 i = NORM_FS - IMGN_FS; i < NORM_FS; i++) { + char fsname[8]; + snprintf(fsname, 7, "%lu:", i); + fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); + } + return true; +} + +bool InitRamDriveFS() { + u32 pdrv = NORM_FS - IMGN_FS; + char fsname[8]; + snprintf(fsname, 7, "%lu:", pdrv); + + InitImgFS(NULL); + MountRamDrive(); + fs_mounted[pdrv] = (f_mount(fs + pdrv, fsname, 1) == FR_OK); + if (!fs_mounted[pdrv] && (GetMountState() == IMG_RAMDRV)) { + f_mkfs(fsname, FM_ANY, 0, MAIN_BUFFER, MAIN_BUFFER_SIZE); // format ramdrive if required + f_mount(NULL, fsname, 1); + fs_mounted[pdrv] = (f_mount(fs + pdrv, fsname, 1) == FR_OK); + } + + return true; +} + void DeinitExtFS() { SetupNandSdDrive(NULL, NULL, NULL, 0); SetupNandSdDrive(NULL, NULL, NULL, 1); @@ -70,7 +102,7 @@ void DeinitExtFS() { f_mount(NULL, fsname, 1); fs_mounted[i] = false; } - if ((i == 7) && (GetMountState() != IMG_RAMDRV)) { // unmount image + if ((i == NORM_FS - IMGN_FS) && (GetMountState() != IMG_RAMDRV)) { // unmount image MountImage(NULL); InitVGameDrive(); } diff --git a/source/fs.h b/source/fs.h index 8a5969b..824a4d4 100644 --- a/source/fs.h +++ b/source/fs.h @@ -39,6 +39,8 @@ bool InitSDCardFS(); bool InitExtFS(); +bool InitImgFS(const char* path); +bool InitRamDriveFS(); void DeinitExtFS(); void DeinitSDCardFS(); diff --git a/source/godmode.c b/source/godmode.c index e75df60..25a7c12 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -84,7 +84,7 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c int drvtype = DriveType(curr_entry->path); char drvstr[32]; snprintf(drvstr, 31, "(%s%s)", - ((drvtype & DRV_SDCARD) ? "SD" : (drvtype & DRV_RAMDRIVE) ? "RAMDrive" : (drvtype & DRV_RAMDRIVE) ? "Game" : + ((drvtype & DRV_SDCARD) ? "SD" : (drvtype & DRV_RAMDRIVE) ? "RAMDrive" : (drvtype & DRV_GAME) ? "Game" : (drvtype & DRV_SYSNAND) ? "SysNAND" : (drvtype & DRV_EMUNAND) ? "EmuNAND" : (drvtype & DRV_IMAGE) ? "Image" : (drvtype & DRV_MEMORY) ? "Memory" : (drvtype & DRV_ALIAS) ? "Alias" : (drvtype & DRV_SEARCH) ? "Search" : ""), ((drvtype & DRV_FAT) ? " FAT" : (drvtype & DRV_VIRTUAL) ? " Virtual" : "")); @@ -692,18 +692,12 @@ u32 GodMode() { clipboard->n_entries = 0; } } else if ((int) user_select == mountable) { // -> mount file as image - if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) + if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & (DRV_IMAGE|DRV_RAMDRIVE))) clipboard->n_entries = 0; // remove last mounted image clipboard entries - DeinitExtFS(); - InitExtFS(); - u32 mount_state = MountImage(curr_entry->path); - InitExtFS(); - InitVGameDrive(); - if (!mount_state || !(DriveType("7:")||DriveType("8:")||DriveType("9:")||DriveType("G:"))) { + InitImgFS(curr_entry->path); + if (!(DriveType("7:")||DriveType("8:")||DriveType("9:")||DriveType("G:"))) { ShowPrompt(false, "Mounting image: failed"); - DeinitExtFS(); - InitExtFS(); - InitVGameDrive(); + InitImgFS(NULL); } else { *current_path = '\0'; GetDirContents(current_dir, current_path); @@ -803,12 +797,10 @@ u32 GodMode() { // highly specific commands if (!*current_path) { // in the root folder... if (switched && (pad_state & BUTTON_X)) { // unmount image - if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) + if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & (DRV_IMAGE|DRV_RAMDRIVE))) clipboard->n_entries = 0; // remove last mounted image clipboard entries - if (!GetMountState()) MountRamDrive(); - else MountImage(NULL); - DeinitExtFS(); - InitExtFS(); + if (!GetMountState()) InitRamDriveFS(); + else InitImgFS(NULL); GetDirContents(current_dir, current_path); } else if (switched && (pad_state & BUTTON_Y)) { SetWritePermissions((GetWritePermissions() > PERM_BASE) ? PERM_BASE : PERM_ALL, false);