⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yaffs_guts.c

📁 把将yaffs 移植到 ucos 系统
💻 C
📖 第 1 页 / 共 5 页
字号:

static __u16 yaffs_CalcNameSum(const char *name)
{
	__u16 sum = 0;
	__u16 i = 1;
	
	__u8 *bname = (__u8 *)name;
	if(bname)
	{
		while ((*bname) && (i <=YAFFS_MAX_NAME_LENGTH))
		{

#ifdef CONFIG_YAFFS_CASE_INSENSITIVE
			sum += toupper(*bname) * i;
#else
			sum += (*bname) * i;
#endif
			i++;
			bname++;
		}
	}
	return sum;
}

void yaffs_SetObjectName(yaffs_Object *obj, const char *name)
{
#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
					if(name && strlen(name) <= YAFFS_SHORT_NAME_LENGTH)
					{
						strcpy(obj->shortName,name);
					}
					else
					{
						obj->shortName[0]='\0';
					}
#endif
					obj->sum = yaffs_CalcNameSum(name);
}

void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
{
	yaffs_ECCCalculate(data , spare->ecc1);
	yaffs_ECCCalculate(&data[256] , spare->ecc2);
}

void yaffs_CalcTagsECC(yaffs_Tags *tags)
{
	// Calculate an ecc
	
	unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes;
	unsigned  i,j;
	unsigned  ecc = 0;
	unsigned bit = 0;

	tags->ecc = 0;
	
	for(i = 0; i < 8; i++)
	{
		for(j = 1; j &0xff; j<<=1)
		{
			bit++;
			if(b[i] & j)
			{
				ecc ^= bit;
			}
		}
	}
	
	tags->ecc = ecc;
	
	
}

int  yaffs_CheckECCOnTags(yaffs_Tags *tags)
{
	unsigned ecc = tags->ecc;
	
	yaffs_CalcTagsECC(tags);
	
	ecc ^= tags->ecc;
	
	if(ecc && ecc <= 64)
	{
		// TODO: Handle the failure better. Retire?
		unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes;

		ecc--;
				
		b[ecc / 8] ^= (1 << (ecc & 7));
		
		// Now recvalc the ecc
		yaffs_CalcTagsECC(tags);
		
		return 1; // recovered error
	}
	else if(ecc)
	{
		// Wierd ecc failure value
		// TODO Need to do somethiong here
		return -1; //unrecovered error
	}
	
	return 0;
}


///////////////////////// TNODES ///////////////////////

// List of spare tnodes
// The list is hooked together using the first pointer
// in the tnode.

//static yaffs_Tnode *yaffs_freeTnodes = NULL;

// static int yaffs_nFreeTnodes;

//static yaffs_TnodeList *yaffs_allocatedTnodeList = NULL;



// yaffs_CreateTnodes creates a bunch more tnodes and
// adds them to the tnode free list.
// Don't use this function directly

static int yaffs_CreateTnodes(yaffs_Device *dev,int nTnodes)
{
    int i;
    yaffs_Tnode *newTnodes;
    yaffs_TnodeList *tnl;
    
    if(nTnodes < 1) return YAFFS_OK;
   
	// make these things
	
    newTnodes = YMALLOC(nTnodes * sizeof(yaffs_Tnode));
   
    if (!newTnodes)
    {
		T(YAFFS_TRACE_ERROR,(TSTR("yaffs: Could not allocate Tnodes"TENDSTR)));
		return YAFFS_FAIL;
    }
    
    // Hook them into the free list
    for(i = 0; i < nTnodes - 1; i++)
    {
    	newTnodes[i].internal[0] = &newTnodes[i+1];
#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
    	newTnodes[i].internal[YAFFS_NTNODES_INTERNAL] = 1;
#endif
    }
    	
	newTnodes[nTnodes - 1].internal[0] = dev->freeTnodes;
#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
   	newTnodes[nTnodes - 1].internal[YAFFS_NTNODES_INTERNAL] = 1;
#endif
	dev->freeTnodes = newTnodes;
	dev->nFreeTnodes+= nTnodes;
	dev->nTnodesCreated += nTnodes;

	// Now add this bunch of tnodes to a list for freeing up.
	// NB If we can't add this to the management list it isn't fatal
	// but it just means we can't free this bunch of tnodes later.
	tnl = YMALLOC(sizeof(yaffs_TnodeList));
	if(!tnl)
	{
		T(YAFFS_TRACE_ERROR,(TSTR("yaffs: Could not add tnodes to management list" TENDSTR)));
		
	}
	else
	{
		tnl->tnodes = newTnodes;
		tnl->next = dev->allocatedTnodeList;
		dev->allocatedTnodeList = tnl;
	}


	T(YAFFS_TRACE_ALLOCATE,(TSTR("yaffs: Tnodes added" TENDSTR)));


	return YAFFS_OK;
}


