int main(int argc, char * argv[]) { assert(argc == 3); int fd = open(argv[1], O_RDWR); assert(fd >= 0); char ** fileNames = parsePath(argv[2]); // Super * super = Super_(fd); GroupDesc * groupDesc = Bgd_(fd); // char buf[BLOCK_SIZE]; // for (int i = 0; i < 5; i++) { // int ino = ialloc(fd); // printf("allocated ino = %d\n", ino); // } // printBitmap(fd, (int) super->s_inodes_count, // (int) groupDesc->bg_inode_bitmap); // printBitmap(fd, (int) super->s_blocks_count, // (int) groupDesc->bg_block_bitmap); Inode * target = groupSearch(fd, fileNames, groupDesc); if (target == NULL) { printf("main: unable to find "); printArray(fileNames); } else { inodeShow(fd, target); } close(fd); return EXIT_SUCCESS; }
static bool groupSearch(int level, int numBlocks, Block parentBlock, Block* result) { int parLevel = getBlockLevel(parentBlock); if(parLevel == level - 1) { if(findGroupInBlock(parentBlock, numBlocks, result, NULL)) return true; } for(int i = 0; i < numSubblocks[parLevel]; i++) { Block sub = getNthSubblock(parentBlock, i); if(getBlockStatus(sub) == SUBDIV) { if(groupSearch(level, numBlocks, sub, result)) return true; } } return false; }
static bool allocBlocks(int level, int numBlocks, Block* result) { //printf("Allocating %d blocks at level %d\n", numBlocks, level); if(level == 0) { //printf(" Will attempt to find top-level group of %d blocks.\n", numBlocks); return findTopLevelGroup(numBlocks, result); } //Need to find subblock(s) //Best to worst options: //-Use same parent block from last allocation //-Allocate new parent block somewhere else //-Depth-first search subdivided blocks looking for free blocks //-Return false //First try lastParents int bestOvershootParent = -1; int bestOvershoot = 0xFFFF; int overshoot = 0; for(int i = 0; i < PARENT_SAVES; i++) { if(validBlock(lastParents[level][i])) { if(findGroupInBlock(lastParents[level][i], numBlocks, result, &overshoot)) { if(overshoot < bestOvershoot) { bestOvershoot = overshoot; bestOvershootParent = i; } } } } if(bestOvershootParent != -1) { Block use = lastParents[level][bestOvershootParent]; if(!findGroupInBlock(use, numBlocks, result, NULL)) { //This should never ever happen //puts("VERY FATAL ERROR: CHECK FOUND LAST_PARENT CASE"); return false; } //puts("Allocation successful via lastParents"); //printf("Resulting block group: "); //printBlock(*result); //puts(""); allocGroup(*result, numBlocks); return true; } //lastParents must be updated //If one is not yet valid, set it to a newly allocated block //Immediately use subblocks of that new block to fulfill current request //puts("Did not find good cached parent block."); bool allValid = true; Block* toReplace; for(int i = 0; i < PARENT_SAVES; i++) { if(!validBlock(lastParents[level][i])) { allValid = false; toReplace = &lastParents[level][i]; break; } } if(!allValid) { bool success = replaceParentSave(toReplace, level - 1); if(success) { //use *toReplace (now a fresh subdivded block) as parent *result = getFirstSubblock(*toReplace); allocGroup(*result, numBlocks); //puts("Allocation successful via newParent"); return true; } } else { int worstGroup = 100; int worstBlock = -1; for(int i = 0; i < PARENT_SAVES; i++) { int thisGroup = getMaxGroup(lastParents[level][i]); if(thisGroup < worstGroup) { worstGroup = thisGroup; worstBlock = i; } } toReplace = &lastParents[level][worstBlock]; //replace worstBlock bool success = replaceParentSave(toReplace, level - 1); if(success) { *result = getFirstSubblock(*toReplace); allocGroup(*result, numBlocks); return true; //puts("Allocation sucessful via new parent."); } } //If here, then depth-first search for an appropriate parent block //that isn't necesarily listed in lastParent. Block first; for(int i = 0; i < numSubblocks[0]; i++) { Block topLevel = {{i, -1, -1, -1}}; if(getBlockStatus(topLevel) == SUBDIV) { if(groupSearch(level, numBlocks, topLevel, &first)) { *result = first; allocGroup(*result, numBlocks); return true; //puts("Allocation successful via worst-case dfs for parent"); } } } //puts("Block group allocation failed!"); return false; }