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

📄 yaffs_guts.c

📁 linux 镜像文件制作 用于压制yaffs2类型的文件镜像啊啊啊啊啊啊
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (bi->chunkErrorStrikes > 3) {			bi->needsRetiring = 1; /* Too many stikes, so retire this */			T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Block struck out" TENDSTR)));		}	}}static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND,		int erasedOk){	int blockInNAND = chunkInNAND / dev->nChunksPerBlock;	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);	yaffs_HandleChunkError(dev, bi);	if (erasedOk) {		/* Was an actual write failure, so mark the block for retirement  */		bi->needsRetiring = 1;		T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,		  (TSTR("**>> Block %d needs retiring" TENDSTR), blockInNAND));	}	/* Delete the chunk */	yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);}/*---------------- Name handling functions ------------*/static __u16 yaffs_CalcNameSum(const YCHAR *name){	__u16 sum = 0;	__u16 i = 1;	const YUCHAR *bname = (const YUCHAR *) name;	if (bname) {		while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH/2))) {#ifdef CONFIG_YAFFS_CASE_INSENSITIVE			sum += yaffs_toupper(*bname) * i;#else			sum += (*bname) * i;#endif			i++;			bname++;		}	}	return sum;}static void yaffs_SetObjectName(yaffs_Object *obj, const YCHAR *name){#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM	memset(obj->shortName, 0, sizeof(YCHAR) * (YAFFS_SHORT_NAME_LENGTH+1));	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);}/*-------------------- TNODES ------------------- * List of spare tnodes * The list is hooked together using the first pointer * in the tnode. *//* 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;	int tnodeSize;	yaffs_Tnode *newTnodes;	__u8 *mem;	yaffs_Tnode *curr;	yaffs_Tnode *next;	yaffs_TnodeList *tnl;	if (nTnodes < 1)		return YAFFS_OK;	/* Calculate the tnode size in bytes for variable width tnode support.	 * Must be a multiple of 32-bits  */	tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;	if (tnodeSize < sizeof(yaffs_Tnode))		tnodeSize = sizeof(yaffs_Tnode);	/* make these things */	newTnodes = YMALLOC(nTnodes * tnodeSize);	mem = (__u8 *)newTnodes;	if (!newTnodes) {		T(YAFFS_TRACE_ERROR,			(TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));		return YAFFS_FAIL;	}	/* Hook them into the free list */#if 0	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] = (void *)1;#endif	}	newTnodes[nTnodes - 1].internal[0] = dev->freeTnodes;#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG	newTnodes[nTnodes - 1].internal[YAFFS_NTNODES_INTERNAL] = (void *)1;#endif	dev->freeTnodes = newTnodes;#else	/* New hookup for wide tnodes */	for (i = 0; i < nTnodes - 1; i++) {		curr = (yaffs_Tnode *) &mem[i * tnodeSize];		next = (yaffs_Tnode *) &mem[(i+1) * tnodeSize];		curr->internal[0] = next;	}	curr = (yaffs_Tnode *) &mem[(nTnodes - 1) * tnodeSize];	curr->internal[0] = dev->freeTnodes;	dev->freeTnodes = (yaffs_Tnode *)mem;#endif	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)));		   return YAFFS_FAIL;	} 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_GetTnodeRaw(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] != (void *)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--;	}	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/	return tn;}static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev){	yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev);	int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;	if (tnodeSize < sizeof(yaffs_Tnode))		tnodeSize = sizeof(yaffs_Tnode);	if (tn)		memset(tn, 0, tnodeSize);	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] = (void *)1;#endif		tn->internal[0] = dev->freeTnodes;		dev->freeTnodes = tn;		dev->nFreeTnodes++;	}	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/}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;}void yaffs_PutLevel0Tnode(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos,		unsigned val){	__u32 *map = (__u32 *)tn;	__u32 bitInMap;	__u32 bitInWord;	__u32 wordInMap;	__u32 mask;	pos &= YAFFS_TNODES_LEVEL0_MASK;	val >>= dev->chunkGroupBits;	bitInMap = pos * dev->tnodeWidth;	wordInMap = bitInMap / 32;	bitInWord = bitInMap & (32 - 1);	mask = dev->tnodeMask << bitInWord;	map[wordInMap] &= ~mask;	map[wordInMap] |= (mask & (val << bitInWord));	if (dev->tnodeWidth > (32 - bitInWord)) {		bitInWord = (32 - bitInWord);		wordInMap++;;		mask = dev->tnodeMask >> (/*dev->tnodeWidth -*/ bitInWord);		map[wordInMap] &= ~mask;		map[wordInMap] |= (mask & (val >> bitInWord));	}}static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn,		unsigned pos){	__u32 *map = (__u32 *)tn;	__u32 bitInMap;	__u32 bitInWord;	__u32 wordInMap;	__u32 val;	pos &= YAFFS_TNODES_LEVEL0_MASK;	bitInMap = pos * dev->tnodeWidth;	wordInMap = bitInMap / 32;	bitInWord = bitInMap & (32 - 1);	val = map[wordInMap] >> bitInWord;	if	(dev->tnodeWidth > (32 - bitInWord)) {		bitInWord = (32 - bitInWord);		wordInMap++;;		val |= (map[wordInMap] << bitInWord);	}	val &= dev->tnodeMask;	val <<= dev->chunkGroupBits;	return val;}/* ------------------- End of individual 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. */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)		return NULL;	if (chunkId > YAFFS_MAX_CHUNK_ID)		return NULL;	/* First check we're tall enough (ie enough topLevel) */	i = chunkId >> YAFFS_TNODES_LEVEL0_BITS;	requiredTallness = 0;	while (i) {		i >>= YAFFS_TNODES_INTERNAL_BITS;		requiredTallness++;	}	if (requiredTallness > fStruct->topLevel)		return NULL; /* Not tall enough, so we can't find it */	/* Traverse down to level 0 */	while (level > 0 && tn) {		tn = tn->internal[(chunkId >>			(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. * *  If the tn argument is NULL, then a fresh tnode will be added otherwise the specified tn will *  be plugged into the ttree. */static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device *dev,					yaffs_FileStructure *fStruct,					__u32 chunkId,					yaffs_Tnode *passedTn){	int requiredTallness;	int i;	int l;	yaffs_Tnode *tn;	__u32 x;	/* Check sane level and page Id */	if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL)		return NULL;	if (chunkId > YAFFS_MAX_CHUNK_ID)		return NULL;	/* First check we're tall enough (ie enough topLevel) */	x = chunkId >> YAFFS_TNODES_LEVEL0_BITS;	requiredTallness = 0;	while (x) {		x >>= YAFFS_TNODES_INTERNAL_BITS;		requiredTallness++;	}	if (requiredTallness > fStruct->topLevel) {		/* Not tall enough, gotta make the tree taller */		for (i = fStruct->topLevel; i < requiredTallness; i++) {			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;	if (l > 0) {		while (l > 0 && tn) {			x = (chunkId >>			     (YAFFS_TNODES_LEVEL0_BITS +			      (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) &			    YAFFS_TNODES_INTERNAL_MASK;			if ((l > 1) && !tn->internal[x]) {				/* Add missing non-level-zero tnode */				tn->internal[x] = yaffs_GetTnode(dev);			} else if (l == 1) {				/* Looking from level 1 at level 0 */				if (passedTn) {					/* If we already have one, then release it.*/					if (tn->internal[x])						yaffs_FreeTnode(dev, tn->internal[x]);					tn->internal[x] = passedTn;				} else if (!tn->internal[x]) {					/* Don't have one, none passed in */					tn->internal[x] = yaffs_GetTnode(dev);				}			}			tn = tn->internal[x];			l--;		}	} else {		/* top is level 0 */		if (passedTn) {			memcpy(tn, passedTn, (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);			yaffs_FreeTnode(dev, passedTn);		}	}	return tn;}static 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;					}				}			}			return (allDone) ? 1 : 0;		} else if (level == 0) {			int hitLimit = 0;			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0 && !hitLimit;					i--) {				theChunk = yaffs_GetChunkGroupBase(dev, tn, i);				if (theChunk) {

⌨️ 快捷键说明

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