Beispiel #1
0
TreeNode * uffs_TreeFindDirNodeByName(uffs_Device *dev,
									  const char *name, u32 len,
									  u16 sum, u16 parent)
{
	int i;
	u16 x;
	TreeNode *node;
	struct uffs_TreeSt *tree = &(dev->tree);
	
	for (i = 0; i < DIR_NODE_ENTRY_LEN; i++) {
		x = tree->dir_entry[i];
		while (x != EMPTY_NODE) {
			node = FROM_IDX(x, TPOOL(dev));
			if (node->u.dir.checksum == sum &&
					node->u.dir.parent == parent) {
				//read file name from flash, and compare...
				if (uffs_TreeCompareFileName(dev, name, len, sum,
											node, UFFS_TYPE_DIR) == U_TRUE) {
					//Got it!
					return node;
				}
			}
			x = node->hash_next;
		}
	}

	return NULL;

}
Beispiel #2
0
/* calculate file length, etc */
static URET _BuildTreeStepThree(uffs_Device *dev)
{
	int i;
	u16 x;
	TreeNode *work;
	TreeNode *node;
	struct uffs_TreeSt *tree;
	uffs_Pool *pool;
	u16 blockSave;

	TreeNode *cache = NULL;
	u16 cacheSerial = INVALID_UFFS_SERIAL;

	tree = &(dev->tree);
	pool = TPOOL(dev);

	uffs_Perror(UFFS_MSG_NOISY, "build tree step three");

	for (i = 0; i < DATA_NODE_ENTRY_LEN; i++) {
		x = tree->data_entry[i];
		while (x != EMPTY_NODE) {
			work = FROM_IDX(x, pool);
			if (work->u.data.parent == cacheSerial) {
				node = cache;
			}
			else {
				node = uffs_TreeFindFileNode(dev, work->u.data.parent);
				cache = node;
				cacheSerial = work->u.data.parent;
			}
			if (node == NULL) {
				x = work->hash_next;
				//this data block does not belong to any file ?
				//should be erased.
				uffs_Perror(UFFS_MSG_NORMAL,
					"find a orphan data block:%d, "
					"parent:%d, serial:%d, will be erased!",
					work->u.data.block,
					work->u.data.parent, work->u.data.serial);

				uffs_BreakFromEntry(dev, UFFS_TYPE_DATA, work);
				blockSave = work->u.data.block;
				work->u.list.block = blockSave;
				uffs_FlashEraseBlock(dev, blockSave);
				if (HAVE_BADBLOCK(dev))
					uffs_BadBlockProcess(dev, work);
				else
					uffs_TreeInsertToErasedListTail(dev, work);
			}
			else {
				node->u.file.len += work->u.data.len;
				x = work->hash_next;
			}
		}
	}

	return U_SUCC;
}
Beispiel #3
0
static void _InsertToEntry(uffs_Device *dev, u16 *entry,
						   int hash, TreeNode *node)
{
	node->hash_next = entry[hash];
	node->hash_prev = EMPTY_NODE;
	if (entry[hash] != EMPTY_NODE) {
		FROM_IDX(entry[hash], TPOOL(dev))->hash_prev = TO_IDX(node, TPOOL(dev));
	}
	entry[hash] = TO_IDX(node, TPOOL(dev));
}
Beispiel #4
0
/** 
 * break the node from entry
 */
