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

📄 yaffs_fs.c

📁 yaffs2设备驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 (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);	if (retVal == YAFFS_OK) {		dentry->d_inode->i_nlink--;		dir->i_version++;		yaffs_GrossUnlock(dev);		mark_inode_dirty(dentry->d_inode);		return 0;	}	yaffs_GrossUnlock(dev);	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;	uid_t uid = current->fsuid;	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;	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, uid, gid, symname);	yaffs_GrossUnlock(dev);	if (obj) {		struct inode *inode;		inode = yaffs_get_inode(dir->i_sb, obj->yst_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;	yaffs_Object *target;        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_rename\n"));	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)) {	    	        T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));		retVal = YAFFS_FAIL;	} else {		/* Now does unlinking internally using shadowing mechanism */	        T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n"));				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(target) {			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);		if (!error)			error = inode_setattr(inode, attr);	}	return error;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf){	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;	struct super_block *sb = dentry->d_sb;#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf){	yaffs_Device *dev = yaffs_SuperToDevice(sb);#elsestatic int yaffs_statfs(struct super_block *sb, struct statfs *buf){	yaffs_Device *dev = yaffs_SuperToDevice(sb);#endif	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;	if (sb->s_blocksize > dev->nDataBytesPerChunk) {		buf->f_blocks =		    (dev->endBlock - dev->startBlock +		     1) * dev->nChunksPerBlock / (sb->s_blocksize /						  dev->nDataBytesPerChunk);		buf->f_bfree =		    yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize /							dev->nDataBytesPerChunk);	} else {		buf->f_blocks =		    (dev->endBlock - dev->startBlock +		     1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk /						  sb->s_blocksize);		buf->f_bfree =		    yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk /							sb->s_blocksize);	}	buf->f_files = 0;	buf->f_ffree = 0;	buf->f_bavail = buf->f_bfree;	yaffs_GrossUnlock(dev);	return 0;}/**static int yaffs_do_sync_fs(struct super_block *sb){	yaffs_Device *dev = yaffs_SuperToDevice(sb);	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_do_sync_fs\n"));	if(sb->s_dirt) {		yaffs_GrossLock(dev);		if(dev)			yaffs_CheckpointSave(dev);				yaffs_GrossUnlock(dev);		sb->s_dirt = 0;	}	return 0;}**/#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))static void yaffs_write_super(struct super_block *sb)#elsestatic int yaffs_write_super(struct super_block *sb)#endif{	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n"));#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))	return 0; /* yaffs_do_sync_fs(sb);*/#endif}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))static int yaffs_sync_fs(struct super_block *sb, int wait)#elsestatic int yaffs_sync_fs(struct super_block *sb)#endif{	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n"));		return 0; /* yaffs_do_sync_fs(sb);*/	}static void yaffs_read_inode(struct inode *inode){	/* NB This is called as a side effect of other functions, but	 * we had to release the lock to prevent deadlocks, so 	 * need to lock again.	 */	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));	yaffs_GrossLock(dev);		obj = yaffs_FindObjectByNumber(dev, inode->i_ino);	yaffs_FillInodeFromObject(inode, obj);	yaffs_GrossUnlock(dev);}static LIST_HEAD(yaffs_dev_list);static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data){	yaffs_Device    *dev = yaffs_SuperToDevice(sb);	if( *flags & MS_RDONLY ) {		struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;	    		T(YAFFS_TRACE_OS,			(KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name ));		yaffs_GrossLock(dev);     	 		yaffs_FlushEntireDeviceCache(dev);    			yaffs_CheckpointSave(dev); 		if (mtd->sync)			mtd->sync(mtd);		yaffs_GrossUnlock(dev);	}	else {		T(YAFFS_TRACE_OS, 			(KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name ));	} 	return 0;}static void yaffs_put_super(struct super_block *sb){	yaffs_Device *dev = yaffs_SuperToDevice(sb);	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n"));	yaffs_GrossLock(dev);		yaffs_FlushEntireDeviceCache(dev);	yaffs_CheckpointSave(dev);	if (dev->putSuperFunc) {		dev->putSuperFunc(sb);	}	yaffs_Deinitialise(dev);		yaffs_GrossUnlock(dev);	/* we assume this is protected by lock_kernel() in mount/umount */	list_del(&dev->devList);		if(dev->spareBuffer){		YFREE(dev->spareBuffer);		dev->spareBuffer = NULL;	}	kfree(dev);}static 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);}static void yaffs_MarkSuperBlockDirty(void *vsb){	struct super_block *sb = (struct super_block *)vsb;		T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb));//	if(sb)//		sb->s_dirt = 1;}static struct super_block *yaffs_internal_read_super(int yaffsVersion,						     struct super_block *sb,						     void *data, int silent){	int nBlocks;	struct inode *inode = NULL;	struct dentry *root;	yaffs_Device *dev = 0;	char devname_buf[BDEVNAME_SIZE + 1];	struct mtd_info *mtd;	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 (!yaffs_devname(sb, devname_buf))		printk(KERN_INFO "yaffs: devname is NULL\n");	else		printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n",		       sb->s_dev,		       yaffs_devname(sb, devname_buf));	sb->s_blocksize = PAGE_CACHE_SIZE;	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;	T(YAFFS_TRACE_OS, ("yaffs_read_super: Using yaffs%d\n", yaffsVersion));	T(YAFFS_TRACE_OS,	  ("yaffs_read_super: block size %d\n", (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	T(YAFFS_TRACE_ALWAYS, ("yaffs: Attempting MTD mount on %u.%u, "			       "\"%s\"\n",			       MAJOR(sb->s_dev), MINOR(sb->s_dev),			       yaffs_devname(sb, devname_buf)));	/* 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 %p\n", mtd->erase));	T(YAFFS_TRACE_OS, (" read %p\n", mtd->read));	T(YAFFS_TRACE_OS, (" write %p\n", mtd->write));	T(YAFFS_TRACE_OS, (" readoob %p\n", mtd->read_oob));	T(YAFFS_TRACE_OS, (" writeoob %p\n", mtd->write_oob));	T(YAFFS_TRACE_OS, (" block_isbad %p\n", mtd->block_isbad));	T(YAFFS_TRACE_OS, (" block_markbad %p\n", mtd->block_markbad));#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))	T(YAFFS_TRACE_OS, (" writesize %d\n", mtd->writesize));#else	T(YAFFS_TRACE_OS, (" oobblock %d\n", mtd->oobblock));#endif	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));	#ifdef CONFIG_YAFFS_AUTO_YAFFS2	if (yaffsVersion == 1 && #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))	    mtd->writesize >= 2048) {#else	    mtd->oobblock >= 2048) {#endif	    T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n"));	    yaffsVersion = 2;	}			/* Added NCB 26/5/2006 for completeness */	if (yaffsVersion == 2 && #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))	    mtd->writesize == 512) {#else	    mtd->oobblock == 512) {#endif	    T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n"));	    yaffsVersion = 1;	}	#endif	if (yaffsVersion == 2) {		/* Check for version 2 style functions */		if (!mtd->erase ||		    !mtd->block_isbad ||		    !mtd->block_markbad ||		    !mtd->read ||		    !mtd->write ||#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))		    !mtd->read_oob || !mtd->write_oob) {#else		    !mtd->write_ecc ||		    !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {

⌨️ 快捷键说明

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