#include <stddef.h> #include "ubixfs.h" #include "inode.h" #include "superblock.h" UbixFS::UbixFS(void) { freeBlockList = NULL; } // UbixFS::UbixFS int32 UbixFS::getFreeBlock(uInt32 AG) { // AG == AllocationGroup signed char * ptr; signed char * endPtr; int32 count; int32 subCount = 128; // Check to make sure neither of these are null if (freeBlockList == NULL || superBlock == NULL) return -1; // Are there any blocks available? if (superBlock->numBlocks == superBlock->usedBlocks) return -1; /* * count is the block from the base of the list. * Since we're given a specific AG to look through, we start the count at * AG << AGShift, where AGShift is the shift value of the number of blocks * in an AG */ count = (AG << superBlock->AGShift); /* * The freeBlockList is a bit map of the free/used blocks. * Used = on bit * Unused = off bit * There are 8 bits per byte (hopefully) and so we have to divide the count * by 8 to get our starting byte offset to look from */ ptr = freeBlockList + (count >> 3); /* * endPtr is the very last address we can look at before we wrap around * This calculation is probably not correct if the number of blocks isn't * divisible by 8 */ endPtr = freeBlockList + ((superBlock->numAGs << superBlock->AGShift) >> 3); // Scan through the freeBlockList while (*ptr == -1) { if (++ptr == endPtr) { ptr = freeBlockList; count = 0; } else { count +=8; } // else } // while *ptr == -1 do { if ((*ptr & subCount) == 0) break; subCount >>= 1; ++count; } while(subCount > 1); *ptr |= subCount; // mark this block as used ++superBlock->usedBlocks; // increment the number of used blocks return count; // return the allocated block number } // Ubixfs::getFreeBlock /* * UbixFS::getFreeBlock(void) * upon success returns a free block based on the next AG after the lastUsedAG * failure returns -1 */ int32 UbixFS::getFreeBlock(void) { if (superBlock == NULL) return -1; if (superBlock->lastUsedAG == superBlock->numAGs) superBlock->lastUsedAG = 0; else superBlock->lastUsedAG++; return getFreeBlock(superBlock->lastUsedAG); } // UbixFS::getFreeBlock bool UbixFS::init(void) { return true; } // UbixFS::init bool UbixFS::format(void * ptr, unsigned long long devBlocks, int blockSize) { return true; } // UbixFS::format bool UbixFS::mount(void) { return true; } // UbixFS::mount bool UbixFS::unmount(void) { return true; } // UbixFS::unmount bool UbixFS::verify(void) { return true; } // UbixFS::verifyFS UbixFS::~UbixFS(void) { delete [] freeBlockList; return; }