// GetTnode gets us a clean tnode. Tries to make allocate more if we run out
static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev)
{
	yaffs_Tnode *tn = NULL;
	
	// If there are none left make more
	if(!dev->freeTnodes)
	{
		yaffs_CreateTnodes(dev,YAFFS_ALLOCATION_NTNODES);
	}
	
	if(dev->freeTnodes)
	{
		tn = dev->freeTnodes;
#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
    	if(tn->internal[YAFFS_NTNODES_INTERNAL] != 1)
		{
			// Hoosterman, this thing looks like it isn't in the list
				T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: Tnode list bug 1" TENDSTR)));
		}
#endif
		dev->freeTnodes = dev->freeTnodes->internal[0];
		dev->nFreeTnodes--;
		// zero out
		memset(tn,0,sizeof(yaffs_Tnode));
	}
	

	return tn;
}


// FreeTnode frees up a tnode and puts it back on the free list
static void yaffs_FreeTnode(yaffs_Device*dev, yaffs_Tnode *tn)
{
	if(tn)
	{
#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
    	if(tn->internal[YAFFS_NTNODES_INTERNAL] != 0)
		{
			// Hoosterman, this thing looks like it is already in the list
				T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: Tnode list bug 2" TENDSTR)));
		}
		tn->internal[YAFFS_NTNODES_INTERNAL] = 1;
#endif
		tn->internal[0] = dev->freeTnodes;
		dev->freeTnodes = tn;
		dev->nFreeTnodes++;
	}
}


static void yaffs_DeinitialiseTnodes(yaffs_Device*dev)
{
	// Free the list of allocated tnodes
	yaffs_TnodeList *tmp;
		
	while(dev->allocatedTnodeList)
	{
		tmp =  dev->allocatedTnodeList->next;

		YFREE(dev->allocatedTnodeList->tnodes);
		YFREE(dev->allocatedTnodeList);
		dev->allocatedTnodeList	= tmp;
		
	}
	
	dev->freeTnodes = NULL;
	dev->nFreeTnodes = 0;
}

static void yaffs_InitialiseTnodes(yaffs_Device*dev)
{
	dev->allocatedTnodeList = NULL;
	dev->freeTnodes = NULL;
	dev->nFreeTnodes = 0;
	dev->nTnodesCreated = 0;

}

#if 0
void yaffs_TnodeTest(yaffs_Device *dev)
{

	int i;
	int j;
	yaffs_Tnode *tn[1000];
	
	YINFO("Testing TNodes");
	
	for(j = 0; j < 50; j++)
	{
		for(i = 0; i < 1000; i++)
		{
			tn[i] = yaffs_GetTnode(dev);
			if(!tn[i])
			{
				YALERT("Getting tnode failed");
			}
		}
		for(i = 0; i < 1000; i+=3)
		{
			yaffs_FreeTnode(dev,tn[i]);
			tn[i] = NULL;
		}
		
	}
}
#endif


////////////////// END OF TNODE MANIPULATION ///////////////////////////

/////////////// Functions to manipulate the look-up tree (made up of tnodes)
// The look up tree is represented by the top tnode and the number of topLevel
// in the tree. 0 means only the level 0 tnode is in the tree.


// FindLevel0Tnode finds the level 0 tnode, if one exists.
// Used when reading.....
static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device *dev,yaffs_FileStructure *fStruct, __u32 chunkId)
{
	
	yaffs_Tnode *tn = fStruct->top;
	__u32 i;
	int requiredTallness;	
	int level = fStruct->topLevel;
	
	// Check sane level and chunk Id
	if(level < 0 || level > YAFFS_TNODES_MAX_LEVEL)
	{
//		char str[50];
//		sprintf(str,"Bad level %d",level);
//		YALERT(str);
		return NULL;
	}
	
	if(chunkId > YAFFS_MAX_CHUNK_ID)
	{
//		char str[50];
//		sprintf(str,"Bad chunkId %d",chunkId);
//		YALERT(str);
		return NULL;
	}

	// First check we're tall enough (ie enough topLevel)
	
	i = chunkId >> (/*dev->chunkGroupBits  + */YAFFS_TNODES_LEVEL0_BITS);
	requiredTallness = 0;
	while(i)
	{
		i >>= YAFFS_TNODES_INTERNAL_BITS;
		requiredTallness++;
	}
	
	
	if(requiredTallness > fStruct->topLevel)
	{
		// Not tall enough, so we can't find it, return NULL.
		return NULL;
	}
		
	
	// Traverse down to level 0
	while (level > 0 && tn)
	{
	    tn = tn->internal[(chunkId >>(/* dev->chunkGroupBits + */ YAFFS_TNODES_LEVEL0_BITS + (level-1) * YAFFS_TNODES_INTERNAL_BITS)) & 
	                       YAFFS_TNODES_INTERNAL_MASK]; 
		level--;
	
	}
	
	return tn;		
}

