#include <stddef.h> #include "ubixfs.h" #include "inode.h" #include "superblock.h" UbixFS::UbixFS(dev_t * dev) { device = dev; freeBlockList = NULL; } // UbixFS::UbixFS int UbixFS::init(void) { return 0; } // UbixFS::init int32 UbixFS::getFreeBlock(uInt32 AG) { // AG == AllocationGroup signed char * ptr; int32 count; int32 subCount = 128; // Check to make sure neither of these are null if (device == NULL || 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); // Scan through the freeBlockList rescan: while (*ptr == -1) { ++ptr; count += 8; if (count+8 > superBlock->numBlocks) break; } // while *ptr == -1 subCount = 128; do { if ((*ptr & subCount) == 0) break; subCount >>= 1; ++count; if (count == superBlock->numBlocks) { count = 0; ptr = freeBlockList; goto rescan; } // if } 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 int32 UbixFS::get8FreeBlocks(uInt32 AG) { // AG == AllocationGroup signed char * ptr; signed char * endPtr; int32 count; if (device == NULL || freeBlockList == NULL || superBlock == NULL) return -1; // Are there any blocks available? if (superBlock->usedBlocks+8 > superBlock->numBlocks) 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); endPtr = freeBlockList + (superBlock->numBlocks >> 3); bool secondTime = false; while (*ptr != 0) { ++ptr; count += 8; if (ptr == endPtr) { if (secondTime) return -1; else secondTime = true; count = 0; ptr = freeBlockList; } // if } // while *ptr = -1; return count; } // UbixFS::get8FreeBlocks int UbixFS::format(dev_t * dev) { return 0; } // UbixFS::format UbixFS::~UbixFS(void) { delete [] freeBlockList; return; }