Ejemplo n.º 1
0
char* _dir_find_entry_name(minifile_t inode, int inode_id)
{
	int i, x;
	block_t dir_data_block;
	char* buff;

	for (i = 0; i < inode->u.data.num_data_blocks; i++)
	{
		dir_data_block = _retrieve_block(_inode_get_data_block_id(inode, i));

		// Go through the listing
		for (x = 0; x < MAX_DIR_DATA_BLOCK_ENTRIES; x++)
		{
			if (dir_data_block->type.dir_data_block.entries[x].inode_block_id != 0)
			{
				if (dir_data_block->type.dir_data_block.entries[x].inode_block_id == inode_id)
				{
					_release_block(dir_data_block);
					_release_block((block_t) inode);
					buff = (char*) malloc(sizeof(char) * (strlen(dir_data_block->type.dir_data_block.entries[x].name) + 1));
					strcpy(buff, dir_data_block->type.dir_data_block.entries[x].name);
					return buff;
				}
			}
		}

		_release_block(dir_data_block);
	}

	_release_block((block_t) inode);

	return NULL;
}
Ejemplo n.º 2
0
int _dir_remove_entry(minifile_t dir, int inode_block_id)
{
	int i, x;
	block_t dir_data_block;
	minifile_t inode = (minifile_t) _retrieve_block(inode_block_id);

	for (i = 0; i < dir->u.data.num_data_blocks; i++)
	{
		dir_data_block = _retrieve_block(_inode_get_data_block_id(dir, i));

		// Go through the listing
		for (x = 0; x < MAX_DIR_DATA_BLOCK_ENTRIES; x++)
		{
			if (dir_data_block->type.dir_data_block.entries[x].inode_block_id == inode_block_id)
			{
				dir_data_block->type.dir_data_block.entries[x].inode_block_id = 0;
				inode->u.data.size--;
				_commit_block((block_t) dir_data_block);
				_commit_block(inode);
				_release_block((block_t) dir_data_block);
				_release_block((block_t) inode);
				return 0;
			}
		}

		_release_block(dir_data_block);
	}

	_release_block((block_t) inode);

	return -1;
}
Ejemplo n.º 3
0
int _dir_find_entry(minifile_t inode, char* filename)
{
	int i, x;
	block_t dir_data_block;

	for (i = 0; i < inode->u.data.num_data_blocks; i++)
	{
		dir_data_block = _retrieve_block(_inode_get_data_block_id(inode, i));

		// Go through the listing
		for (x = 0; x < MAX_DIR_DATA_BLOCK_ENTRIES; x++)
		{
			if (dir_data_block->type.dir_data_block.entries[x].inode_block_id != 0)
			{
				if ( strcmp(dir_data_block->type.dir_data_block.entries[x].name, filename) == 0)
				{
					_release_block(dir_data_block);
					_release_block((block_t) inode);
					return dir_data_block->type.dir_data_block.entries[x].inode_block_id;
				}
			}
		}

		_release_block(dir_data_block);
	}
	_release_block((block_t) inode);

	return -1;
}
Ejemplo n.º 4
0
int _inode_get_data_block_id(minifile_t inode, int block_num)
{
	int indir_block_id;
	block_t indir_block;
	int blocks_seen;
	int block_id;

	if (inode->u.data.num_data_blocks == 0)
	{
		// Add the first data block. 
		// Other than this, if they specify a nonexistent block, we return -1
		block_id = _inode_add_new_data_block(inode);
	}
	

	if (block_num < 11)
	{
		return inode->u.data.data_block_ids[block_num];
	}

	indir_block_id = inode->u.data.indir_block_id;
	blocks_seen = 11;

	while (indir_block_id != 0)
	{
		indir_block = _retrieve_block(indir_block_id);

		if ((block_num - blocks_seen) < MAX_INDIR_BLOCK_ENTRIES -1) // nearly positive we need +1 after blocknum, write it out - say we have 12 data blocks in groups of two. If we saw 9 blocks, we'd really have seen 8 and be on the wrong block, but 10-9 = 1 < 2...
		{
			block_id = indir_block->type.indir_block.entries[(block_num-11) % MAX_INDIR_BLOCK_ENTRIES];
			_release_block(indir_block);

			return block_id;
		}

		indir_block_id = indir_block->type.indir_block.entries[MAX_INDIR_BLOCK_ENTRIES];
		_release_block(indir_block);

		blocks_seen += MAX_INDIR_BLOCK_ENTRIES -1;
	}

	return -1;
}
Ejemplo n.º 5
0
/* This gets the current data block, and creates a new one (and indir block) if it 
 * sees that the current ones are full. */
