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

📄 yaffs_guts.c

📁 linux 镜像文件制作 用于压制yaffs2类型的文件镜像啊啊啊啊啊啊
💻 C
📖 第 1 页 / 共 5 页
字号:
					chunkInInode = (chunkOffset <<						YAFFS_TNODES_LEVEL0_BITS) + i;					foundChunk =						yaffs_FindChunkInGroup(dev,								theChunk,								&tags,								in->objectId,								chunkInInode);					if (foundChunk > 0) {						yaffs_DeleteChunk(dev,								  foundChunk, 1,								  __LINE__);						in->nDataChunks--;						if (limit) {							*limit = *limit - 1;							if (*limit <= 0)								hitLimit = 1;						}					}					yaffs_PutLevel0Tnode(dev, tn, i, 0);				}			}			return (i < 0) ? 1 : 0;		}	}	return 1;}static void yaffs_SoftDeleteChunk(yaffs_Device *dev, int chunk){	yaffs_BlockInfo *theBlock;	T(YAFFS_TRACE_DELETION, (TSTR("soft delete chunk %d" TENDSTR), chunk));	theBlock = yaffs_GetBlockInfo(dev, chunk / dev->nChunksPerBlock);	if (theBlock) {		theBlock->softDeletions++;		dev->nFreeChunks++;	}}/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all the chunks in the file. * All soft deleting does is increment the block's softdelete count and pulls the chunk out * of the tnode. * Thus, essentially this is the same as DeleteWorker except that the chunks are soft deleted. */static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn,				  __u32 level, int chunkOffset){	int i;	int theChunk;	int allDone = 1;	yaffs_Device *dev = in->myDev;	if (tn) {		if (level > 0) {			for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0;			     i--) {				if (tn->internal[i]) {					allDone =					    yaffs_SoftDeleteWorker(in,								   tn->								   internal[i],								   level - 1,								   (chunkOffset								    <<								    YAFFS_TNODES_INTERNAL_BITS)								   + i);					if (allDone) {						yaffs_FreeTnode(dev,								tn->								internal[i]);						tn->internal[i] = NULL;					} else {						/* Hoosterman... how could this happen? */					}				}			}			return (allDone) ? 1 : 0;		} else if (level == 0) {			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) {				theChunk = yaffs_GetChunkGroupBase(dev, tn, i);				if (theChunk) {					/* Note this does not find the real chunk, only the chunk group.					 * We make an assumption that a chunk group is not larger than					 * a block.					 */					yaffs_SoftDeleteChunk(dev, theChunk);					yaffs_PutLevel0Tnode(dev, tn, i, 0);				}			}			return 1;		}	}	return 1;}static void yaffs_SoftDeleteFile(yaffs_Object *obj){	if (obj->deleted &&	    obj->variantType == YAFFS_OBJECT_TYPE_FILE && !obj->softDeleted) {		if (obj->nDataChunks <= 0) {			/* Empty file with no duplicate object headers, just delete it immediately */			yaffs_FreeTnode(obj->myDev,					obj->variant.fileVariant.top);			obj->variant.fileVariant.top = NULL;			T(YAFFS_TRACE_TRACING,			  (TSTR("yaffs: Deleting empty file %d" TENDSTR),			   obj->objectId));			yaffs_DoGenericObjectDeletion(obj);		} else {			yaffs_SoftDeleteWorker(obj,					       obj->variant.fileVariant.top,					       obj->variant.fileVariant.					       topLevel, 0);			obj->softDeleted = 1;		}	}}/* Pruning removes any part of the file structure tree that is beyond the * bounds of the file (ie that does not point to chunks). * * A file should only get pruned when its size is reduced. * * Before pruning, the chunks must be pulled from the tree and the * level 0 tnode entries must be zeroed out. * Could also use this for file deletion, but that's probably better handled * by a special case. */static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device *dev, yaffs_Tnode *tn,				__u32 level, int del0){	int i;	int hasData;	if (tn) {		hasData = 0;		for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) {			if (tn->internal[i] && level > 0) {				tn->internal[i] =				    yaffs_PruneWorker(dev, tn->internal[i],						      level - 1,						      (i == 0) ? del0 : 1);			}			if (tn->internal[i])				hasData++;		}		if (hasData == 0 && del0) {			/* Free and return NULL */			yaffs_FreeTnode(dev, tn);			tn = NULL;		}	}	return tn;}static int yaffs_PruneFileStructure(yaffs_Device *dev,				yaffs_FileStructure *fStruct){	int i;	int hasData;	int done = 0;	yaffs_Tnode *tn;	if (fStruct->topLevel > 0) {		fStruct->top =		    yaffs_PruneWorker(dev, fStruct->top, fStruct->topLevel, 0);		/* Now we have a tree with all the non-zero branches NULL but the height		 * is the same as it was.		 * Let's see if we can trim internal tnodes to shorten the tree.		 * We can do this if only the 0th element in the tnode is in use		 * (ie all the non-zero are NULL)		 */		while (fStruct->topLevel && !done) {			tn = fStruct->top;			hasData = 0;			for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {				if (tn->internal[i])					hasData++;			}			if (!hasData) {				fStruct->top = tn->internal[0];				fStruct->topLevel--;				yaffs_FreeTnode(dev, tn);			} else {				done = 1;			}		}	}	return YAFFS_OK;}/*-------------------- End of File Structure functions.-------------------*//* yaffs_CreateFreeObjects creates a bunch more objects and * adds them to the object free list. */static int yaffs_CreateFreeObjects(yaffs_Device *dev, int nObjects){	int i;	yaffs_Object *newObjects;	yaffs_ObjectList *list;	if (nObjects < 1)		return YAFFS_OK;	/* make these things */	newObjects = YMALLOC(nObjects * sizeof(yaffs_Object));	list = YMALLOC(sizeof(yaffs_ObjectList));	if (!newObjects || !list) {		if (newObjects)			YFREE(newObjects);		if (list)			YFREE(list);		T(YAFFS_TRACE_ALLOCATE,		  (TSTR("yaffs: Could not allocate more objects" TENDSTR)));		return YAFFS_FAIL;	}	/* Hook them into the free list */	for (i = 0; i < nObjects - 1; i++) {		newObjects[i].siblings.next =				(struct ylist_head *)(&newObjects[i + 1]);	}	newObjects[nObjects - 1].siblings.next = (void *)dev->freeObjects;	dev->freeObjects = newObjects;	dev->nFreeObjects += nObjects;	dev->nObjectsCreated += nObjects;	/* Now add this bunch of Objects to a list for freeing up. */	list->objects = newObjects;	list->next = dev->allocatedObjectList;	dev->allocatedObjectList = list;	return YAFFS_OK;}/* AllocateEmptyObject gets us a clean Object. Tries to make allocate more if we run out */static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device *dev){	yaffs_Object *tn = NULL;#ifdef VALGRIND_TEST	tn = YMALLOC(sizeof(yaffs_Object));#else	/* If there are none left make more */	if (!dev->freeObjects)		yaffs_CreateFreeObjects(dev, YAFFS_ALLOCATION_NOBJECTS);	if (dev->freeObjects) {		tn = dev->freeObjects;		dev->freeObjects =			(yaffs_Object *) (dev->freeObjects->siblings.next);		dev->nFreeObjects--;	}#endif	if (tn) {		/* Now sweeten it up... */		memset(tn, 0, sizeof(yaffs_Object));		tn->beingCreated = 1;		tn->myDev = dev;		tn->hdrChunk = 0;		tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN;		YINIT_LIST_HEAD(&(tn->hardLinks));		YINIT_LIST_HEAD(&(tn->hashLink));		YINIT_LIST_HEAD(&tn->siblings);		/* Now make the directory sane */		if (dev->rootDir) {			tn->parent = dev->rootDir;			ylist_add(&(tn->siblings), &dev->rootDir->variant.directoryVariant.children);		}		/* Add it to the lost and found directory.		 * NB Can't put root or lostNFound in lostNFound so		 * check if lostNFound exists first		 */		if (dev->lostNFoundDir)			yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn);		tn->beingCreated = 0;	}	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/	return tn;}static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device *dev, int number,					       __u32 mode){	yaffs_Object *obj =	    yaffs_CreateNewObject(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);	if (obj) {		obj->fake = 1;		/* it is fake so it might have no NAND presence... */		obj->renameAllowed = 0;	/* ... and we're not allowed to rename it... */		obj->unlinkAllowed = 0;	/* ... or unlink it */		obj->deleted = 0;		obj->unlinked = 0;		obj->yst_mode = mode;		obj->myDev = dev;		obj->hdrChunk = 0;	/* Not a valid chunk. */	}	return obj;}static void yaffs_UnhashObject(yaffs_Object *tn){	int bucket;	yaffs_Device *dev = tn->myDev;	/* If it is still linked into the bucket list, free from the list */	if (!ylist_empty(&tn->hashLink)) {		ylist_del_init(&tn->hashLink);		bucket = yaffs_HashFunction(tn->objectId);		dev->objectBucket[bucket].count--;	}}/*  FreeObject frees up a Object and puts it back on the free list */static void yaffs_FreeObject(yaffs_Object *tn){	yaffs_Device *dev = tn->myDev;#ifdef __KERNEL__	T(YAFFS_TRACE_OS, (TSTR("FreeObject %p inode %p"TENDSTR), tn, tn->myInode));#endif	if (tn->parent)		YBUG();	if (!ylist_empty(&tn->siblings))		YBUG();#ifdef __KERNEL__	if (tn->myInode) {		/* We're still hooked up to a cached inode.		 * Don't delete now, but mark for later deletion		 */		tn->deferedFree = 1;		return;	}#endif	yaffs_UnhashObject(tn);#ifdef VALGRIND_TEST	YFREE(tn);#else	/* Link into the free list. */	tn->siblings.next = (struct ylist_head *)(dev->freeObjects);	dev->freeObjects = tn;	dev->nFreeObjects++;#endif	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/}#ifdef __KERNEL__void yaffs_HandleDeferedFree(yaffs_Object *obj){	if (obj->deferedFree)		yaffs_FreeObject(obj);}#endifstatic void yaffs_DeinitialiseObjects(yaffs_Device *dev){	/* Free the list of allocated Objects */	yaffs_ObjectList *tmp;	while (dev->allocatedObjectList) {		tmp = dev->allocatedObjectList->next;		YFREE(dev->allocatedObjectList->objects);		YFREE(dev->allocatedObjectList);		dev->allocatedObjectList = tmp;	}	dev->freeObjects = NULL;	dev->nFreeObjects = 0;}static void yaffs_InitialiseObjects(yaffs_Device *dev){	int i;	dev->allocatedObjectList = NULL;	dev->freeObjects = NULL;	dev->nFreeObjects = 0;	for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {		YINIT_LIST_HEAD(&dev->objectBucket[i].list);		dev->objectBucket[i].count = 0;	}}static int yaffs_FindNiceObjectBucket(yaffs_Device *dev){	static int x;	int i;	int l = 999;	int lowest = 999999;	/* First let's see if we can find one that's empty. */	for (i = 0; i < 10 && lowest > 0; i++) {		x++;		x %= YAFFS_NOBJECT_BUCKETS;		if (dev->objectBucket[x].count < lowest) {			lowest = dev->objectBucket[x].count;			l = x;		}	}	/* If we didn't find an empty list, then try	 * looking a bit further for a short one	 */	for (i = 0; i < 10 && lowest > 3; i++) {		x++;		x %= YAFFS_NOBJECT_BUCKETS;		if (dev->objectBucket[x].count < lowest) {			lowest = dev->objectBucket[x].count;			l = x;		}	}	return l;}static int yaffs_CreateNewObjectNumber(yaffs_Device *dev){	int bucket = yaffs_FindNiceObjectBucket(dev);	/* Now find an object value that has not already been taken	 * by scanning the list.	 */	int found = 0;	struct ylist_head *i;	__u32 n = (__u32) bucket;	/* yaffs_CheckObjectHashSanity();  */	while (!found) {		found = 1;		n += YAFFS_NOBJECT_BUCKETS;		if (1 || dev->objectBucket[bucket].count > 0) {			ylist_for_each(i, &dev->objectBucket[bucket].list) {				/* If there is already one in the list */				if (i && ylist_entry(i, yaffs_Object,						hashLink)->objectId == n) {					found = 0;				}			}		}	}	return n;}static void yaffs_HashObject(yaffs_Object *in){	int bucket = yaffs_HashFunction(in->objectId);	yaffs_Device *dev = in->myDev;	ylist_add(&in->hashLink, &dev->objectBucket[bucket].list);	dev->objectBucket[bucket].count++;}yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number){	int bucket = yaffs_HashFunction(number);	struct ylist_head *i;	yaffs_Object *in;	ylist_for_each(i, &dev->objectBucket[bucket].list) {		/* Look if it is in the list */		if (i) {			in = ylist_entry(i, yaffs_Object, hashLink);			if (in->objectId == number) {#ifdef __KERNEL__				/* Don't tell the VFS about this one if it is defered free */				if (in->deferedFree)					return NULL;#endif				return in;			}		}

⌨️ 快捷键说明

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