/* * Format a drive with GOSFS. */ int GOSFS_Format(struct Block_Device *blockDev) { uint_t numDiskBlocks = blockDev->ops->Get_Num_Blocks(blockDev); uint_t numGOSFSBlocks = numDiskBlocks/DISK_BLOCKS_PER_GOSFS; /* Allocate 4KB for super block */ GOSFSsuperblock *super = Safe_Calloc(PAGE_SIZE); /* Creating bitmap and memcpying to super is redudant, so I skipped it */ /* Create root directory */ GOSFSdirectory *rootDir = Safe_Calloc(PAGE_SIZE); /* Initialize values in the super block */ super->rootDir = 1; // Rootdir will be at GOSFS block[1] super->size = numGOSFSBlocks; Set_Bit(&super->bitmap, 0); // GOSFS block[0] used for superblock Set_Bit(&super->bitmap, 1); // GOSFS block[1] used for root dir super->magic = GOSFS_MAGIC; /* Write superblock to disk */ GOSFS_Block_Write(blockDev, 0, super); /* Write root dir to disk */ GOSFS_Block_Write(blockDev, 1, rootDir); /* Free memory used */ Free(super); Free(rootDir); return 0; }
/* ein Byte in das ???-Register des ST7036 senden */ void ST7036_write_byte( char data ) { signed char u8_zahl = 8; char c_data; // Chip-Select auf log.0 Clear_Bit( ST7036_CSB ); c_data = data; do { _delay_loop_2(6); if ( c_data & 0x80 ) // oberstes Bit von c_data betrachten Set_Bit(ST7036_SI); // und Datenleitung entsprechend setzen else Clear_Bit(ST7036_SI); _delay_loop_2(5); // einen Clockpuls erzeugen Clear_Bit(ST7036_CLK); _delay_loop_2(6); Set_Bit(ST7036_CLK); c_data = c_data << 1; u8_zahl --; } while (u8_zahl > 0); // Chip-Select wieder auf log.1 warte_ms( 2 ); Set_Bit( ST7036_CSB ); }
int Server_Creat(int pinum, int type, char *name){ Data_Init(); if(Inode_BitMap.bits[pinum] == false || inode_table[pinum].type != MFS_DIRECTORY){ return -1; } if(Server_LookUp(pinum,name) >= 0){ return 0; } int inum = First_Empty(&Inode_BitMap); Set_Bit(&Inode_BitMap, inum); if(Add_Entry(pinum, inum, name, inode_table, data_region) != 0){ fprintf(stderr,"add entry error\n"); } if(type == MFS_REGULAR_FILE){ inode_table[inum].type = type; inode_table[inum].size = 0; inode_table[inum].blocks = 0; int i; for(i = 0; i < MFS_PTR_NUMS; i++){ inode_table[inum].ptr[i] = -1; } } if(type == MFS_DIRECTORY){ int to_write_block = First_Empty(&Data_BitMap); Set_Bit(&Data_BitMap,to_write_block); inode_table[inum].type = type; inode_table[inum].size = 2 * sizeof(MFS_DirEnt_t); inode_table[inum].blocks = 1; inode_table[inum].ptr[0] = to_write_block; int i; for(i = 1; i < MFS_PTR_NUMS; i++){ inode_table[inum].ptr[i] = -1; } MFS_DirEnt_t * entries = (MFS_DirEnt_t *) data_region[to_write_block].data; entries[0].inum = inum; strcpy(entries[0].name, "."); entries[1].inum = pinum; strcpy(entries[1].name, ".."); for(i = 2; i < MFS_BLOCK_SIZE / sizeof(MFS_DirEnt_t); i++){ entries[i].inum = -1; } } Data_Write(); return 0; }
/* * Format a drive with GOSFS. */ int GOSFS_Format(struct Block_Device *blockDev) { GOSFSsuperblock *superblock; GOSFSdirectory *rootDir; int rc; /* Allocate space for superblock */ superblock = Malloc(sizeof(GOSFSsuperblock)); rootDir = Malloc(sizeof(GOSFSdirectory)); if (superblock == 0 || rootDir == 0) goto memfail; /* Zero out superblock and root directory for new filesystem */ memset(superblock, '\0', sizeof(GOSFSsuperblock)); memset(rootDir, '\0', sizeof(GOSFSdirectory)); /* Set magic number and calculate disk size */ superblock->magic = GOSFS_MAGIC; superblock->size = blockDev->ops->Get_Num_Blocks(blockDev) * SECTOR_SIZE; /* Write the root directory to block 1 (following the superblock */ superblock->rootDirPointer = 1; rc = writeGOSFSBlock(blockDev, 1, rootDir, sizeof(GOSFSdirectory)); if (rc < 0) goto fail; /* Mark the superblock (0) and root dir block as taken */ Set_Bit(superblock->freeBlocks, 0); Set_Bit(superblock->freeBlocks, 1); /* Write out the superblock */ rc = writeGOSFSBlock(blockDev, GOSFS_SUPERBLOCK, superblock, sizeof(GOSFSsuperblock)); if (rc < 0) goto fail; /* Free allocated structures */ Free(superblock); Free(rootDir); return 0; memfail: rc = ENOMEM; goto fail; fail: if (superblock) Free(superblock); if (rootDir) Free(rootDir); return rc; }
void add_block(int inum){ if(Inode_BitMap.bits[inum] == false){ fprintf(stderr,"error\n"); exit(-1); } if(inode_table[inum].type != MFS_DIRECTORY ){ fprintf(stderr, "error\n"); exit(-1); } int i; for(i = 0; i < MFS_PTR_NUMS; i ++){ if(inode_table[inum].ptr[i] == -1){ break; } } int curr_block = First_Empty(&Data_BitMap); inode_table[inum].ptr[i] = curr_block; Set_Bit(&Data_BitMap, curr_block); inode_table[inum].blocks++; MFS_DirEnt_t *entries = (MFS_DirEnt_t *)data_region[curr_block].data; for(i = 0; i < MFS_BLOCK_SIZE / sizeof(MFS_DirEnt_t); i++){ entries[i].inum = -1; } }
// positioniert den Cursor auf x/y. // 0/0 ist links oben, 2/15 ist rechts unten void ST7036_goto_xy(unsigned char xwert, unsigned char ywert) { //_delay_loop_2(50000); ST7036_write_command_byte(0x80 + ywert*0x20 + xwert); //_delay_loop_2(50000); Set_Bit(ST7036_RS); }
/* Reset durchführen */ void ST7036_reset(void) { #ifdef ST7036_RESET Clear_Bit(lcdReset); // Hardware-Reset log.0 an den ST7036 anlegen warte_ms( 100 ); Set_Bit(lcdReset); #endif }
/* ein Byte in das Daten-Register des KS0073 senden */ void ST7036_init(void) { Set_Bit(ST7036_CLK); Set_Bit(ST7036_CSB); //ST7036_reset(); warte_ms(50); // mehr als 40ms warten // ST7036_write_command_byte( 0x38 ); // Function set; 8 bit Datenlänge, 2 Zeilen warte_us(50); // mehr als 26,3µs warten ST7036_write_command_byte( 0x39 ); // Function set; 8 bit Datenlänge, 2 Zeilen, Instruction table 1 warte_us(50); // mehr als 26,3µs warten ST7036_write_command_byte( 0x1d ); // Bias Set; BS 1/5; 3 zeiliges Display /1d warte_us(50); // mehr als 26,3µs warten ST7036_write_command_byte( 0x7c ); // Kontrast C3, C2, C1 setzen /7c warte_us(50); // mehr als 26,3µs warten ST7036_write_command_byte( 0x50 ); // Booster aus; Kontrast C5, C4 setzen /50 warte_us(50); // mehr als 26,3µs warten ST7036_write_command_byte( 0x6c ); // Spannungsfolger und Verstärkung setzen /6c warte_ms( 500 ); // mehr als 200ms warten !!! ST7036_write_command_byte( 0x0f ); // Display EIN, Cursor EIN, Cursor BLINKEN /0f warte_us(50); // mehr als 26,3µs warten ST7036_write_command_byte( 0x01 ); // Display löschen, Cursor Home warte_ms(400); // ST7036_write_command_byte( 0x06 ); // Cursor Auto-Increment warte_us(50); // mehr als 26,3µs warten }
int Create_Semaphore(char *name, int nameLength, int initCount) { int sid = 0; int ret = -1; /* Syscall contract */ KASSERT(name != NULL); KASSERT(0 < nameLength && nameLength <= MAX_SEMAPHORE_NAME); KASSERT(0 <= initCount); KASSERT(strnlen(name, MAX_SEMAPHORE_NAME) == nameLength); bool atomic = Begin_Int_Atomic(); sid = isSemaphoreCreated(name, nameLength); KASSERT(sid < 0 || sid < MAX_NUM_SEMAPHORES); KASSERT(g_currentThread->semaphores != NULL); /* Negative sid for non existing, otherwise sid is Semaphore ID */ if (0 <= sid) { /* Already created semaphore */ g_Semaphores[sid].references++; Set_Bit(g_currentThread->semaphores, sid); ret = sid; } else { /* Semaphore not created. Create. */ sid = getFreeSemaphore(); if (sid < 0) { /* No semaphores available */ ret = EUNSPECIFIED; } else { strncpy(g_Semaphores[sid].name, name, MAX_SEMAPHORE_NAME); g_Semaphores[sid].resources = initCount; g_Semaphores[sid].available = false; g_Semaphores[sid].references = 1; Clear_Thread_Queue(&g_Semaphores[sid].waitingThreads); Set_Bit(g_currentThread->semaphores, sid); ret = sid; } } End_Int_Atomic(atomic); return ret; }
int main() { void *bitset = Create_Bit_Set(100); assert(Find_First_Free_Bit(bitset,100) == 0); Set_Bit(bitset, 0); assert(Find_First_Free_Bit(bitset,100) == 1); Set_Bit(bitset, 1); assert(Find_First_Free_Bit(bitset,100) == 2); Set_Bit(bitset, 3); assert(Find_First_Free_Bit(bitset,100) == 2); Set_Bit(bitset, 4); Set_Bit(bitset, 5); Set_Bit(bitset, 6); Set_Bit(bitset, 7); assert(Find_First_Free_Bit(bitset,100) == 2); Set_Bit(bitset, 2); assert(Find_First_Free_Bit(bitset,100) == 8); Clear_Bit(bitset, 2); assert(Find_First_Free_Bit(bitset,100) == 2); }
int Server_Write(int inum, char * buffer, int block){ int i; Data_Init(); if(Inode_BitMap.bits[inum] == false){ return -1; } if(inode_table[inum].type != MFS_REGULAR_FILE){ return -1; } if(block < 0 || block > 9){ return -1; } int to_write_block; if(inode_table[inum].ptr[block] == -1){ to_write_block = First_Empty(&Data_BitMap); Set_Bit(&Data_BitMap,to_write_block); for(i = 0; i <= block; i++){ if(inode_table[inum].ptr[i] == -1){ inode_table[inum].size += MFS_BLOCK_SIZE; inode_table[inum].blocks ++; } } inode_table[inum].ptr[block] = to_write_block; }else{ to_write_block = inode_table[inum].ptr[block]; } for(i = 0; i < MFS_BLOCK_SIZE; i++){ data_region[to_write_block].data[i] = buffer[i]; } Data_Write(); return 0; }
void Double_Indirect_Set_Helper(struct Block_Device *dev, GOSFSsuperblock *super, int *array, int index, int blockNum) { int *arr = Safe_Calloc(PAGE_SIZE); int *empty = Safe_Calloc(PAGE_SIZE); int newBlock = 0; if (array[index/INT_ARR_SIZE] == 0) { newBlock = Find_First_Free_Bit(&super->bitmap, super->size); Set_Bit(&super->bitmap, newBlock); array[index/INT_ARR_SIZE] = newBlock; GOSFS_Block_Write(dev, newBlock, empty); } GOSFS_Block_Read(dev, array[index/INT_ARR_SIZE], arr); arr[index % INT_ARR_SIZE] = blockNum; GOSFS_Block_Write(dev, blockNum, empty); GOSFS_Block_Write(dev, array[index/INT_ARR_SIZE], arr); Free(empty); Free(arr); }
int Double_Indirect_Helper(struct Block_Device *dev, GOSFSsuperblock *super, int *array, int index) { int blockNum = 0; int tempBlock = 0; int *arr = Safe_Calloc(PAGE_SIZE); int *empty = Safe_Calloc(PAGE_SIZE); if (array[index/INT_ARR_SIZE] == 0) { blockNum = 0; /* Allocate block for double indirect */ tempBlock = Find_First_Free_Bit(&super->bitmap, super->size); Set_Bit(&super->bitmap, tempBlock); array[index/INT_ARR_SIZE] = tempBlock; GOSFS_Block_Write(dev, array[index/INT_ARR_SIZE], empty); } else { GOSFS_Block_Read(dev, array[index/INT_ARR_SIZE], arr); blockNum = arr[index % INT_ARR_SIZE]; } Free(empty); Free(arr); return blockNum; }
*/ REBSER *Parse_String(REBSER *series, REBCNT index, REBVAL *rules, REBCNT flags) /* ***********************************************************************/ { REBCNT tail = series->tail; REBSER *blk; REBSER *set; REBCNT begin; REBCNT end; REBOOL skip_spaces = !(flags & PF_ALL); REBUNI uc; blk = BUF_EMIT; // shared series RESET_SERIES(blk); // String of delimiters or single character: if (IS_STRING(rules) || IS_CHAR(rules)) { begin = Find_Max_Bit(rules); if (begin <= ' ') begin = ' ' + 1; set = Make_Bitset(begin); Set_Bits(set, rules, TRUE); } // None, so use defaults ",;": else { set = Make_Bitset(1+MAX(',',';')); Set_Bit(set, ',', TRUE); Set_Bit(set, ';', TRUE); } SAVE_SERIES(set); // If required, make space delimiters too: if (skip_spaces) { for (uc = 1; uc <= ' '; uc++) Set_Bit(set, uc, TRUE); } while (index < tail) { if (--Eval_Count <= 0 || Eval_Signals) Do_Signals(); // Skip whitespace if not /all refinement: if (skip_spaces) { uc = 0; for (; index < tail; index++) { uc = GET_ANY_CHAR(series, index); if (!IS_WHITE(uc)) break; } } else uc = GET_ANY_CHAR(series, index); // prefetch if (index < tail) { // Handle quoted strings (in a simple way): if (uc == '"') { begin = ++index; // eat quote for (; index < tail; index++) { uc = GET_ANY_CHAR(series, index); if (uc == '"') break; } end = index; if (index < tail) index++; } // All other tokens: else { begin = index; for (; index < tail; index++) { if (Check_Bit(set, GET_ANY_CHAR(series, index), !(flags & PF_CASE))) break; } end = index; } // Skip trailing spaces: if (skip_spaces) for (; index < tail; index++) { uc = GET_ANY_CHAR(series, index); if (!IS_WHITE(uc)) break; } // Check for and remove separator: if (Check_Bit(set, GET_ANY_CHAR(series, index), !(flags & PF_CASE))) index++; // Append new string: Set_String(Append_Value(blk), Copy_String(series, begin, end - begin)); } } UNSAVE_SERIES(set); return Copy_Block(blk, 0); }
/* Grows a file by one block (from the end position) and, if necessary, * allocates indirect or double indirect blocks to contain this * new block. */ static int growFile(struct File *file) { GOSFSinstance *instance = (GOSFSinstance *) file->mountPoint->fsData; GOSFSsuperblock *superblock = instance->superblock; GOSFSptr *filePtr = (GOSFSptr *) file->fsData; GOSFSfileNode *node = &filePtr->node; GOSFSdirectory *dir; ulong_t nextBlock = file->endPos / GOSFS_BLOCK_SIZE; char *buf; int *indirect = 0, *doubleIndirect = 0; int rc, newBlock; buf = Malloc(GOSFS_BLOCK_SIZE); indirect = Malloc(GOSFS_BLOCK_SIZE); doubleIndirect = Malloc(GOSFS_BLOCK_SIZE); dir = Malloc(sizeof(GOSFSdirectory)); if (!buf || !indirect || !doubleIndirect || !dir) goto memfail; if (nextBlock < INDIRECT_BLOCK_START) { /* This is a simple direct block */ rc = Find_First_Free_Bit(superblock->freeBlocks, superblock->size); if (rc < 0) goto fail; node->blocks[nextBlock] = rc; newBlock = rc; } else if (nextBlock < DOUBLE_INDIRECT_BLOCK_START) { /* Check for indirect block existence */ if (node->blocks[INDIRECT_BLOCK] == 0) { /* Need to create indirect block */ rc = Find_First_Free_Bit(superblock->freeBlocks, superblock->size); if (rc < 0) goto fail; /* Update (cached) file node */ node->blocks[INDIRECT_BLOCK] = rc; newBlock = rc; /* Write out zero-filled block */ memset(buf, '\0', GOSFS_BLOCK_SIZE); rc = writeGOSFSBlock(instance->dev, newBlock, buf, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; /* Claim bit */ Set_Bit(superblock->freeBlocks, newBlock); /* "Read" indirect block by copying it to array */ memcpy(indirect, buf, GOSFS_BLOCK_SIZE); } else { /* Read in indirect block */ rc = readGOSFSBlock(instance->dev, node->blocks[INDIRECT_BLOCK], indirect, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; } rc = Find_First_Free_Bit(superblock->freeBlocks, superblock->size); if (rc < 0) goto fail; /* Update block array */ indirect[nextBlock - INDIRECT_BLOCK_START] = rc; newBlock = rc; /* Write out updated block array to disk */ rc = writeGOSFSBlock(instance->dev, node->blocks[INDIRECT_BLOCK], indirect, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; } else if (nextBlock < MAX_BLOCK) { /* Check for indirect block existence */ if (node->blocks[DOUBLE_INDIRECT_BLOCK] == 0) { /* Need to create indirect block */ rc = Find_First_Free_Bit(superblock->freeBlocks, superblock->size); if (rc < 0) goto fail; /* Update (cached) file node */ node->blocks[DOUBLE_INDIRECT_BLOCK] = rc; newBlock = rc; /* Write out zero-filled block */ memset(buf, '\0', GOSFS_BLOCK_SIZE); rc = writeGOSFSBlock(instance->dev, newBlock, buf, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; /* Claim bit */ Set_Bit(superblock->freeBlocks, newBlock); /* "Read" indirect block by copying it to array */ memcpy(indirect, buf, GOSFS_BLOCK_SIZE); } else { /* Read in indirect block */ rc = readGOSFSBlock(instance->dev, node->blocks[DOUBLE_INDIRECT_BLOCK], indirect, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; } /* Check for double indirect block existence */ if (indirect[(nextBlock - DOUBLE_INDIRECT_BLOCK_START) / (GOSFS_BLOCK_SIZE / sizeof(int))] == 0) { /* Need to create second indirect block */ rc = Find_First_Free_Bit(superblock->freeBlocks, superblock->size); if (rc < 0) goto fail; /* Update indirect block */ indirect[(nextBlock - DOUBLE_INDIRECT_BLOCK_START) / (GOSFS_BLOCK_SIZE / sizeof(int))] = rc; newBlock = rc; Set_Bit(superblock->freeBlocks, newBlock); /* Write out zero-filled block */ memset(buf, '\0', GOSFS_BLOCK_SIZE); rc = writeGOSFSBlock(instance->dev, newBlock, buf, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; /* Write out updated indirect block */ rc = writeGOSFSBlock(instance->dev, node->blocks[DOUBLE_INDIRECT_BLOCK], indirect, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; /* "Read" double indirect block by copying array */ memcpy(doubleIndirect, buf, GOSFS_BLOCK_SIZE); } else { /* Read in double indirect block */ rc = indirect[(nextBlock - DOUBLE_INDIRECT_BLOCK_START) / (GOSFS_BLOCK_SIZE / sizeof(int))]; rc = readGOSFSBlock(instance->dev, rc, doubleIndirect, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; } /* Now finally we can allocate a block for the double indirect layer */ rc = Find_First_Free_Bit(superblock->freeBlocks, superblock->size); if (rc < 0) goto fail; doubleIndirect[(nextBlock - DOUBLE_INDIRECT_BLOCK_START) % (GOSFS_BLOCK_SIZE / sizeof(int))] = rc; newBlock = rc; /* Write out updated double indirect block */ rc = indirect[(nextBlock - DOUBLE_INDIRECT_BLOCK_START) / (GOSFS_BLOCK_SIZE / sizeof(int))]; rc = writeGOSFSBlock(instance->dev, rc, doubleIndirect, GOSFS_BLOCK_SIZE); if (rc < 0) goto fail; } else { /* This would be triple indirect and above */ rc = EINVALID; goto fail; } /* Now update file node on disk */ rc = readGOSFSBlock(instance->dev, filePtr->blockNum, dir, sizeof(GOSFSdirectory)); if (rc < 0) goto fail; memcpy(&dir->files[filePtr->offset], node, sizeof(GOSFSfileNode)); rc = writeGOSFSBlock(instance->dev, filePtr->blockNum, dir, sizeof(GOSFSdirectory)); Set_Bit(superblock->freeBlocks, newBlock); /* Now update superblock */ rc = writeGOSFSBlock(instance->dev, GOSFS_SUPERBLOCK, superblock, sizeof(GOSFSsuperblock)); if (rc < 0) goto fail; Free(buf); Free(indirect); Free(doubleIndirect); Free(dir); return newBlock; memfail: rc = ENOMEM; goto fail; fail: if (buf) Free(buf); if (indirect) Free(indirect); if (doubleIndirect) Free(doubleIndirect); if (dir) Free(dir); return rc; }
/* * Create a directory named by given path. */ int GOSFS_Create_Directory(struct Mount_Point *mountPoint, const char *path) { GOSFSinstance *instance = (GOSFSinstance *) mountPoint->fsData; GOSFSfileNode *filePtr = 0; GOSFSdirectory *dir, *newDir; char *file = path, *nextSlash; int rc, offset, i; uint_t parentBlock; /* Malloc data for file node and directory */ newDir = Malloc(sizeof(GOSFSdirectory)); dir = Malloc(sizeof(GOSFSdirectory)); if (dir == 0 || newDir == 0) goto memfail; /* Point to the root directory and read in contents... */ parentBlock = instance->superblock->rootDirPointer; readGOSFSBlock(instance->dev, parentBlock, dir, sizeof(GOSFSdirectory)); /* Iterate until there are no remaining slashes */ while ((nextSlash = strchr(file + 1, '/'))) { /* Ignores leading '/' character */ file += 1; offset = nextSlash - file; filePtr = lookupFileInDirectory(dir, file, offset); if (!filePtr) { /* Need to create a directory */ /* Make sure name is not too long */ if (offset >= sizeof(dir->files[0].name)) goto fail; /* First find a free spot in the directory */ for (i = 0; i < MAX_FILES_PER_DIR; i++) { if (!dir->files[i].isUsed) { offset = i; break; } } if (offset == -1) /* No free space in directory */ goto fail; /* Now set up the file node at that point */ filePtr = &dir->files[i]; memset(filePtr, '\0', sizeof(GOSFSfileNode)); filePtr->isUsed = true; filePtr->isDirectory = true; memcpy(filePtr->name, file, offset); /* Allocate an empty block for this directory */ rc = Find_First_Free_Bit(instance->superblock->freeBlocks, instance->superblock->size); if (rc < 0) goto fail; Set_Bit(instance->superblock->freeBlocks, rc); /* Clear out this new directory */ memset(newDir, '\0', sizeof(GOSFSdirectory)); filePtr->blocks[0] = rc; rc = writeGOSFSBlock(instance->dev, rc, newDir, sizeof(GOSFSdirectory)); if (rc < 0) goto fail; /* Now write out the updated parent directory to disk */ rc = writeGOSFSBlock(instance->dev, parentBlock, dir, sizeof(GOSFSdirectory)); if (rc < 0) goto fail; } if (!filePtr->isDirectory) goto fail; /* Read in the directory this file node represents */ parentBlock = filePtr->blocks[0]; rc = readGOSFSBlock(instance->dev, parentBlock, dir, sizeof(GOSFSdirectory)); if (rc < 0) goto fail; file = nextSlash; } file += 1; /* Make sure this doesn't exist */ filePtr = lookupFileInDirectory(dir, file, strlen(file)); if (filePtr) goto fail; /* Create the final directory */ /* Make sure name is not too long */ if (strlen(file) >= sizeof(dir->files[0].name)) goto fail; /* First find a free spot in the directory */ for (i = 0; i < MAX_FILES_PER_DIR; i++) { if (!dir->files[i].isUsed) { offset = i; break; } } if (offset == -1) /* No free space in directory */ goto fail; /* Now set up the file node at that point */ filePtr = &dir->files[i]; memset(filePtr, '\0', sizeof(GOSFSfileNode)); filePtr->isUsed = true; filePtr->isDirectory = true; memcpy(filePtr->name, file, strlen(file)); /* Allocate an empty block for this directory */ rc = Find_First_Free_Bit(instance->superblock->freeBlocks, instance->superblock->size); if (rc < 0) goto fail; Set_Bit(instance->superblock->freeBlocks, rc); /* Clear out this new directory */ memset(newDir, '\0', sizeof(GOSFSdirectory)); filePtr->blocks[0] = rc; rc = writeGOSFSBlock(instance->dev, rc, newDir, sizeof(GOSFSdirectory)); if (rc < 0) goto fail; /* Now write out the updated directory to disk */ rc = writeGOSFSBlock(instance->dev, parentBlock, dir, sizeof(GOSFSdirectory)); if (rc < 0) goto fail; /* Write out the updated superblock */ rc = writeGOSFSBlock(instance->dev, GOSFS_SUPERBLOCK, instance->superblock, sizeof(GOSFSsuperblock)); if (rc < 0) goto fail; Free(dir); return 0; memfail: rc = ENOMEM; goto fail; fail: if (dir) Free(dir); return rc; }
int Image_Init(const char * filename){ int fd, i; if((fd = open(filename,O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) == -1){ exit(-1); } BitMap_Init(&Inode_BitMap); BitMap_Init(&Data_BitMap); for(i = 0; i < MFS_BLOCK_NUMS; i++){ Inode_Init(&inode_table[i]); } inode_table[0].type = MFS_DIRECTORY; inode_table[0].size = 2 * sizeof(MFS_DirEnt_t); inode_table[0].blocks = 1; inode_table[0].ptr[0] = 0; MFS_DirEnt_t *root_dot = (MFS_DirEnt_t *)data_region[0].data; MFS_DirEnt_t *root_dotdot = root_dot + 1; root_dot -> inum = 0; strcpy(root_dot -> name,"."); root_dotdot -> inum = 0; strcpy(root_dotdot -> name, ".."); int j; for(j = 2; j < MFS_BLOCK_SIZE / sizeof(MFS_DirEnt_t); j ++){ (root_dot + j) -> inum = -1; } Set_Bit(&Inode_BitMap, 0); Set_Bit(&Data_BitMap,0); if(write(fd, &Inode_BitMap, sizeof(Bitmap_t)) != sizeof(Bitmap_t)){ fprintf(stderr, "write error\n"); exit(-1); } if(write(fd,&Data_BitMap, sizeof(Bitmap_t)) != sizeof(Bitmap_t)){ fprintf(stderr,"write error\n"); exit(-1); } if(write(fd,inode_table, MFS_BLOCK_NUMS*sizeof(Inode_t)) != MFS_BLOCK_NUMS*sizeof(Inode_t)){ fprintf(stderr,"write error\n"); exit(-1); } if(write(fd,data_region, MFS_BLOCK_NUMS*sizeof(Block_t)) != MFS_BLOCK_NUMS*sizeof(Block_t)){ fprintf(stderr,"write error\n"); exit(-1); } fsync(fd); return fd; }
/* * Read function for PFAT files. */ static int PFAT_Read(struct File *file, void *buf, ulong_t numBytes) { struct PFAT_File *pfatFile = (struct PFAT_File*) file->fsData; struct PFAT_Instance *instance = (struct PFAT_Instance*) file->mountPoint->fsData; ulong_t start = file->filePos; ulong_t end = file->filePos + numBytes; ulong_t startBlock, endBlock, curBlock; ulong_t i; /* Special case: can't handle reads longer than INT_MAX */ if (numBytes > INT_MAX) return EINVALID; /* Make sure request represents a valid range within the file */ if (start >= file->endPos || end > file->endPos || end < start) { Debug("Invalid read position: filePos=%lu, numBytes=%lu, endPos=%lu\n", file->filePos, numBytes, file->endPos); return EINVALID; } /* * Now the complicated part; ensure that all blocks containing the * data we need are in the file data cache. */ startBlock = (start % SECTOR_SIZE) / SECTOR_SIZE; endBlock = Round_Up_To_Block(end) / SECTOR_SIZE; /* * Traverse the FAT finding the blocks of the file. * As we encounter requested blocks that aren't in the * file data cache, we issue requests to read them. */ curBlock = pfatFile->entry->firstBlock; for (i = 0; i < endBlock; ++i) { /* Are we at a valid block? */ if (curBlock == FAT_ENTRY_FREE || curBlock == FAT_ENTRY_EOF) { Print("Unexpected end of file in FAT at file block %lu\n", i); return EIO; /* probable filesystem corruption */ } /* Do we need to read this block? */ if (i >= startBlock) { int rc = 0; /* Only allow one thread at a time to read this block. */ Mutex_Lock(&pfatFile->lock); if (!Is_Bit_Set(pfatFile->validBlockSet, i)) { /* Read block into the file data cache */ Debug("Reading file block %lu (device block %lu)\n", i, curBlock); rc = Block_Read(file->mountPoint->dev, curBlock, pfatFile->fileDataCache + i*SECTOR_SIZE); if (rc == 0) /* Mark as having read this block */ Set_Bit(pfatFile->validBlockSet, i); } /* Done attempting to fetch the block */ Mutex_Unlock(&pfatFile->lock); if (rc != 0) return rc; } /* Continue to next block */ ulong_t nextBlock = instance->fat[curBlock]; curBlock = nextBlock; } /* * All cached data we need is up to date, * so just copy it into the caller's buffer. */ memcpy(buf, pfatFile->fileDataCache + start, numBytes); Debug("Read satisfied!\n"); return numBytes; }
/* * Gets the next block num we need to write to. Also handles setting blocks * array in the node to the new block num */ int Get_Blocknum_To_Write(struct File *file) { int blockNum = 0; int tempBlock = 0; int index = ((int)file->filePos) / PAGE_SIZE; int *array = Safe_Calloc(PAGE_SIZE); void *empty = Safe_Calloc(PAGE_SIZE); GOSFSptr *entry = (GOSFSptr *)file->fsData; GOSFSfileNode *node = &entry->node; GOSFSsuperblock *super = (GOSFSsuperblock *)file->mountPoint->fsData; struct Block_Device *dev = file->mountPoint->dev; /* Return the block num we need to write to, or 0 if it doesn't exist */ if (index < SINGLE_BLOCK) { blockNum = node->blocks[index]; } else if (index > SINGLE_MIN_INDEX && index < SINGLE_MAX_INDEX) { if (node->blocks[SINGLE_BLOCK] == 0) { blockNum = 0; /* Allocate new block for single indirect */ tempBlock = Find_First_Free_Bit(&super->bitmap, super->size); Set_Bit(&super->bitmap, tempBlock); node->blocks[SINGLE_BLOCK] = tempBlock; GOSFS_Block_Write(dev, tempBlock, empty); } else { GOSFS_Block_Read(dev, node->blocks[SINGLE_BLOCK], array); blockNum = array[index - SINGLE_BLOCK]; } } else { if (node->blocks[DBL_BLOCK] == 0) { blockNum = 0; /* Allocate new block for double indirect */ tempBlock = Find_First_Free_Bit(&super->bitmap, super->size); Set_Bit(&super->bitmap, tempBlock); node->blocks[DBL_BLOCK] = tempBlock; GOSFS_Block_Write(dev, tempBlock, empty); } else { GOSFS_Block_Read(dev, node->blocks[DBL_BLOCK], array); blockNum = Double_Indirect_Helper(dev, super, array, index - SINGLE_MAX_INDEX); GOSFS_Block_Write(dev, node->blocks[DBL_BLOCK], array); // In case array changed } } /* If it does not exist than we need to allocate a new block */ if (blockNum == 0) { blockNum = Find_First_Free_Bit(&super->bitmap, super->size); Set_Bit(&super->bitmap, blockNum); // Set the super bit map if (index < SINGLE_BLOCK) { node->blocks[index] = blockNum; GOSFS_Block_Write(dev, node->blocks[index], empty); } else if (index > SINGLE_MIN_INDEX && index < SINGLE_MAX_INDEX) { GOSFS_Block_Read(dev, node->blocks[SINGLE_BLOCK], array); array[index - SINGLE_BLOCK] = blockNum; GOSFS_Block_Write(dev, blockNum, empty); // Write empty array back GOSFS_Block_Write(dev, node->blocks[SINGLE_BLOCK], array); // Write change back } else { GOSFS_Block_Read(dev, node->blocks[DBL_BLOCK], array); Double_Indirect_Set_Helper(dev, super, array, index - SINGLE_MAX_INDEX, blockNum); GOSFS_Block_Write(dev, node->blocks[DBL_BLOCK], array); } } Free(empty); Free(array); return blockNum; }
/* ein Byte in das Daten-Register des KS0073 senden */ void ST7036_write_data_byte( char data ) { Set_Bit( ST7036_RS ); _delay_loop_2( 7 ); ST7036_write_byte( data ); }
/* * Create a directory named by given path. */ int GOSFS_Create_Directory(struct Mount_Point *mountPoint, const char *path) { int rc = 0; int blockNum = 0; // The GOSFS block the fileNode(file or dir) exists in int newBlock = 0; int index = 0; char name[MAX_NAME_SIZE] = {}; bool found = 0; GOSFSfileNode *currNode = 0; GOSFSsuperblock *super = (GOSFSsuperblock *)mountPoint->fsData; GOSFSptr *gosfsEntry = Safe_Calloc(sizeof(GOSFSptr)); GOSFSdirectory *currDir = Safe_Calloc(PAGE_SIZE); /* Grab the root directory from the disk */ GOSFS_Block_Read(mountPoint->dev, super->rootDir, currDir); blockNum = super->rootDir; /* Create all of the directories in the path if they don't exist */ while (*path != 0) { memset(name, '\0', MAX_NAME_SIZE); memset(gosfsEntry, '\0', sizeof(GOSFSptr)); newBlock = 0; currNode = 0; Get_Next_Name_In_Path(&path, name); found = GOSFS_Lookup(currDir, name, blockNum, gosfsEntry); /* If last element in path exists then fail */ if (found == true && *path == 0) { rc = EEXIST; goto fail; } /* If anything in path is a file then fail */ if (found == true && gosfsEntry->node.isDirectory == 0) { rc = ENOTDIR; goto fail; } /* If entry is a directory, then go into it */ if (found == true && gosfsEntry->node.isDirectory == 1) { blockNum = gosfsEntry->node.blocks[0]; GOSFS_Block_Read(mountPoint->dev, blockNum, currDir); continue; } /* If entry does not exist, then make it */ if (found == false) { /* Find the next open spot in the directory */ for (index = 0; index < MAX_FILES_PER_DIR; index++) { currNode = &currDir->files[index]; if (currNode->isUsed == 0) { /* Allocate new GOSFS block for new dir */ newBlock = Find_First_Free_Bit(&super->bitmap, super->size); Set_Bit(&super->bitmap, newBlock); /* Set up new dir */ memcpy(currNode->name, name, MAX_NAME_SIZE); currNode->size = MAX_FILES_PER_DIR; currNode->isUsed = 1; currNode->isDirectory = 1; currNode->blocks[0] = newBlock; /* Write changes to the curr dir back to disk */ GOSFS_Block_Write(mountPoint->dev, blockNum, currDir); memset(currDir, '\0', PAGE_SIZE); // new curr dir empty GOSFS_Block_Write(mountPoint->dev, newBlock, currDir); blockNum = newBlock; break; } /* If no more room in curr dir */ if ((index + 1) == MAX_FILES_PER_DIR) { rc = ENOMEM; goto fail; } } } } /* Write super block back to disk */ GOSFS_Block_Write(mountPoint->dev, 0, super); fail: done: Free(currDir); Free(gosfsEntry); return rc; }