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

📄 yaffs_guts.c

📁 一个 yaffs2 日志文件系统 支持NAND FLASH等
💻 C
📖 第 1 页 / 共 5 页
字号:
		    	{					theChunk =  (tn->level0[i] << in->myDev->chunkGroupBits);					T(YAFFS_TRACE_SCAN,(TSTR("soft delete tch %d cgb %d chunk %d" TENDSTR),						tn->level0[i],in->myDev->chunkGroupBits,theChunk));											theBlock =	yaffs_GetBlockInfo(in->myDev,  theChunk/in->myDev->nChunksPerBlock);					if(theBlock)					{						theBlock->softDeletions++;					}			    	tn->level0[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, 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.// yaffs_PruneWorker should only be called by yaffs_PruneFileStructure()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));       if (!newObjects)    {		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 list_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 = YMALLOC(sizeof(yaffs_ObjectList));	if(!list)	{		T(YAFFS_TRACE_ALLOCATE,(TSTR("Could not add objects to management list" TENDSTR)));	}	else	{		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 outstatic yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device *dev){	yaffs_Object *tn = NULL;		// 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--;				// Now sweeten it up...			memset(tn,0,sizeof(yaffs_Object));		tn->myDev = dev;		tn->chunkId = -1;		tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN;		INIT_LIST_HEAD(&(tn->hardLinks));		INIT_LIST_HEAD(&(tn->hashLink));		INIT_LIST_HEAD(&tn->siblings);				// 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);			}	}		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 has 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->st_mode = mode;		obj->myDev = dev;		obj->chunkId = 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(!list_empty(&tn->hashLink))	{		list_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 liststatic void yaffs_FreeObject(yaffs_Object *tn){	yaffs_Device *dev = tn->myDev;		yaffs_UnhashObject(tn);		// Link into the free list.	tn->siblings.next = (struct list_head *)(dev->freeObjects);	dev->freeObjects = tn;	dev->nFreeObjects++;}static void yaffs_DeinitialiseObjects(yaffs_Device *dev){	// Free the list of allocated Objects		while( dev->allocatedObjectList)	{		YFREE(dev->allocatedObjectList->objects);		dev->allocatedObjectList =  dev->allocatedObjectList->next;	}		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++)	{		INIT_LIST_HEAD(&dev->objectBucket[i].list);		dev->objectBucket[i].count = 0;		}}int yaffs_FindNiceObjectBucket(yaffs_Device *dev){	static int x = 0;	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 list_head *i;		__u32 n = (__u32)bucket;	//yaffs_CheckObjectHashSanity();			while(!found)	{		found = 1;		n +=  YAFFS_NOBJECT_BUCKETS;		if(1 ||dev->objectBucket[bucket].count > 0)		{			list_for_each(i,&dev->objectBucket[bucket].list)			{				// If there is already one in the list				if(i && list_entry(i, yaffs_Object,hashLink)->objectId == n)				{					found = 0;				}			}		}	}		//T(("bucket %d count %d inode %d\n",bucket,yaffs_objectBucket[bucket].count,n);		return n;	}void yaffs_HashObject(yaffs_Object *in){	int bucket = yaffs_HashFunction(in->objectId);	yaffs_Device *dev = in->myDev;		if(!list_empty(&in->hashLink))	{		//YINFO("!!!");	}		list_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 list_head *i;	yaffs_Object *in;		list_for_each(i,&dev->objectBucket[bucket].list)	{		// Look if it is in the list		if(i)		{			in = list_entry(i, yaffs_Object,hashLink);			if(in->objectId == number)			{				return in;			}		}	}		return NULL;}yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type){			yaffs_Object *theObject;	if(number < 0)	{		number = yaffs_CreateNewObjectNumber(dev);	}		theObject = yaffs_AllocateEmptyObject(dev);		if(theObject)	{		theObject->fake = 0;		theObject->renameAllowed = 1;		theObject->unlinkAllowed = 1;		theObject->objectId = number;		yaffs_HashObject(theObject);		theObject->variantType = type;#ifdef CONFIG_YAFFS_WINCE		yfsd_WinFileTimeNow(theObject->win_atime);		theObject->win_ctime[0] = theObject->win_mtime[0] = theObject->win_atime[0];		theObject->win_ctime[1] = theObject->win_mtime[1] = theObject->win_atime[1];#else		theObject->st_atime = theObject->st_mtime =	theObject->st_ctime = CURRENT_TIME;#endif		switch(type)		{			case YAFFS_OBJECT_TYPE_FILE: 				theObject->variant.fileVariant.fileSize = 0;				theObject->variant.fileVariant.scannedFileSize = 0;				theObject->variant.fileVariant.topLevel = 0;				theObject->variant.fileVariant.top  = yaffs_GetTnode(dev);				break;			case YAFFS_OBJECT_TYPE_DIRECTORY:				INIT_LIST_HEAD(&theObject->variant.directoryVariant.children);				break;			case YAFFS_OBJECT_TYPE_SYMLINK:				// No action required				break;			case YAFFS_OBJECT_TYPE_HARDLINK:				// No action required				break;			case YAFFS_OBJECT_TYPE_SPECIAL:				// No action required				break;			case YAFFS_OBJECT_TYPE_UNKNOWN:				// todo this should not happen				break;		}	}		return theObject;}yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device *dev, int number,yaffs_ObjectType type){	yaffs_Object *theObject = NULL;		if(number > 0)	{		theObject = yaffs_FindObjectByNumber(dev,number);	}		if(!theObject)	{		theObject = yaffs_CreateNewObject(dev,number,type);	}		return theObject;}char *yaffs_CloneString(const char *str){	char *newStr = NULL;		if(str && *str)	{		newStr = YMALLOC(strlen(str) + 1);		strcpy(newStr,str);	}	return newStr;	}//// Mknod (create) a new object.// equivalentObject only has meaning for a hard link;// aliasString only has meaning for a sumlink.// rdev only has meaning for devices (a subset of special objects)yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type,								 yaffs_Object *parent,								 const char *name, 								 __u32 mode,								 __u32 uid,								 __u32 gid,								 yaffs_Object *equivalentObject,								 const char *aliasString,								 __u32 rdev){	yaffs_Object *in;	yaffs_Device *dev = parent->myDev;		// Check if the entry exists. If it does then fail the call since we don't want a dup.	if(yaffs_FindObjectByName(parent,name))	{		return NULL;	}		in = yaffs_CreateNewObject(dev,-1,type);		if(in)	{		in->chunkId = -1;		in->valid = 1;		in->variantType = type;		in->st_mode  = mode;		#ifdef CONFIG_YAFFS_WINCE		yfsd_WinFileTimeNow(in->win_atime);		in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0];

⌨️ 快捷键说明

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