Newer
Older
ubixos / src / sys / ubixfsv2 / ubixfs.cpp
#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::verifyFS(void) {
  return true;

} // UbixFS::verifyFS

UbixFS::~UbixFS(void) {
  delete [] freeBlockList;
  return;
}