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

📄 yaffs_guts.cpp

📁 文件系统在DSP上的实现
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//描述:从HASH表里把该number的yaffs_Object找出来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_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type){			yaffs_Object *theObject;	if(number < 0)    //number<0,则表示创建	{		number = yaffs_CreateNewObjectNumber(dev);   //新建一个没被使用的objectId	}		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#if defined(CONFIG_KERNEL_2_5)		theObject->st_atime = theObject->st_mtime =	theObject->st_ctime = CURRENT_TIME.tv_sec;		#else		theObject->st_atime = theObject->st_mtime =	theObject->st_ctime = CURRENT_TIME;		#endif#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;}//描述:从HASH表里把该number的yaffs_Object找出来,如果找不出来则新建一个//参数:@number yaffs_Tags.objectId(注意不是chunkId),如果number<0,则表示创建yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device *dev, int number,yaffs_ObjectType type){	yaffs_Object *theObject = NULL;		if(number > 0)	{		theObject = yaffs_FindObjectByNumber(dev,number); //从HASH表里把该number的yaffs_Object找出来	}		if(!theObject)	{		theObject = yaffs_CreateNewObject(dev,number,type);  //新建一个yaffs_Object,并对它进行初始化	}		return theObject;}char *yaffs_CloneString(const char *str){	char *newStr = NULL;		if(str && *str)	{		newStr = (char* )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_Object加入到的文件系统目录结构//      生成该文件的yaffs_ObjectHeader并把它作为新chunk的数据写到FLASH,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);  //新建一个yaffs_Object,并对它进行初始化		if(in)	{		in->chunkId = -1;   //此chunkId就是chunkInNAND,是yaffs_ObjectHeader的chunkInNAND		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];		in->win_ctime[1] = in->win_mtime[1] = in->win_atime[1];		#else#if defined(CONFIG_KERNEL_2_5)		in->st_atime = in->st_mtime = in->st_ctime = CURRENT_TIME.tv_sec;#else		in->st_atime = in->st_mtime = in->st_ctime = CURRENT_TIME;#endif		in->st_rdev  = rdev;		in->st_uid   = uid;		in->st_gid   = gid;#endif				in->nDataChunks = 0;		yaffs_SetObjectName(in,name);		in->dirty = 1;				yaffs_AddObjectToDirectory(parent,in);				in->myDev = parent->myDev;								switch(type)		{			case YAFFS_OBJECT_TYPE_SYMLINK:				in->variant.symLinkVariant.alias = yaffs_CloneString(aliasString);				break;			case YAFFS_OBJECT_TYPE_HARDLINK:				in->variant.hardLinkVariant.equivalentObject = equivalentObject;				in->variant.hardLinkVariant.equivalentObjectId = equivalentObject->objectId;				list_add(&in->hardLinks,&equivalentObject->hardLinks);				break;			case YAFFS_OBJECT_TYPE_FILE: // do nothing			case YAFFS_OBJECT_TYPE_DIRECTORY: // do nothing			case YAFFS_OBJECT_TYPE_SPECIAL: // do nothing			case YAFFS_OBJECT_TYPE_UNKNOWN:				break;		}		if(/*yaffs_GetNumberOfFreeChunks(dev) <= 0 || */		   yaffs_UpdateObjectHeader(in,name,0) < 0)		{		 //根据in的字段,参数name作为文件名,生成yaffs_ObjectHeader并把它作为新chunk的数据写到FLASH,                 //返回写到的chunkInNAMD			// Could not create the object header, fail the creation			yaffs_AbortHalfCreatedObject(in);			in = NULL;		}	}		return in;}yaffs_Object *yaffs_MknodFile(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid){	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_FILE,parent,name,mode,uid,gid,NULL,NULL,0);}yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid){	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_DIRECTORY,parent,name,mode,uid,gid,NULL,NULL,0);}yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid, __u32 rdev){	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_DIRECTORY,parent,name,mode,uid,gid,NULL,NULL,rdev);}yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid,const char *alias){	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SYMLINK,parent,name,mode,uid,gid,NULL,alias,0);}// NB yaffs_Link returns the object id of the equivalent object.yaffs_Object *yaffs_Link(yaffs_Object *parent, const char *name, yaffs_Object *equivalentObject){	// Get the real object in case we were fed a hard link as an equivalent object	equivalentObject = yaffs_GetEquivalentObject(equivalentObject);		if(yaffs_MknodObject(YAFFS_OBJECT_TYPE_HARDLINK,parent,name,0,0,0,equivalentObject,NULL,0))	{		return equivalentObject;	}	else	{		return NULL;	}	}static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const char *newName,int force){	int unlinkOp;	if(newDir == NULL)	{		newDir = obj->parent; // use the old directory	}	unlinkOp = (newDir == obj->myDev->unlinkedDir && obj->variantType == YAFFS_OBJECT_TYPE_FILE);		// If the object is a file going into the unlinked directory, then it is OK to just stuff it in since	// duplicate names are allowed.	// Otherwise only proceed if the new name does not exist and if we're putting it into a directory.	if( (unlinkOp|| 		 force || 		 !yaffs_FindObjectByName(newDir,newName))  &&	     newDir->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)	{		yaffs_SetObjectName(obj,newName);		obj->dirty = 1;				yaffs_AddObjectToDirectory(newDir,obj);				if(unlinkOp) obj->unlinked = 1;						if(yaffs_UpdateObjectHeader(obj,newName,0) >= 0)		{			return YAFFS_OK;		}	}		return YAFFS_FAIL;}int yaffs_RenameObject(yaffs_Object *oldDir, const char *oldName, yaffs_Object *newDir, const char *newName){	yaffs_Object *obj;	int force = 0;	#ifdef CONFIG_YAFFS_CASE_INSENSITIVE	// Special case for WinCE.	// While look-up is case insensitive, the name isn't.	// THerefore we might want to change x.txt to X.txt	if(oldDir == newDir && _stricmp(oldName,newName) == 0)	{		force = 1;	}	#endif		obj = yaffs_FindObjectByName(oldDir,oldName);	if(obj && obj->renameAllowed)	{		return yaffs_ChangeObjectName(obj,newDir,newName,force);	}	return YAFFS_FAIL;}static int yaffs_CheckObjectHashSanity(yaffs_Device *dev){	// Scan the buckets and check that the lists 	// have as many members as the count says there are	int bucket;	int countEm;	struct list_head *j;	int ok = YAFFS_OK;		for(bucket = 0; bucket < YAFFS_NOBJECT_BUCKETS; bucket++)	{		countEm = 0;				list_for_each(j,&dev->objectBucket[bucket].list)		{			countEm++;		}				if(countEm != dev->objectBucket[bucket].count)		{			T(YAFFS_TRACE_ERROR,(TSTR("Inode hash inconsistency" TENDSTR)));			ok = YAFFS_FAIL;		}	}	return ok;}#if 0void yaffs_ObjectTest(yaffs_Device *dev){	yaffs_Object *in[1000];	int inNo[1000];	yaffs_Object *inold[1000];	int i;	int j;		memset(in,0,1000*sizeof(yaffs_Object *));	memset(inold,0,1000*sizeof(yaffs_Object *));		yaffs_CheckObjectHashSanity(dev);		for(j = 0; j < 10; j++)	{		//T(("%d\n",j));				for(i = 0; i < 1000; i++)		{			in[i] = yaffs_CreateNewObject(dev,-1,YAFFS_OBJECT_TYPE_FILE);			if(!in[i])			{				YINFO("No more inodes");			}			else			{				inNo[i] = in[i]->objectId;			}		}				for(i = 0; i < 1000; i++)		{			if(yaffs_FindObjectByNumber(dev,inNo[i]) != in[i])			{				//T(("Differnce in look up test\n"));			}			else			{				// T(("Look up ok\n"));			}		}				yaffs_CheckObjectHashSanity(dev);			for(i = 0; i < 1000; i+=3)		{			yaffs_FreeObject(in[i]);				in[i] = NULL;		}					yaffs_CheckObjectHashSanity(dev);	}		}#endif/////////////////////////// Block Management and Page Allocation ///////////////////static int yaffs_InitialiseBlocks(yaffs_Device *dev,int nBlocks){	dev->allocationBlock = -1; // force it to get a new one	//Todo we're assuming the malloc will pass.	dev->blockInfo = (yaffs_BlockInfo* )YMALLOC(nBlocks * sizeof(yaffs_BlockInfo));	// Set up dynamic blockinfo stuff.	dev->chunkBitmapStride = (dev->nChunksPerBlock+7)/8;	dev->chunkBits = (__u8* )YMALLOC(dev->chunkBitmapStride * nBlocks);	if(dev->blockInfo && dev->chunkBits)	{		memset(dev->blockInfo,0,nBlocks * sizeof(yaffs_BlockInfo));		memset(dev->chunkBits,0,dev->chunkBitmapStride * nBlocks);		return YAFFS_OK;	}		return YAFFS_FAIL;	}static void yaffs_DeinitialiseBlocks(yaffs_Device *dev){	YFREE(dev->blockInfo);	dev->blockInfo = NULL;	YFREE(dev->chunkBits);	dev->chunkBits = NULL;}// FindDiretiestBlock is used to select the dirtiest block (or close enough)// for garbage collection.//描述:找出已经写满并且有用页面最少的块,并返回块号static int yaffs_FindDirtiestBlock(yaffs_Device *dev,int aggressive){	int b = dev->currentDirtyChecker;		int i;	int iterations;	int dirtiest = -1;	int pagesInUse; 	yaffs_BlockInfo *bi;	// If we're doing aggressive GC then we are happy to take a less-dirty block, and	// search further.		pagesInUse = (aggressive)? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;                        //有用页面最少的最低标准	//aggressive与否决定扫描块的个数	if(aggressive)	{		iterations = dev->endBlock - dev->startBlock + 1;	}	else	{		iterations = dev->endBlock - dev->startBlock + 1;		iterations = iterations / 16;		if(iterations > 200)		{			iterations = 200;		}	}		for(i = 0; i <= iterations && pagesInUse > 0 ; i++)	{		b++;		if ( b < dev->startBlock || b > dev->endBlock)		{			b =  dev->startBlock;		}		if(b < dev->startBlock || b > dev->endBlock) //????:有了上一步的判断,这里的判断应该不会成立		{			T(YAFFS_TRACE_ERROR,(TSTR("**>> Block %d is not valid" TENDSTR),b));			YBUG();		}				bi = yaffs_GetBlockInfo(dev,b);				if(bi->blockState == YAFFS_BLOCK_STATE_FULL &&		   (bi->pagesInUse - bi->softDeletions )< pagesInUse) //找出已经写满并且有用页面最少的块		{                                                     //####:这样的话每页必须用完才能写下一页			dirtiest = b;			pagesInUse = (bi->pagesInUse - bi->softDeletions);		}	}		dev->currentDirtyChecker = b;		return dirtiest;}//描述:把脏的块擦除使之变成YAFFS_BLOCK_STATE_EMPTY的块static void yaffs_BlockBecameDirty(yaffs_Device *dev,int blockNo){	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,blockNo);		int erasedOk = 0;		// If the block is still healthy erase it and mark as clean.	// If the block has had a data failure, then retire it.	bi->blockState = YAFFS_BLOCK_STATE_DIRTY;	//if(!bi->needsRetiring)		   //BY CEN  不产生坏块	{		erasedOk = yaffs_EraseBlockInNAND(dev,blockNo);		if(!erasedOk)		{			T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,(TSTR("**>> Erasure failed %d" TENDSTR),blockNo));		}	}		if( erasedOk )	{

⌨️ 快捷键说明

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