int _inode_find_curr_data_block_id(minifile_t inode)
{
	int num_data_blocks = inode->u.data.num_data_blocks;
	int size = inode->u.data.size;
	block_t indir_block;
	int block_id;
	int threshold_size;

/* todo - put this back after we have creating files/dirs working
	if (inode->u.data.block_type != BLOCK_TYPE_DIRECTORY)
	{
		return 0;
	}
*/

	// Determine what the size of the inode really means
	if (inode->u.data.block_type == BLOCK_TYPE_DIRECTORY)
	{
		threshold_size = MAX_DIR_DATA_BLOCK_ENTRIES;
		if (size >= 11)
			size -= 11;
	}
	 else
	{
		threshold_size = DISK_BLOCK_SIZE;
		if (size >= 11*DISK_BLOCK_SIZE)
			size -= 11*DISK_BLOCK_SIZE;
	}

	// If no block yet
	if (num_data_blocks == 0)
	{
		return _inode_add_new_data_block(inode);		
	}

	// If we're out of blocks, get a new one and return it
	if (size > 0 && size % threshold_size == 0)
	{
		return _inode_add_new_data_block(inode);
	}

	// Otherwise, find the latest data block
	if (num_data_blocks <= 11)
	{
		return inode->u.data.data_block_ids[num_data_blocks-1];
	}
	 else
	{
		indir_block = _retrieve_block(inode->u.data.latest_indir_block_id);
		block_id = indir_block->type.indir_block.entries[((num_data_blocks-12) % MAX_INDIR_BLOCK_ENTRIES)];
		_release_block(indir_block);
		return block_id;
	}
}
Ejemplo n.º 6
0
void _big_xdebug_write(unsigned EAX, void* *ECX)
{
        // ECX IS BLOCK TABLE
        // EAX IS BYTE COUNT

        if (EAX)
        {
                void* *EBX = ECX;
                unsigned count = EAX;
L1:
                void *p = *EBX;
                *EBX = 0;

                unsigned n = PAGE_SIZE;
                if (count <= n)
                    n = count;
                _xdebug_normal(p, n);

                count -= n;
                ++EBX;
                _release_block(p);
                if (count)
                    goto L1;
                return;
        }
        void *a = (void *)EAX;
        void **c = ECX;
        __asm
        {
                mov     EAX,a
                mov     ECX,c
                xchg    [ECX],EAX
                mov     a,EAX
        }
        if (a)
            _release_block(a);
}
Ejemplo n.º 7
0
int _pop_free_data_block()
{
	block_t block;
	int block_id;
	superblock_t superblock = (superblock_t) _retrieve_block(0);

	block = _retrieve_block(superblock->u.data.first_free_data_block_id);
	block_id = block->block_id;
	superblock->u.data.first_free_data_block_id = block->type.free_data_block.next_free_data_block_id;

	_release_block(block);

	_commit_block((block_t) superblock);

	return block_id;
}
Ejemplo n.º 8
0
int _pop_free_inode()
{
	block_t block;
	int block_id;

	superblock_t superblock = (superblock_t) _retrieve_block(0);
	if (superblock == NULL)
		return -1;

	block = _retrieve_block(superblock->u.data.first_free_inode_id);

	block_id = block->block_id;
	superblock->u.data.first_free_inode_id = block->type.free_inode.next_free_inode_id;
	_release_block(block);

	_commit_block((block_t) superblock);
	return block_id;
}
Ejemplo n.º 9
0
// todo - make it search for an empty spot
int _dir_add_entry(minifile_t inode, int inode_block_id, char* name)
{
	block_t dir_data_block;
	int dir_size = inode->u.data.size;
	int next_idx = dir_size % MAX_DIR_DATA_BLOCK_ENTRIES;
	int found_block_id;
	int curr_data_block;

	if (inode == NULL)
	{
		return -1;
	}

	// todo - ensure file isn't already in directory
	found_block_id = _dir_find_entry(inode, name);
	if (found_block_id != -1)
	{
		return found_block_id;
	}

	// Get the block - it is guaranteed to have room
	curr_data_block = _inode_find_curr_data_block_id(inode);

	dir_data_block = _retrieve_block(curr_data_block);

	// Add ourselves to the block
	dir_data_block->type.dir_data_block.entries[next_idx].inode_block_id = inode_block_id;
	strcpy(dir_data_block->type.dir_data_block.entries[next_idx].name, name); // todo - may need to account for endianness & use packing 

	// Update the inode's size
	inode->u.data.size++;

	// Close & save the block
	dir_data_block->is_dirty = 1;

	_release_block(dir_data_block);

	// Release the inode too
	_commit_block((block_t) inode);

	return 0;
}
Ejemplo n.º 10
0
int _inode_add_new_data_block(minifile_t inode)
{
	int num_data_blocks = inode->u.data.num_data_blocks;
	int new_block_id;
	int new_indir_block_id;
	block_t indir_block;

	// Check if we need to add a normal block
	if (num_data_blocks < 11)
	{
		new_block_id = _pop_free_data_block();

		inode->u.data.data_block_ids[num_data_blocks] = new_block_id;
	}
	 // Check if we need to create our first indirection block
	 else if (num_data_blocks == 11)
	{
		// Get the new block IDs
		new_indir_block_id = _pop_free_data_block();
		new_block_id = _pop_free_data_block();

		// Setup the indirection block
		indir_block = _retrieve_block(new_indir_block_id);
		indir_block->type.indir_block.entries[0] = new_block_id;
		indir_block->type.indir_block.entries[MAX_INDIR_BLOCK_ENTRIES] = 0; // we check this eventually

		// Close & save the indirection block
		indir_block->is_dirty = 1;
		_release_block(indir_block);

		// Update the inode
		inode->u.data.indir_block_id = new_indir_block_id;

		inode->u.data.latest_indir_block_id = new_indir_block_id;	
	}
	// Check if we need to update the indirection current blocks
	 else if (num_data_blocks > 11)
	{
		// Check if we need to create a new indirection block as well
		if ((num_data_blocks-11) % MAX_INDIR_BLOCK_ENTRIES == 0)
		{
			// We could make this just make the indir block, and remove the code from
			// the else and put it below, which would look cleaner; however, it would
			// also be slower.

			// Get the new data blocks
			new_indir_block_id = _pop_free_data_block();
			new_block_id = _pop_free_data_block();

			// Setup the indirection block
			indir_block = _retrieve_block(new_indir_block_id);
			indir_block->type.indir_block.entries[0] = new_block_id;
			indir_block->type.indir_block.entries[MAX_INDIR_BLOCK_ENTRIES] = 0; // we check this eventually

			// Close & save the indirection block		
			indir_block->is_dirty = 1;
			_release_block(indir_block);

			// Open up the old indirection block and update it
			indir_block = _retrieve_block(inode->u.data.latest_indir_block_id);
			indir_block->type.indir_block.entries[MAX_INDIR_BLOCK_ENTRIES] = new_indir_block_id; // we check this eventually

			// Close and save the old indirection block
			indir_block->is_dirty = 1;
			_commit_block(indir_block);
			_release_block(indir_block);

			// Update the inode
			inode->u.data.latest_indir_block_id = new_indir_block_id;	

		}
		// Otherwise, just add a new data block to the current indirection block
		 else
		{
			// Get the new data block
			new_block_id = _pop_free_data_block();

			// Open up the indirection block and update it
			indir_block = _retrieve_block(inode->u.data.latest_indir_block_id);
			indir_block->type.indir_block.entries[((num_data_blocks-11) % MAX_INDIR_BLOCK_ENTRIES)] = new_block_id; // no need for +1, the math works

			// Close and save the indirection block
			indir_block->is_dirty = 1;
			_release_block(indir_block);
		}
	}
	// Update & commit the inode
	inode->u.data.num_data_blocks++;
	_commit_block((block_t) inode);

	return new_block_id;
}
Ejemplo n.º 11
0
/* Given a path, find the inode it refers to (either file or dir) */
int _find_path_inode(char* path)
{
	int i, x;
	minifile_t inode;
	block_t data_block;
	char** path_parts;
	int path_part_ct = 0;
	int found_inode = 1;
	minithread_t running = minithread_self();
	superblock_t superblock;
	int block_id;
	int path_parts_size = _find_path_len(path);

	if (strcmp(path, "/") == 0)
	{
		superblock = (superblock_t) _retrieve_block(0);
		block_id = superblock->u.data.root_dir_block_id;
		return block_id;
	}

	// Split up path by "/"s
	path_parts = _parse_path(path, path_parts_size);

	// Is this a relative or absolute path?
	if (path[0] == '/')
	{
		/* TODO: MUST PUT THIS BACK IN
		superblock = (superblock_t) _retrieve_block(0);
		inode = (minifile_t) _retrieve_block(superblock->u.data.root_dir_block_id);
		*/
		inode = (minifile_t) _retrieve_block(1);
		path_part_ct++;
	} 
	 else
	{
		inode = (minifile_t) _retrieve_block(running->dir_block_id);
	}

	while (found_inode == 1 && path_part_ct < path_parts_size)
	{
		found_inode = 0;

		// Go through all the data blocks
		for (i = 0; i < inode->u.data.num_data_blocks; i++)
		{
			if (found_inode == 1)
				break;

			data_block = _retrieve_block(_inode_get_data_block_id(inode, i));

			// Go through the listing
			for (x = 0; x < MAX_DIR_DATA_BLOCK_ENTRIES; x++)
			{
				if (data_block->type.dir_data_block.entries[x].inode_block_id == 0)
				{
					continue;
				}

				if (strcmp(data_block->type.dir_data_block.entries[x].name, path_parts[path_part_ct]) == 0)
				{
					// We found it
					block_id = data_block->type.dir_data_block.entries[x].inode_block_id;
					_release_block((block_t) inode);
					inode = (minifile_t) _retrieve_block(data_block->type.dir_data_block.entries[x].inode_block_id);
					found_inode = 1;
					path_part_ct++;
					break;
				}
			}
		}
	}

	_release_block((block_t) inode);

	if (found_inode == 1)
	{
		return block_id;
	}

	
	return -1;
}