diff --git a/src/sys/ubixfsv2/btree.h b/src/sys/ubixfsv2/btree.h index ce78c4c..0ed58de 100644 --- a/src/sys/ubixfsv2/btree.h +++ b/src/sys/ubixfsv2/btree.h @@ -31,6 +31,7 @@ uInt32 treeDepth; uInt32 treeWidth; uInt32 treeLeafCount; + uInt32 firstDeleted; ubixfsInode * treeSearch(bNode *, const char *); ubixfsInode * inodeSearch(ubixfsInode *, const char *); void splitNode(bNode *); diff --git a/src/sys/ubixfsv2/inode.h b/src/sys/ubixfsv2/inode.h index 82ca268..5b83c1b 100644 --- a/src/sys/ubixfsv2/inode.h +++ b/src/sys/ubixfsv2/inode.h @@ -12,7 +12,7 @@ #define INODE_WAS_WRITTEN 0x00020000 #define NO_TRANSACTION 0x00040000 -#define NUM_DIRECT_BLOCKS 12 +#define NUM_DIRECT_BLOCKS 64 #define MAX_FILENAME_LENGTH 256 typedef struct dataStream { diff --git a/src/sys/ubixfsv2/superblock.h b/src/sys/ubixfsv2/superblock.h index b2eaef5..ed5c2e2 100644 --- a/src/sys/ubixfsv2/superblock.h +++ b/src/sys/ubixfsv2/superblock.h @@ -28,6 +28,7 @@ // number of bits needed to shift a block number to get a byte address uInt32 blockShift __attribute__ ((packed)); +// numBlocks must be divisible by 8 for the getFreeBlock function to work off_t numBlocks __attribute__ ((packed)); off_t usedBlocks __attribute__ ((packed)); @@ -36,6 +37,7 @@ int32 blocksPerAG __attribute__ ((packed)); int32 AGShift __attribute__ ((packed)); int32 numAGs __attribute__ ((packed)); + int32 lastUsedAG __attribute__ ((packed)); // flags tells whether the FS is clean (0x434C454E) or dirty (0x44495954) int32 flags __attribute__ ((packed)); diff --git a/src/sys/ubixfsv2/ubixfs.cpp b/src/sys/ubixfsv2/ubixfs.cpp index e625872..1b4ac28 100644 --- a/src/sys/ubixfsv2/ubixfs.cpp +++ b/src/sys/ubixfsv2/ubixfs.cpp @@ -7,6 +7,88 @@ 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; @@ -35,7 +117,6 @@ } // UbixFS::verifyFS - UbixFS::~UbixFS(void) { delete [] freeBlockList; return; diff --git a/src/sys/ubixfsv2/ubixfs.h b/src/sys/ubixfsv2/ubixfs.h index 1102f47..b55247c 100644 --- a/src/sys/ubixfsv2/ubixfs.h +++ b/src/sys/ubixfsv2/ubixfs.h @@ -5,7 +5,10 @@ class UbixFS { protected: - unsigned char * freeBlockList; + signed char * freeBlockList; + diskSuperBlock * superBlock; + int32 getFreeBlock(uInt32); + int32 getFreeBlock(void); public: UbixFS(void); bool init(void);