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

📄 yaffs_guts.c

📁 full package of jaffs file system
💻 C
📖 第 1 页 / 共 5 页
字号:
		yaffs_MarkBlockBad(dev,blockInNAND);		yaffs_GetBlockInfo(dev,blockInNAND)->blockState = YAFFS_BLOCK_STATE_DEAD;	dev->nRetiredBlocks++;}static int yaffs_RewriteBufferedBlock(yaffs_Device *dev){	dev->doingBufferedBlockRewrite = 1;	//	//	Remove erased chunks	//  Rewrite existing chunks to a new block	//	Set current write block to the new block		dev->doingBufferedBlockRewrite = 0;		return 1;}static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND){	int blockInNAND = chunkInNAND/dev->nChunksPerBlock;	// Mark the block for retirement	yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1;	T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,(TSTR("**>>Block %d marked for retirement" TENDSTR),blockInNAND));	//TODO		// Just do a garbage collection on the affected block then retire the block	// NB recursion}static void yaffs_CheckWrittenBlock(yaffs_Device *dev,int chunkInNAND){}static void yaffs_HandleWriteChunkOk(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags){}static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaffs_ExtendedTags *tags){}static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND){	int blockInNAND = chunkInNAND/dev->nChunksPerBlock;	// Mark the block for retirement	yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1;	// Delete the chunk	yaffs_DeleteChunk(dev,chunkInNAND,1,__LINE__);}#if 0static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1,int dataSize){	if( memcmp(d0,d1,dataSize) != 0 ||		s0->tagByte0 != s1->tagByte0 ||		s0->tagByte1 != s1->tagByte1 ||		s0->tagByte2 != s1->tagByte2 ||		s0->tagByte3 != s1->tagByte3 ||		s0->tagByte4 != s1->tagByte4 ||		s0->tagByte5 != s1->tagByte5 ||		s0->tagByte6 != s1->tagByte6 ||		s0->tagByte7 != s1->tagByte7 ||		s0->ecc1[0]  != s1->ecc1[0]  ||		s0->ecc1[1]  != s1->ecc1[1]  ||		s0->ecc1[2]  != s1->ecc1[2]  ||		s0->ecc2[0]  != s1->ecc2[0]  ||		s0->ecc2[1]  != s1->ecc2[1]  ||		s0->ecc2[2]  != s1->ecc2[2] )		{			return 0;		}		return 1;}#endif///////////////////////// Object management //////////////////// List of spare objects// The list is hooked together using the first pointer// in the object// static yaffs_Object *yaffs_freeObjects = NULL;// static int yaffs_nFreeObjects;// static yaffs_ObjectList *yaffs_allocatedObjectList = NULL;// static yaffs_ObjectBucket yaffs_objectBucket[YAFFS_NOBJECT_BUCKETS];static __u16 yaffs_CalcNameSum(const YCHAR *name){	__u16 sum = 0;	__u16 i = 1;		YUCHAR *bname = (YUCHAR *)name;	if(bname)	{		while ((*bname) && (i <=YAFFS_MAX_NAME_LENGTH))		{#ifdef CONFIG_YAFFS_CASE_INSENSITIVE			sum += yaffs_toupper(*bname) * i;#else			sum += (*bname) * i;#endif			i++;			bname++;		}	}	return sum;}void yaffs_SetObjectName(yaffs_Object *obj, const YCHAR *name){#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM					if(name && yaffs_strlen(name) <= YAFFS_SHORT_NAME_LENGTH)					{						yaffs_strcpy(obj->shortName,name);					}					else					{						obj->shortName[0]=_Y('\0');					}#endif					obj->sum = yaffs_CalcNameSum(name);}#if 0void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare){	yaffs_ECCCalculate(data , spare->ecc1);	yaffs_ECCCalculate(&data[256] , spare->ecc2);}#endif///////////////////////// 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 directlystatic 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 outstatic 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 liststatic 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 0void 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;		}int yaffs_FindChunkInGroup(yaffs_Device *dev, int theChunk, yaffs_ExtendedTags *tags, int objectId, int chunkInInode){	int j;							for(j = 0; theChunk && j < dev->chunkGroupSize; j++)	{		if(yaffs_CheckChunkBit(dev,theChunk / dev->nChunksPerBlock,theChunk % dev->nChunksPerBlock))		{			yaffs_ReadChunkWithTagsFromNAND(dev,theChunk,NULL,tags);			if(yaffs_TagsMatch(tags,objectId,chunkInInode))			{				// found it;				return theChunk;								}		}		theChunk++;	}	return -1;}// 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_ExtendedTags tags;	int foundChunk;	yaffs_Device *dev = in->myDev;	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(dev,tn->internal[i]);			    		tn->internal[i] = NULL;					}			    }		    

⌨️ 快捷键说明

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