Beispiel #1
0
/*
 * 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 );
}
Beispiel #3
0
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;
}
Beispiel #5
0
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

}
Beispiel #9
0
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;
}
Beispiel #10
0
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);
}
Beispiel #11
0
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;
}
Beispiel #12
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);
}
Beispiel #13
0
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;
}
Beispiel #14
0
*/	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;
}
Beispiel #17
0
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;

}
Beispiel #18
0
/*
 * 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;
}
Beispiel #19
0
/*
 * 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 );
}
Beispiel #21
0
/*
 * 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;
  
}