void uffs_BreakFromEntry(uffs_Device *dev, u8 type, TreeNode *node)
{
	u16 *entry;
	int hash;
	TreeNode *work;

	switch (type) {
	case UFFS_TYPE_DIR:
		hash = GET_DIR_HASH(node->u.dir.serial);
		entry = &(dev->tree.dir_entry[hash]);
		break;
	case UFFS_TYPE_FILE:
		hash = GET_FILE_HASH(node->u.file.serial);
		entry = &(dev->tree.file_entry[hash]);
		break;
	case UFFS_TYPE_DATA:
		hash = GET_DATA_HASH(node->u.data.parent, node->u.data.serial);
		entry = &(dev->tree.data_entry[hash]);
		break;
	default:
		uffs_Perror(UFFS_MSG_SERIOUS, "unknown type when break...");
		return;
	}

	if (node->hash_prev != EMPTY_NODE) {
		work = FROM_IDX(node->hash_prev, &(dev->mem.tree_pool));
		work->hash_next = node->hash_next;
	}
	if (node->hash_next != EMPTY_NODE) {
		work = FROM_IDX(node->hash_next, &(dev->mem.tree_pool));
		work->hash_prev = node->hash_prev;
	}

	if (*entry == TO_IDX(node, &(dev->mem.tree_pool))) {
		*entry = node->hash_next;
	}
}
Beispiel #5
0
TreeNode * uffs_TreeFindDataNodeByBlock(uffs_Device *dev, u16 block)
{
	int hash;
	TreeNode *node;
	struct uffs_TreeSt *tree = &(dev->tree);
	u16 x;

	for (hash = 0; hash < DATA_NODE_ENTRY_LEN; hash++) {
		x = tree->data_entry[hash];
		while (x != EMPTY_NODE) {
			node = FROM_IDX(x, TPOOL(dev));
			if (node->u.data.block == block)
				return node;
			x = node->hash_next;
		}
	}

	return NULL;
}
Beispiel #6
0
TreeNode * uffs_TreeFindDirNode(uffs_Device *dev, u16 serial)
{
	int hash;
	u16 x;
	TreeNode *node;
	struct uffs_TreeSt *tree = &(dev->tree);

	hash = serial & DIR_NODE_HASH_MASK;
	x = tree->dir_entry[hash];
	while (x != EMPTY_NODE) {
		node = FROM_IDX(x, TPOOL(dev));
		if (node->u.dir.serial == serial) {
			return node;
		}
		else {
			x = node->hash_next;
		}
	}
	return NULL;
}
Beispiel #7
0
TreeNode * uffs_TreeFindDataNode(uffs_Device *dev, u16 parent, u16 serial)
{
	int hash;
	TreeNode *node;
	struct uffs_TreeSt *tree = &(dev->tree);
	u16 x;

	hash = GET_DATA_HASH(parent, serial);
	x = tree->data_entry[hash];
	while(x != EMPTY_NODE) {
		node = FROM_IDX(x, TPOOL(dev));

		if(node->u.data.parent == parent &&
			node->u.data.serial == serial)
				return node;

		x = node->hash_next;
	}

	return NULL;
}
Beispiel #8
0
TreeNode * uffs_TreeFindDirNodeWithParent(uffs_Device *dev, u16 parent)
{
	int hash;
	u16 x;
	TreeNode *node;
	struct uffs_TreeSt *tree = &(dev->tree);

	for (hash = 0; hash < DIR_NODE_ENTRY_LEN; hash++) {
		x = tree->dir_entry[hash];
		while (x != EMPTY_NODE) {
			node = FROM_IDX(x, TPOOL(dev));
			if (node->u.dir.parent == parent) {
				return node;
			}
			else {
				x = node->hash_next;
			}
		}
	}
	
	return NULL;
}
Beispiel #9
0
static URET do_FindObject(uffs_FindInfo *f, uffs_ObjectInfo *info, u16 x)
{
	URET ret = U_SUCC;
	TreeNode *node;
	uffs_Device *dev = f->dev;

	if (f->step == 0) 
	{ //!< working on dirs
		while (x != EMPTY_NODE) 
		{
			node = FROM_IDX(x, TPOOL(dev));
			if (node->u.dir.parent == f->serial) 
			{
				f->work = node;
				f->pos++;
				if (info)
					ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_DIR, NULL);
				goto ext;
			}
			x = node->hash_next;
		}

		f->hash++; //come to next hash entry

		for (; f->hash < DIR_NODE_ENTRY_LEN; f->hash++) 
		{
			x = dev->tree.dir_entry[f->hash];
			while (x != EMPTY_NODE) 
			{
				node = FROM_IDX(x, TPOOL(dev));
				if (node->u.dir.parent == f->serial) 
				{
					f->work = node;
					f->pos++;
					if (info)
						ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_DIR, NULL);
					goto ext;
				}
				x = node->hash_next;
			}
		}

		//no subdirs, then lookup files ..
		f->step++;
		f->hash = 0;
		x = EMPTY_NODE;
	}

	if (f->step == 1) 
	{

		while (x != EMPTY_NODE) 
		{
			node = FROM_IDX(x, TPOOL(dev));
			if (node->u.file.parent == f->serial) 
			{
				f->work = node;
				f->pos++;
				if (info)
					ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_FILE, NULL);
				goto ext;
			}
			x = node->hash_next;
		}

		f->hash++; //come to next hash entry

		for (; f->hash < FILE_NODE_ENTRY_LEN; f->hash++) 
		{
			x = dev->tree.file_entry[f->hash];
			while (x != EMPTY_NODE) 
			{
				node = FROM_IDX(x, TPOOL(dev));
				if (node->u.file.parent == f->serial) 
				{
					f->work = node;
					f->pos++;
					if (info) 
						ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_FILE, NULL);
					goto ext;
				}
				x = node->hash_next;
			}
		}

		//no any files, stopped.
		f->step++;
	}

	ret = U_FAIL;
ext:

	return ret;

}