// AddOrFindLevel0Tnode finds the level 0 tnode if it exists, otherwise first expands the tree.
// This happens in two steps:
//  1. If the tree isn't tall enough, then make it taller.
//  2. Scan down the tree towards the level 0 tnode adding tnodes if required.
//
// Used when modifying the tree.
//
static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device *dev, yaffs_FileStructure *fStruct, __u32 chunkId)
{
	
	yaffs_Tnode *tn; 
	
	int requiredTallness;
	int i;
	int l;
	
	__u32 x;
		
	
	//T((TSTR("AddOrFind topLevel=%d, chunk=%d"),fStruct->topLevel,chunkId));
	
	// Check sane level and page Id
	if(fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL)
	{
//		char str[50];
//		sprintf(str,"Bad level %d",fStruct->topLevel);
//		YALERT(str);
		return NULL;
	}
	
	if(chunkId > YAFFS_MAX_CHUNK_ID)
	{
//		char str[50];
//		sprintf(str,"Bad chunkId %d",chunkId);
//		YALERT(str);
		return NULL;
	}
	
	// First check we're tall enough (ie enough topLevel)
	
	x = chunkId >> (/*dev->chunkGroupBits + */YAFFS_TNODES_LEVEL0_BITS);
	requiredTallness = 0;
	while(x)
	{
		x >>= YAFFS_TNODES_INTERNAL_BITS;
		requiredTallness++;
	}
	
	//T((TSTR(" required=%d"),requiredTallness));
	
	
	if(requiredTallness > fStruct->topLevel)
	{
		// Not tall enough,gotta make the tree taller
		for(i = fStruct->topLevel; i < requiredTallness; i++)
		{
			//T((TSTR(" add new top")));
			
			tn = yaffs_GetTnode(dev);
			
			if(tn)
			{
				tn->internal[0] = fStruct->top;
				fStruct->top = tn;
			}
			else
			{
					T(YAFFS_TRACE_ERROR,(TSTR("yaffs: no more tnodes" TENDSTR)));
			}
		}
		
		fStruct->topLevel = requiredTallness;
	}
	
	
	// Traverse down to level 0, adding anything we need
	
	l = fStruct->topLevel;
	tn = fStruct->top;
	while (l > 0 && tn)
	{
		x = (chunkId >> (/*dev->chunkGroupBits + */YAFFS_TNODES_LEVEL0_BITS + (l-1) * YAFFS_TNODES_INTERNAL_BITS)) & 
	                       YAFFS_TNODES_INTERNAL_MASK;
			       
		//T((TSTR(" [%d:%d]"),l,i));
		
	    if(!tn->internal[x])
	    {
	    	//T((TSTR(" added")));
		
	    	tn->internal[x] = yaffs_GetTnode(dev);
	    }
	    
	    tn = 	tn->internal[x];
		l--;
	
	}
	
	//TSTR(TENDSTR)));
	
	return tn;		
}

// DeleteWorker scans backwards through the tnode tree and deletes all the
// chunks and tnodes in the file
// Returns 1 if the tree was deleted. Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.

static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit)
{
	int i;
	int chunkInInode;
	int theChunk;
	yaffs_Tags tags;
	int found;
	int chunkDeleted;
	int allDone = 1;
	
	
	if(tn)
	{
		if(level > 0)
		{
		
			for(i = YAFFS_NTNODES_INTERNAL -1; allDone && i >= 0; i--)
			{
			    if(tn->internal[i])
		    	{
					if(limit && (*limit) < 0)
					{
						allDone = 0;
					}
					else
					{
						allDone = yaffs_DeleteWorker(in,tn->internal[i],level - 1,
										(chunkOffset << YAFFS_TNODES_INTERNAL_BITS ) + i ,limit);
					}
					if(allDone)
					{
						yaffs_FreeTnode(in->myDev,tn->internal[i]);
			    		tn->internal[i] = NULL;
					}
			    }
		    
			}
			return (allDone) ? 1 : 0;
		}
		else if(level == 0)
		{
			int hitLimit = 0;
			
			for(i = YAFFS_NTNODES_LEVEL0 -1; i >= 0 && !hitLimit; i--)
			{
			    if(tn->level0[i])
		    	{
					int j;
					
					chunkInInode = (chunkOffset << YAFFS_TNODES_LEVEL0_BITS ) + i;
					
					theChunk =  tn->level0[i] << in->myDev->chunkGroupBits;

					// Now we need to search for it
					for(j = 0,found = 0; theChunk && j < in->myDev->chunkGroupSize && !found; j++)
					{
						yaffs_ReadChunkTagsFromNAND(in->myDev,theChunk,&tags,&chunkDeleted);
						if(yaffs_TagsMatch(&tags,in->objectId,chunkInInode,chunkDeleted))
						{
							// found it;
							found = 1;
					
						}
						else
						{
							theChunk++;
						}
					}
					
					if(found)
					{
						yaffs_DeleteChunk(in->myDev,theChunk,1);
						in->nDataChunks--;
						if(limit)
						{ 
							*limit = *limit-1;
							if(*limit <= 0) 
							{ 
								hitLimit = 1;
							}
						}
					
					}
					

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -