Ejemplo n.º 1
0
/*
 * Read metadata block from disk, possibly create it if it does not exist and
 * and open flags allow
 */
static int read_meta(TEE_Result *errno, struct sql_fs_fd *fdp)
{
	size_t msize = meta_size();
	size_t out_size = sizeof(fdp->meta);
	uint8_t *meta = NULL;
	int rc = -1;

	*errno = TEE_ERROR_GENERIC;

	meta = malloc(msize);
	if (!meta) {
		*errno = TEE_ERROR_OUT_OF_MEMORY;
		goto exit;
	}

	rc = tee_fs_rpc_lseek(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd, 0,
			      TEE_FS_SEEK_SET);
	if (rc < 0)
		goto exit;

	rc = sql_fs_read_rpc(fdp->fd, meta, msize);
	if (rc < 0) {
		/* Read error */
		goto exit;
	} else if (rc == 0) {
		/* No meta data on disk yet */
		if (!(fdp->flags & TEE_FS_O_CREATE))
			goto exit;
		rc = create_meta(errno, fdp);
	} else if (rc == (int)msize) {
#ifdef CFG_ENC_FS
		TEE_Result res;

		res = tee_fs_decrypt_file(META_FILE, meta, msize,
					  (uint8_t *)&fdp->meta, &out_size,
					  fdp->encrypted_fek);
		if (res != TEE_SUCCESS) {
			*errno = res;
			rc = -1;
			goto exit;
		}
#else
		memcpy((uint8_t *)&fdp->meta,
		       meta + tee_fs_get_header_size(META_FILE),
		       out_size);
#endif
		rc = 0;
	} else {
		/* Unexpected data length */
		rc = -1;
	}
exit:
	free(meta);
	return rc;
}
Ejemplo n.º 2
0
unsigned long get_data_segment_free_space_size(){
	metadata_t *head = NULL;
	int i = 0;
	unsigned long result = 0;
	for (i = 0; i < ARRAY_SIZE; i++) {
		head = freelist_arr[i];
		while (head != NULL) {
			result += meta_size(head);
			head = head->next;
		}
	}
	return result;
}
Ejemplo n.º 3
0
/* Given a position in the user data, return the offset in the DB file */
static tee_fs_off_t pos_to_raw(tee_fs_off_t pos)
{
	tee_fs_off_t res;

	if (pos < 0)
		return -1;
	res = meta_size() + block_num(pos) * block_size_raw();
	if (pos % BLOCK_SIZE) {
		res += block_header_size();
		res += pos % BLOCK_SIZE;
	}

	return res;
}
Ejemplo n.º 4
0
void add_node(metadata_t *node) {
	int idx = array_idx(meta_size(node));
	if (!freelist_arr[idx]) {
		freelist_arr[idx] = node;
		node->prev = NULL;
		node->next = NULL;
	}
	else {
		node->prev = NULL;
		node->next = freelist_arr[idx];
		freelist_arr[idx]->prev = node;
		freelist_arr[idx] = node;
	}
}
Ejemplo n.º 5
0
static int write_meta(TEE_Result *errno, struct sql_fs_fd *fdp)
{
	int fd = fdp->fd;
	size_t ct_size = meta_size();
	uint8_t *ct;
	int rc = -1;

	*errno = TEE_ERROR_GENERIC;

	ct = malloc(ct_size);
	if (!ct) {
		*errno = TEE_ERROR_OUT_OF_MEMORY;
		goto exit;
	}

	rc = tee_fs_rpc_lseek(OPTEE_MSG_RPC_CMD_SQL_FS, fd, 0,
			      TEE_FS_SEEK_SET);
	if (rc < 0)
		goto exit;

#ifdef CFG_ENC_FS
	{
		TEE_Result res;

		res = tee_fs_encrypt_file(META_FILE,
					  (const uint8_t *)&fdp->meta,
					  sizeof(fdp->meta), ct, &ct_size,
					  fdp->encrypted_fek);
		if (res != TEE_SUCCESS) {
			*errno = res;
			rc = -1;
			goto exit;
		}
	}
#else
	copy_data(META_FILE, ct, (const uint8_t *)&fdp->meta,
		  sizeof(fdp->meta));
#endif

	rc = sql_fs_write_rpc(fdp->fd, ct, ct_size);
	if (rc != (int)ct_size)
		rc = -1;
	else
		rc = 0;

exit:
	free(ct);
	return rc;
}
Ejemplo n.º 6
0
/* Given a position in the DB file, return the offset in the user data */
static tee_fs_off_t raw_to_pos(tee_fs_off_t raw_pos)
{
	tee_fs_off_t pos = raw_pos;
	ssize_t n = block_num_raw(raw_pos);

	if (n < 0)
		return -1;

	pos -= meta_size();
	pos -= block_header_size();
	if (pos < 0)
		return -1;

	return (n * BLOCK_SIZE) + (pos % BLOCK_SIZE);
}
Ejemplo n.º 7
0
void* dmalloc(size_t numbytes, int flag) {
	if(!is_init) { 			//Initialize through sbrk call first time
		if(!dmalloc_init()) {
			return NULL;
		}
	}

	assert(numbytes > 0);

	/* Your code goes here */
	size_t space = ALIGN(numbytes);
	// go over the linked list, find the first fit
	//metadata_t* flpt = freelist;
	metadata_t* flpt = find_fit(space, flag);
	if (!flpt) {
		//return NULL;
		if (!(flpt = extend_heap(space))) {
			printf("extend heap failed! \n");
			return NULL;
		}
	}
	size_t rest = meta_size(flpt) - space;
	delete_node(flpt);
	if (rest < ALIGN(META_SIZE + FOOTER_SIZE + 1)) {
		set_alloc(flpt);
		set_alloc((metadata_t *)(to_footer(to_block(flpt))));
	}
	else {
		rest = rest - META_SIZE - FOOTER_SIZE;
		set_size(flpt, space);
		set_alloc(flpt);
		set_size((metadata_t *)(to_footer(to_block(flpt))), space);
		set_alloc((metadata_t *)(to_footer(to_block(flpt))));
		metadata_t* newmt = (metadata_t *)((void *)flpt + META_SIZE + space + FOOTER_SIZE);
		set_size(newmt, rest);
		set_free(newmt);
		set_size((metadata_t *)to_footer(to_block(newmt)), rest);
		set_free((metadata_t *)to_footer(to_block(newmt)));
		add_node(newmt);
	}
	void * result = to_block(flpt);
	assert(result != NULL);
	if (!result) {
		int a = 1;
	}
	return result;
}
Ejemplo n.º 8
0
metadata_t * find_fit(size_t space, int flag) {
    int idx = array_idx(space);
    metadata_t *flpt = NULL;
    if (flag == FF) {
		while (idx < ARRAY_SIZE) {
			flpt = freelist_arr[idx];
			while (flpt) {
				if (meta_size(flpt) < space) {
					flpt = flpt->next;
				}
				else {
					return flpt;
				}
			}
			idx++;
		}
		return NULL;
    }
    else if (flag == BF) {
    	size_t redundant = ~(size_t)0x00;
    	metadata_t *result = NULL;
    	while (idx < ARRAY_SIZE && result == NULL) {
    		flpt = freelist_arr[idx];
    		while (flpt) {
    			if (meta_size(flpt) == space) {
    				return flpt;
    			}
    			else if (meta_size(flpt) > space && redundant > meta_size(flpt) - space) {
    				result = flpt;
    				redundant = meta_size(flpt) - space;			
    			}
    			flpt = flpt->next;
    		}
    		idx++;
    	}
    	return result;
    }
    else if (flag == WF) {
		metadata_t *result = NULL;
		int i = ARRAY_SIZE - 1;
		for (; i >= idx && !result; i--) {
			flpt = freelist_arr[i];
			while (flpt && !result) {
				if (meta_size(flpt) >= space) {
					result = flpt;
				}
				flpt = flpt->next;
			}
		}
		return result;
	}
    return NULL;
}
Ejemplo n.º 9
0
bool dmalloc_init() {

	/* Two choices: 
 	* 1. Append prologue and epilogue blocks to the start and the end of the freelist
 	* 2. Initialize freelist pointers to NULL
 	*
 	* Note: We provide the code for 2. Using 1 will help you to tackle the
 	* corner cases succinctly.
 	*/
 	
 	is_init = true;

	size_t max_bytes = ALIGN(MAX_HEAP_SIZE);
	int i = 0;
	for (i = 0; i < ARRAY_SIZE; i++) {
	    freelist_arr[i] = NULL;
	}
	
	metadata_t *fl = (metadata_t*) sbrk(max_bytes); // returns heap_region, which is initialized to freelist
	heap_begin = fl;
	/* Q: Why casting is used? i.e., why (void*)-1? */
	if (fl == (void *)-1)
		return false;
	//prologue block
	footer_t* prologue = (footer_t *)fl;
	set_size((metadata_t *)prologue, 0);
	set_alloc((metadata_t *)prologue);
	//epilogue block
	metadata_t* epilogue = (metadata_t *)((void *)fl + max_bytes - META_SIZE);
	set_size(epilogue, 0);
	set_alloc(epilogue);
	//freelist
	fl = (metadata_t *)((void *)fl + FOOTER_SIZE);
	set_size(fl, max_bytes - 2 * META_SIZE - 2 * FOOTER_SIZE);
	set_free(fl);
	set_size((metadata_t *)to_footer(to_block(fl)), meta_size(fl));	
	set_free((metadata_t *)to_footer(to_block(fl)));
	fl->next = NULL;
	fl->prev = NULL;
	add_node(fl);
	return true;
}
Ejemplo n.º 10
0
void delete_node(metadata_t *node) {
	size_t space = meta_size(node);
	int idx = array_idx(space);
	if (!node->prev && !node->next) {
		freelist_arr[idx] = NULL;
	}
	else if (!node->prev) {
		freelist_arr[idx] = node->next;
		node->next = NULL;
		freelist_arr[idx]->prev = NULL;
	}
	else if (!node->next) {
		node->prev->next = NULL;
		node->prev = NULL;
	}
	else {
		node->prev->next = node->next;
		node->next->prev = node->prev;
		node->prev = NULL;
		node->next = NULL;
	}
}
Ejemplo n.º 11
0
/* Return the position of a block in the DB file */
static ssize_t block_pos_raw(size_t block_num)
{
	return meta_size() + block_num * block_size_raw();
}
Ejemplo n.º 12
0
/* Return the block number from a position in the DB file */
static ssize_t block_num_raw(tee_fs_off_t raw_pos)
{
	return (raw_pos - meta_size()) / block_size_raw();
}
Ejemplo n.º 13
0
inline size_t block_size(void *bp) {
	return meta_size(to_meta(bp));
}
Ejemplo n.º 14
0
inline void set_footer_size(metadata_t *mt, size_t s) {
	footer_t* ft = (footer_t *) ((void *)(mt) + META_SIZE + meta_size(mt) + FOOTER_SIZE);
	ft->size = s;
}