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

📄 yaffs_fs.c

📁 full package of jaffs file system
💻 C
📖 第 1 页 / 共 4 页
字号:
	return error;}static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode){	int retVal;	T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mkdir\n"));	retVal =  yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);#if 0 // attempt to fix dir bug - didn't work	if(!retVal)	{		dget(dentry);	}#endif	return retVal;}//#if defined(CONFIG_KERNEL_2_5)	/* Added NCB 185-8-2003 */#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *n)#elsestatic int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)#endif{	T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_create\n"));	return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);}static int yaffs_unlink(struct inode * dir, struct dentry *dentry){	int retVal;		yaffs_Device *dev;			T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_unlink %d:%s\n",(int)(dir->i_ino),dentry->d_name.name));		dev = yaffs_InodeToObject(dir)->myDev;		yaffs_GrossLock(dev);			retVal = yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name);			yaffs_GrossUnlock(dev);		if( retVal == YAFFS_OK)	{		dentry->d_inode->i_nlink--;		mark_inode_dirty(dentry->d_inode);		return 0;	}	else	{		return -ENOTEMPTY;	}}/* * Create a link... */static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry){	struct inode *inode = old_dentry->d_inode;	yaffs_Object *obj = NULL;	yaffs_Object *link=NULL;	yaffs_Device *dev;		T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_link\n"));		obj = yaffs_InodeToObject(inode);	dev = obj->myDev;		yaffs_GrossLock(dev);	if (!S_ISDIR(inode->i_mode))	// Don't link directories	{		link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj);	}		if(link)	{		old_dentry->d_inode->i_nlink =  yaffs_GetObjectLinkCount(obj);		d_instantiate(dentry, old_dentry->d_inode);		atomic_inc(&old_dentry->d_inode->i_count);		T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_link link count %d i_count %d\n",				old_dentry->d_inode->i_nlink,atomic_read(&old_dentry->d_inode->i_count)));		}		yaffs_GrossUnlock(dev);		if(link)	{			return 0;	}			return -EPERM; }static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname){	yaffs_Object *obj;	yaffs_Device *dev;		T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_symlink\n"));		dev = yaffs_InodeToObject(dir)->myDev;	yaffs_GrossLock(dev);	obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, 							 S_IFLNK | S_IRWXUGO, current->uid, current->gid,							 symname);	yaffs_GrossUnlock(dev);	if(obj)	{		struct inode* inode;			inode = yaffs_get_inode(dir->i_sb, obj->st_mode, 0, obj);		d_instantiate(dentry, inode);		T(YAFFS_TRACE_OS,(KERN_DEBUG"symlink created OK\n"));		return 0;	}	else	{		T(YAFFS_TRACE_OS,(KERN_DEBUG"symlink not created\n"));	}		return -ENOMEM;}static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync){	yaffs_Object *obj;	yaffs_Device *dev;		obj = yaffs_DentryToObject(dentry);	dev = obj->myDev;		T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_sync_object\n"));	yaffs_GrossLock(dev);	yaffs_FlushFile(obj,1);	yaffs_GrossUnlock(dev);	return 0;}/* * The VFS layer already does all the dentry stuff for rename. * * NB: POSIX says you can rename an object over an old object of the same name */static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry){	yaffs_Device *dev;	int retVal = YAFFS_FAIL;	int removed = 0;	yaffs_Object *target;		dev = yaffs_InodeToObject(old_dir)->myDev;	yaffs_GrossLock(dev);		// Check if the target is an existing directory that is not empty.	target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),new_dentry->d_name.name);		if(target &&	   target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&	   !list_empty(&target->variant.directoryVariant.children))	{		retVal = YAFFS_FAIL;	}	else	{	   		// Unlink the target if it exists		removed = yaffs_Unlink(yaffs_InodeToObject(new_dir),new_dentry->d_name.name);			retVal =  yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name,									yaffs_InodeToObject(new_dir),new_dentry->d_name.name);										}	yaffs_GrossUnlock(dev);		if(retVal == YAFFS_OK)	{		if(removed == YAFFS_OK)		{			new_dentry->d_inode->i_nlink--;			mark_inode_dirty(new_dentry->d_inode);		}				return 0;	}	else	{		return -ENOTEMPTY;	}	}static int yaffs_setattr(struct dentry *dentry, struct iattr *attr){	struct inode *inode = dentry->d_inode;	int error;	yaffs_Device *dev;		T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId));		if((error = inode_change_ok(inode,attr)) == 0)	{			dev = yaffs_InodeToObject(inode)->myDev;		yaffs_GrossLock(dev);		if(yaffs_SetAttributes(yaffs_InodeToObject(inode),attr) == YAFFS_OK)		{			error = 0;		}		else		{			error = -EPERM;		}		yaffs_GrossUnlock(dev);		inode_setattr(inode,attr);	}	return error;}//#if defined(CONFIG_KERNEL_2_5)	/* Added NCB 185-8-2003 */#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)#elsestatic int yaffs_statfs(struct super_block *sb, struct statfs *buf)#endif{	yaffs_Device *dev = yaffs_SuperToDevice(sb);	T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_statfs\n"));	yaffs_GrossLock(dev);		buf->f_type = YAFFS_MAGIC;	buf->f_bsize = sb->s_blocksize;	buf->f_namelen = 255;	buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * YAFFS_CHUNKS_PER_BLOCK/						(sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);	buf->f_files = 0;	buf->f_ffree = 0;	buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev)/						(sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);	buf->f_bavail =  buf->f_bfree;		yaffs_GrossUnlock(dev);	return 0;}static void yaffs_read_inode (struct inode *inode){	// NB This is called as a side effect of other functions and	// thus gross locking should always be in place already.		yaffs_Object *obj ; 	yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);		T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_read_inode for %d\n",(int)inode->i_ino));	obj  = yaffs_FindObjectByNumber(dev,inode->i_ino);		yaffs_FillInodeFromObject(inode,obj);}// Todo// Currently we only can report a single partition. Need to use lists herestatic yaffs_Device *yaffs_dev;static yaffs_Device *yaffsram_dev;static void yaffs_put_super(struct super_block *sb){	yaffs_Device *dev = yaffs_SuperToDevice(sb);		yaffs_GrossLock(dev);	if(dev->putSuperFunc)	{		 dev->putSuperFunc(sb);	}	yaffs_Deinitialise(dev);	yaffs_GrossUnlock(dev);	if(dev == yaffs_dev) yaffs_dev = NULL;	if(dev == yaffsram_dev) yaffsram_dev = NULL;			kfree(dev);}#ifdef CONFIG_YAFFS_MTD_ENABLEDstatic void  yaffs_MTDPutSuper(struct super_block *sb){		struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;		if(mtd->sync)	{		mtd->sync(mtd);	}		put_mtd_device(mtd);}#endifstatic struct super_block *yaffs_internal_read_super(int yaffsVersion,int useRam, struct super_block * sb, void * data, int silent){	int nBlocks;	struct inode * inode = NULL;	struct dentry * root;	yaffs_Device *dev;	int err;		sb->s_magic = YAFFS_MAGIC;	sb->s_op = &yaffs_super_ops;		if(!sb)		printk(KERN_INFO"yaffs: sb is NULL\n");	else if(!sb->s_dev)		printk(KERN_INFO"yaffs: sb->s_dev is NULL\n");	else if(! kdevname(sb->s_dev))		printk(KERN_INFO"yaffs: kdevname is NULL\n");	else		printk(KERN_INFO"yaffs: dev is %d name is \"%s\"\n", sb->s_dev, kdevname(sb->s_dev));	#ifdef CONFIG_YAFFS_USE_CHUNK_SIZE	sb->s_blocksize = YAFFS_BYTES_PER_CHUNK;	sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT;#else	sb->s_blocksize = PAGE_CACHE_SIZE;	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;#endif	T(YAFFS_TRACE_OS,("yaffs_read_super: Using yaffs%d\n",yaffsVersion));	T(YAFFS_TRACE_OS,("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",(int)(sb->s_blocksize)));#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY	T(YAFFS_TRACE_OS,("yaffs: Write verification disabled. All guarantees null and void\n"));#endif		if(useRam)	{#ifdef CONFIG_YAFFS_RAM_ENABLED		// Set the yaffs_Device up for ram emulation		sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL);		if(!dev)		{			// Deep shit could not allocate device structure			T(YAFFS_TRACE_OS,("yaffs_read_super: Failed trying to allocate yaffs_Device.\n"));			return NULL;		}		memset(dev,0,sizeof(yaffs_Device));		dev->genericDevice = NULL; // Not used for RAM emulation.		nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);		dev->startBlock = 1;  // Don't use block 0		dev->endBlock = nBlocks - 1;		dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;		dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;		dev->nReservedBlocks = 5;				if(yaffsVersion == 2)		{			dev->writeChunkWithTagsToNAND  = nandemul2k_WriteChunkWithTagsToNAND;			dev->readChunkWithTagsFromNAND = nandemul2k_ReadChunkWithTagsFromNAND;			dev->markNANDBlockBad          = nandemul2k_MarkNANDBlockBad;			dev->queryNANDBlock            = nandemul2k_QueryNANDBlock;			dev->eraseBlockInNAND          = nandemul2k_EraseBlockInNAND;			dev->initialiseNAND            = nandemul2k_InitialiseNAND;			dev->isYaffs2 = 1;			dev->nChunksPerBlock = nandemul2k_GetChunksPerBlock();			dev->nBytesPerChunk =  nandemul2k_GetBytesPerChunk();;			nBlocks = nandemul2k_GetNumberOfBlocks();			dev->startBlock = 1;  // Don't use block 0			dev->endBlock = nBlocks - 1;		}		else		{			dev->writeChunkToNAND = nandemul_WriteChunkToNAND;			dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;			dev->eraseBlockInNAND = nandemul_EraseBlockInNAND;			dev->initialiseNAND = nandemul_InitialiseNAND;			dev->isYaffs2 = 0;		}				yaffsram_dev = dev;		#endif	}	else	{	#ifdef CONFIG_YAFFS_MTD_ENABLED		struct mtd_info *mtd;				T(YAFFS_TRACE_ALWAYS,("yaffs: Attempting MTD mount on %u.%u, \"%s\"\n",		 MAJOR(sb->s_dev),MINOR(sb->s_dev),kdevname(sb->s_dev)));					// Check it's an mtd device.....		if(MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR)		{			return NULL; // This isn't an mtd device		} 				// Get the device		mtd = get_mtd_device(NULL, MINOR(sb->s_dev));		if (!mtd) 		{			T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev)));			return NULL;		}				// Check it's NAND		if(mtd->type != MTD_NANDFLASH)		{			T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device is not NAND it's type %d\n", mtd->type));			return NULL;		}		T(YAFFS_TRACE_OS,(" erase %x\n",mtd->erase));		T(YAFFS_TRACE_OS,(" read %x\n",mtd->read));		T(YAFFS_TRACE_OS,(" write %x\n",mtd->write));		T(YAFFS_TRACE_OS,(" readoob %x\n",mtd->read_oob));		T(YAFFS_TRACE_OS,(" writeoob %x\n",mtd->write_oob));		T(YAFFS_TRACE_OS,(" block_isbad %x\n",mtd->block_isbad));		T(YAFFS_TRACE_OS,(" block_markbad %x\n",mtd->block_markbad));		T(YAFFS_TRACE_OS,(" oobblock %d\n",mtd->oobblock));		T(YAFFS_TRACE_OS,(" oobsize %d\n",mtd->oobsize));		T(YAFFS_TRACE_OS,(" erasesize %d\n",mtd->erasesize));		T(YAFFS_TRACE_OS,(" size %d\n",mtd->size));		if(yaffsVersion == 2)		{			// Check for version 2 style functions			if(!mtd->erase ||			   !mtd->block_isbad ||			   !mtd->block_markbad ||			   !mtd->read  ||			   !mtd->write ||#ifndef CONFIG_YAFFS_USE_OLD_MTD			   !mtd->write_ecc ||			   !mtd->read_ecc ||#endif			   !mtd->read_oob ||			   !mtd->write_oob )			{

⌨️ 快捷键说明

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