Skip to content

Instantly share code, notes, and snippets.

@rw-r-r-0644
Last active June 4, 2021 15:50
Show Gist options
  • Save rw-r-r-0644/d72491ee7c4ce961c4edfdf43d28498d to your computer and use it in GitHub Desktop.
Save rw-r-r-0644/d72491ee7c4ce961c4edfdf43d28498d to your computer and use it in GitHub Desktop.
/* this computations are repeated thoughout the function */
static inline u32 _blockClusters(FSISFS_Volume *isfs) {
return isfs->devCaps.blockSize >> 0xe;
}
static inline u32 _superblockCount(FSISFS_Volume *isfs) {
return 1 << isfs->superblockCountLog2;
}
static inline u8 _superblockSizeLog2(FSISFS_Volume *isfs) {
return isfs->metadataSizeLog2 - isfs->superblockCountLog2;
}
static inline u32 _superblockClusters(FSISFS_Volume *isfs) {
return 1 << (_superblockSizeLog2(isfs) - 0xe);
}
static inline u32 _metadataAreaStartCluster(FSISFS_Volume *isfs) {
return isfs->fsOffset + (isfs->dataAreaSize >> 0xe);
}
static inline u32 _nextSuperblockSlot(FSISFS_Volume *isfs) {
isfs->superblockSlot = (isfs->superblockSlot + 1) & _superblockCount(isfs);
}
int ISFS_CommitSuperblock(FSISFS_Volume *isfs)
{
int rc = 0;
if ((isfs->initState & 0x44) == 0x44) {
return -0x80017;
}
isfs->super.generation++;
for (u32 index = 0; index < _superblockCount(isfs); index++, _nextSuperblockSlot(isfs)) {
/* get superblock cluster (the *actual* code is more complex and redundant, but should have the same result) */
u32 superblockCluster = _metadataAreaStartCluster(isfs) + _superblockClusters(isfs) * isfs->superblockSlot;
/* check if the superblock slot contains bad blocks */
BOOL slotGood = TRUE;
for (u16 clusOffs = 0; clusOffs < _superblockClusters(isfs); clusOffs += _blockClusters(isfs))
if (isfs->super.fat[superblockCluster + clusOffs] != 0xfffc) {
slotGood = FALSE;
/* do not write to this slot */
if (!slotGood)
continue;
/* set hmac seed */
*(uint *)(isfs->hmacSeedBuf + 0x10) = superblockCluster
/* write slot clusters */
rc = ISFS_WriteCluster(isfs, superblockCluster & 0xffff, _superblockClusters(isfs), 6, isfs->hmacSeedBuf, isfs, NULL);
if (rc == 0) {
break;
}
if (rc == -0x80470) {
/* write failed and blocks should be marked as bad */
ISFS_SyslogWrite("ISFS: %s(%d)Detected bad logical block at %d (slot %d).Will never reuse this slot.\n",
"fs_fat.c", 0x34d, superblockCluster, isfs->superblockSlot);
ISFS_DebugWrite("ISFS: %s(%d) Detected bad logical block at %d (slot %d).Will never reuse this slot.\n"
"fs_fat.c", 0x34d, superblockCluster, isfs->superblockSlot);
/* mark the slot blocks as bad */
for (u16 clusOffs = 0; clusOffs < _superblockClusters(isfs); clusOffs += _blockClusters(isfs))
for (u16 clusIdx = 0; clusIdx < _blockClusters(isfs); clusIdx++)
isfs->super.fat[superblockCluster + clusOffs + clusIdx] = 0xfffd;
/* ensure the next slot will be loaded instead */
isfs->super.generation++;
} else {
/* other error */
ISFS_SyslogWrite("ISFS: %s(%d)Could not write FAT blocks at %d (slot %d).rc=%d\n",
"fs_fat.c", 0x356, superblockCluster, isfs->superblockSlot, rc);
ISFS_DebugWrite("ISFS: %s(%d) Could not write FAT blocks at %d (slot %d).rc=%d\n",
"fs_fat.c", 0x356, superblockCluster, isfs->superblockSlot, rc);
}
}
/* not a single slot was successfully writable */
if (index == _superblockCount(isfs)) {
ISFS_SyslogWrite("ISFS: The flash is corrupted beyond use\n");
ISFS_DebugWrite("ISFS: %s(%d)The flash is corrupted beyond use\n","fs_fat.c",0x364);
return = -0x8001b;
}
return rc;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment