diff --git a/src/sfs.c b/src/sfs.c index f5384f8..573460f 100644 --- a/src/sfs.c +++ b/src/sfs.c @@ -954,3 +954,155 @@ bool sfsFormat(void) memset(inodeBitmap, 0, (uint64)nsb.inodeBitmapBlocks * sfsBlockSize); memset(blockBitmap, 0, (uint64)nsb.blockBitmapBlocks * sfsBlockSize); + sb = nsb; + isMounted = true; + + uint8 zeroBlk[sfsBlockSize]; + memset(zeroBlk, 0, sizeof(zeroBlk)); + for (uint32 i = 0; i < sb.inodeTableBlocks; i++) + blockWrite(sb.inodeTableStart + i, zeroBlk); + + bitSet(inodeBitmap, 0); + bitSet(inodeBitmap, sfsRootInode); + + SfsInode rootInode; + memset(&rootInode, 0, sizeof(rootInode)); + rootInode.type = sfsTypeDir; + rootInode.linkCount = 1; + rootInode.mtime = rootInode.ctime = (uint32)rtcNow(); + rootInode.mode = fsModeDefaultDir; + rootInode.uid = currentThreadUid(); + rootInode.gid = currentThreadGid(); + writeInodeRaw(sfsRootInode, &rootInode); + + flushInodeBitmap(); + flushBlockBitmap(); + flushSuperblock(); + return true; +} + +bool sfsMount(void) +{ + if (!ataPresent()) + return false; + + uint8 buf[sfsBlockSize]; + if (!ataReadSectors(sfsBaseLba, 1, buf)) + return false; + + SfsSuperblock onDisk; + memcpy(&onDisk, buf, sizeof(onDisk)); + if (onDisk.magic != sfsMagic) + return sfsFormat(); + + sb = onDisk; + + if (inodeBitmap) { + kfree(inodeBitmap); + inodeBitmap = nullptr; + } + if (blockBitmap) { + kfree(blockBitmap); + blockBitmap = nullptr; + } + + inodeBitmap = (uint8*)kmalloc((uint64)sb.inodeBitmapBlocks * sfsBlockSize); + blockBitmap = (uint8*)kmalloc((uint64)sb.blockBitmapBlocks * sfsBlockSize); + if (!inodeBitmap || !blockBitmap) + return false; + + for (uint32 i = 0; i < sb.inodeBitmapBlocks; i++) + if (!blockRead(sb.inodeBitmapStart + i, inodeBitmap + (uint64)i * sfsBlockSize)) + return false; + for (uint32 i = 0; i < sb.blockBitmapBlocks; i++) + if (!blockRead(sb.blockBitmapStart + i, blockBitmap + (uint64)i * sfsBlockSize)) + return false; + + isMounted = true; + return true; +} + +void sfsUnmount(void) +{ + if (!isMounted) + return; + flushInodeBitmap(); + flushBlockBitmap(); + flushSuperblock(); + if (inodeBitmap) { + kfree(inodeBitmap); + inodeBitmap = nullptr; + } + if (blockBitmap) { + kfree(blockBitmap); + blockBitmap = nullptr; + } + isMounted = false; +} + +bool sfsMounted(void) +{ + return isMounted; +} + +uint64 sfsCapacityBytes(void) +{ + if (!isMounted) + return 0; + return (uint64)(sb.totalBlocks - sb.dataStart) * sfsBlockSize; +} + +uint64 sfsFreeDataBlocks(void) +{ + if (!isMounted) + return 0; + uint32 dataBlockCount = sb.totalBlocks - sb.dataStart; + uint64 free = 0; + for (uint32 i = 0; i < dataBlockCount; i++) + if (!bitTest(blockBitmap, i)) + free++; + return free; +} + +int32 sfsLookup(const char* path) +{ + return lookupFrom(path, true, 0); +} + +int32 sfsLookupNoFollow(const char* path) +{ + return lookupFrom(path, false, 0); +} + +int32 sfsCreateFile(const char* path) +{ + return createNode(path, sfsTypeFile); +} + +int32 sfsCreateDir(const char* path) +{ + return createNode(path, sfsTypeDir); +} + +int32 sfsCreateFifo(const char* path) +{ + return createNode(path, sfsTypeFifo); +} + +uint64 sfsGeneration(void) +{ + return formatGeneration; +} + +int32 sfsCreateSymlink(const char* path, const char* target) +{ + if (!isMounted || !target) + return -1; + uint64 targetLen = strlen(target); + if (targetLen == 0 || targetLen > sfsSymlinkTargetMax) + return -1; + + int32 newInode = createNode(path, sfsTypeSymlink); + if (newInode < 0) + return -1; +