diff --git a/core/driver/format.c b/core/driver/format.c index 17717a9..8a1b107 100644 --- a/core/driver/format.c +++ b/core/driver/format.c @@ -44,6 +44,9 @@ REDSTATUS RedVolFormat(void) { REDSTATUS ret; + REDSTATUS ret2; + bool fBDevOpen = false; + bool fGeoInited = false; if(gpRedVolume->fMounted) { @@ -52,12 +55,11 @@ REDSTATUS RedVolFormat(void) else { ret = RedBDevOpen(gbRedVolNum, BDEV_O_RDWR); + fBDevOpen = (ret == 0); } if(ret == 0) { - REDSTATUS ret2; - /* fReadOnly might still be true from the last time the volume was mounted (or from the checker). Clear it now to avoid assertions in lower-level code. @@ -65,167 +67,171 @@ REDSTATUS RedVolFormat(void) gpRedVolume->fReadOnly = false; ret = RedVolInitGeometry(); + fGeoInited = (ret == 0); + } - if(ret == 0) - { - MASTERBLOCK *pMB; - - /* Overwrite the master block with zeroes, so that if formatting is - interrupted, the volume will not be mountable. - */ - ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB)); - - if(ret == 0) - { - ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U); + if(ret == 0) + { + MASTERBLOCK *pMB; - RedBufferDiscard(pMB); - } - } + /* Overwrite the master block with zeroes, so that if formatting is + interrupted, the volume will not be mountable. + */ + ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB)); if(ret == 0) { - ret = RedIoFlush(gbRedVolNum); - } - - #if REDCONF_IMAP_EXTERNAL == 1 - if((ret == 0) && !gpRedCoreVol->fImapInline) - { - uint32_t ulImapBlock; - uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + (gpRedCoreVol->ulImapNodeCount * 2U); - uint16_t uImapFlags = (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY); - - /* Technically it is only necessary to create one copy of each imap - node (the copy the metaroot points at), but creating them both - avoids headaches during disk image analysis from stale imaps - left over from previous formats. - */ - for(ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++) - { - IMAPNODE *pImap; - - ret = RedBufferGet(ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR(&pImap)); - if(ret != 0) - { - break; - } + ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U); - RedBufferPut(pImap); - } + RedBufferDiscard(pMB); } - #endif - - /* Write the first metaroot. - */ - if(ret == 0) - { - RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR)); - - gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable; - #if REDCONF_API_POSIX == 1 - gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount; - #endif - gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN; - - /* The branched flag is typically set automatically when bits in - the imap change. It is set here explicitly because the imap has - only been initialized, not changed. - */ - gpRedCoreVol->fBranched = true; + } - ret = RedVolTransact(); - } + if(ret == 0) + { + ret = RedIoFlush(gbRedVolNum); + } - #if REDCONF_API_POSIX == 1 - /* Create the root directory. + #if REDCONF_IMAP_EXTERNAL == 1 + if((ret == 0) && !gpRedCoreVol->fImapInline) + { + uint32_t ulImapBlock; + uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + (gpRedCoreVol->ulImapNodeCount * 2U); + uint16_t uImapFlags = (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY); + + /* Technically it is only necessary to create one copy of each imap + node (the copy the metaroot points at), but creating them both + avoids headaches during disk image analysis from stale imaps left + over from previous formats. */ - if(ret == 0) + for(ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++) { - CINODE rootdir; + IMAPNODE *pImap; - rootdir.ulInode = INODE_ROOTDIR; - ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR); - - if(ret == 0) + ret = RedBufferGet(ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR(&pImap)); + if(ret != 0) { - RedInodePut(&rootdir, 0U); + break; } + + RedBufferPut(pImap); } + } + #endif + + /* Write the first metaroot. + */ + if(ret == 0) + { + RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR)); + + gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable; + #if REDCONF_API_POSIX == 1 + gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount; #endif + gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN; - #if REDCONF_API_FSE == 1 - /* The FSE API does not support creating or deletes files, so all the - inodes are created during setup. + /* The branched flag is typically set automatically when bits in the + imap change. It is set here explicitly because the imap has only + been initialized, not changed. */ - if(ret == 0) - { - uint32_t ulInodeIdx; + gpRedCoreVol->fBranched = true; - for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++) - { - CINODE ino; + ret = RedVolTransact(); + } - ino.ulInode = INODE_FIRST_FREE + ulInodeIdx; - ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG); + #if REDCONF_API_POSIX == 1 + /* Create the root directory. + */ + if(ret == 0) + { + CINODE rootdir; - if(ret == 0) - { - RedInodePut(&ino, 0U); - } - } - } - #endif + rootdir.ulInode = INODE_ROOTDIR; + ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR); - /* Write the second metaroot. - */ if(ret == 0) { - ret = RedVolTransact(); + RedInodePut(&rootdir, 0U); } + } + #endif - /* Populate and write out the master block. - */ - if(ret == 0) + #if REDCONF_API_FSE == 1 + /* The FSE API does not support creating or deleting files, so all the + inodes are created during setup. + */ + if(ret == 0) + { + uint32_t ulInodeIdx; + + for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++) { - MASTERBLOCK *pMB; + CINODE ino; + + ino.ulInode = INODE_FIRST_FREE + ulInodeIdx; + ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG); - ret = RedBufferGet(BLOCK_NUM_MASTER, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB)); if(ret == 0) { - pMB->ulVersion = RED_DISK_LAYOUT_VERSION; - RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum)); - pMB->ulFormatTime = RedOsClockGetTime(); - pMB->ulInodeCount = gpRedVolConf->ulInodeCount; - pMB->ulBlockCount = gpRedVolume->ulBlockCount; - pMB->uMaxNameLen = REDCONF_NAME_MAX; - pMB->uDirectPointers = REDCONF_DIRECT_POINTERS; - pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS; - pMB->bBlockSizeP2 = BLOCK_SIZE_P2; - - #if REDCONF_API_POSIX == 1 - pMB->bFlags |= MBFLAG_API_POSIX; - #endif - #if REDCONF_INODE_TIMESTAMPS == 1 - pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS; - #endif - #if REDCONF_INODE_BLOCKS == 1 - pMB->bFlags |= MBFLAG_INODE_BLOCKS; - #endif - #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) - pMB->bFlags |= MBFLAG_INODE_NLINK; - #endif - - ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U); - - RedBufferPut(pMB); + RedInodePut(&ino, 0U); } } + } + #endif + + /* Write the second metaroot. + */ + if(ret == 0) + { + ret = RedVolTransact(); + } + + /* Populate and write out the master block. + */ + if(ret == 0) + { + MASTERBLOCK *pMB; + ret = RedBufferGet(BLOCK_NUM_MASTER, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB)); if(ret == 0) { - ret = RedIoFlush(gbRedVolNum); + pMB->ulVersion = RED_DISK_LAYOUT_VERSION; + RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum)); + pMB->ulFormatTime = RedOsClockGetTime(); + pMB->ulInodeCount = gpRedVolConf->ulInodeCount; + pMB->ulBlockCount = gpRedVolume->ulBlockCount; + pMB->uMaxNameLen = REDCONF_NAME_MAX; + pMB->uDirectPointers = REDCONF_DIRECT_POINTERS; + pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS; + pMB->bBlockSizeP2 = BLOCK_SIZE_P2; + + #if REDCONF_API_POSIX == 1 + pMB->bFlags |= MBFLAG_API_POSIX; + #endif + #if REDCONF_INODE_TIMESTAMPS == 1 + pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS; + #endif + #if REDCONF_INODE_BLOCKS == 1 + pMB->bFlags |= MBFLAG_INODE_BLOCKS; + #endif + #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) + pMB->bFlags |= MBFLAG_INODE_NLINK; + #endif + + ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U); + + RedBufferPut(pMB); } + } + if(ret == 0) + { + ret = RedIoFlush(gbRedVolNum); + } + + if(fBDevOpen) + { ret2 = RedBDevClose(gbRedVolNum); if(ret == 0) { @@ -233,12 +239,16 @@ REDSTATUS RedVolFormat(void) } } - /* Discard the buffers so a subsequent format will not run into blocks it - does not expect. - */ - if(ret == 0) + if(fGeoInited) { - ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount); + /* Discard the buffers so a subsequent format will not run into blocks + it does not expect. + */ + ret2 = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount); + if(ret == 0) + { + ret = ret2; + } } return ret; diff --git a/include/redver.h b/include/redver.h index 9bd9e64..75c1eec 100644 --- a/include/redver.h +++ b/include/redver.h @@ -33,7 +33,7 @@ */ -#define RED_BUILD_NUMBER "860" +#define RED_BUILD_NUMBER "861" #define RED_KIT_GPL 0U /* Open source GPL kit. */ #define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */ diff --git a/tests/util/printf.c b/tests/util/printf.c index 2aa85ad..14ff504 100644 --- a/tests/util/printf.c +++ b/tests/util/printf.c @@ -955,10 +955,10 @@ static uint32_t LtoA( } else { - char ach[12U]; /* big enough for a int32_t in base 10 */ - uint32_t ulDigits = 0U; - uint32_t ulNum; - bool fSign; + char ach[12U]; /* big enough for a int32_t in base 10 */ + uint32_t ulDigits = 0U; + uint32_t ulNum; + bool fSign; if(lNum < 0) { @@ -1025,10 +1025,10 @@ static uint32_t LLtoA( } else { - char ach[12U]; /* big enough for a int32_t in base 10 */ - uint32_t ulDigits = 0U; - uint64_t ullNum; - bool fSign; + char ach[21U]; /* big enough for a int64_t in base 10 */ + uint32_t ulDigits = 0U; + uint64_t ullNum; + bool fSign; if(llNum < 0) { @@ -1157,7 +1157,6 @@ static uint32_t ULLtoA( } else { - char ach[21U]; /* Big enough for a uint64_t in radix 10 */ uint32_t ulDigits = 0U; uint64_t ullNumericVal = ullNum;