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

📄 yaffs_fs.c

📁 linux 镜像文件制作 用于压制yaffs2类型的文件镜像啊啊啊啊啊啊
💻 C
📖 第 1 页 / 共 5 页
字号:
	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, ("yaffs_statfs\n"));	yaffs_GrossLock(dev);	buf->f_type = YAFFS_MAGIC;	buf->f_bsize = sb->s_blocksize;	buf->f_namelen = 255;	if (dev->nDataBytesPerChunk & (dev->nDataBytesPerChunk - 1)) {		/* Do this if chunk size is not a power of 2 */		uint64_t bytesInDev;		uint64_t bytesFree;		bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock + 1))) *			((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk));		do_div(bytesInDev, sb->s_blocksize); /* bytesInDev becomes the number of blocks */		buf->f_blocks = bytesInDev;		bytesFree  = ((uint64_t)(yaffs_GetNumberOfFreeChunks(dev))) *			((uint64_t)(dev->nDataBytesPerChunk));		do_div(bytesFree, sb->s_blocksize);		buf->f_bfree = bytesFree;	} else 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, ("yaffs_do_sync_fs\n"));	if (sb->s_dirt) {		yaffs_GrossLock(dev);		if (dev) {			yaffs_FlushEntireDeviceCache(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, ("yaffs_write_super\n"));	if (yaffs_auto_checkpoint >= 2)		yaffs_do_sync_fs(sb);#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))	return 0;#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, ("yaffs_sync_fs\n"));	if (yaffs_auto_checkpoint >= 1)		yaffs_do_sync_fs(sb);	return 0;}#ifdef YAFFS_USE_OWN_IGETstatic struct inode *yaffs_iget(struct super_block *sb, unsigned long ino){	struct inode *inode;	yaffs_Object *obj;	yaffs_Device *dev = yaffs_SuperToDevice(sb);	T(YAFFS_TRACE_OS,		("yaffs_iget for %lu\n", ino));	inode = iget_locked(sb, ino);	if (!inode)		return ERR_PTR(-ENOMEM);	if (!(inode->i_state & I_NEW))		return 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_GrossLock(dev);	obj = yaffs_FindObjectByNumber(dev, inode->i_ino);	yaffs_FillInodeFromObject(inode, obj);	yaffs_GrossUnlock(dev);	unlock_new_inode(inode);	return inode;}#elsestatic 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,		("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);}#endifstatic YLIST_HEAD(yaffs_dev_list);#if 0 /* not used */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,			("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,			("yaffs_remount_fs: %s: RW\n", dev->name));	}	return 0;}#endifstatic void yaffs_put_super(struct super_block *sb){	yaffs_Device *dev = yaffs_SuperToDevice(sb);	T(YAFFS_TRACE_OS, ("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 */	ylist_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, ("yaffs_MarkSuperBlockDirty() sb = %p\n", sb));	if (sb)		sb->s_dirt = 1;}typedef struct {	int inband_tags;	int skip_checkpoint_read;	int skip_checkpoint_write;	int no_cache;} yaffs_options;#define MAX_OPT_LEN 20static int yaffs_parse_options(yaffs_options *options, const char *options_str){	char cur_opt[MAX_OPT_LEN + 1];	int p;	int error = 0;	/* Parse through the options which is a comma seperated list */	while (options_str && *options_str && !error) {		memset(cur_opt, 0, MAX_OPT_LEN + 1);		p = 0;		while (*options_str && *options_str != ',') {			if (p < MAX_OPT_LEN) {				cur_opt[p] = *options_str;				p++;			}			options_str++;		}		if (!strcmp(cur_opt, "inband-tags"))			options->inband_tags = 1;		else if (!strcmp(cur_opt, "no-cache"))			options->no_cache = 1;		else if (!strcmp(cur_opt, "no-checkpoint-read"))			options->skip_checkpoint_read = 1;		else if (!strcmp(cur_opt, "no-checkpoint-write"))			options->skip_checkpoint_write = 1;		else if (!strcmp(cur_opt, "no-checkpoint")) {			options->skip_checkpoint_read = 1;			options->skip_checkpoint_write = 1;		} else {			printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",					cur_opt);			error = 1;		}	}	return error;}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;	char *data_str = (char *)data;	yaffs_options options;	sb->s_magic = YAFFS_MAGIC;	sb->s_op = &yaffs_super_ops;	sb->s_flags |= MS_NOATIME;	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));	if (!data_str)		data_str = "";	printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);	memset(&options, 0, sizeof(options));	if (yaffs_parse_options(&options, data_str)) {		/* Option parsing failed */		return NULL;	}	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));	T(YAFFS_TRACE_OS, (" %s %d\n", WRITE_SIZE_STR, WRITE_SIZE(mtd)));	T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize));	T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize));#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)	T(YAFFS_TRACE_OS, (" size %u\n", mtd->size));#else	T(YAFFS_TRACE_OS, (" size %lld\n", mtd->size));#endif#ifdef CONFIG_YAFFS_AUTO_YAFFS2	if (yaffsVersion == 1 && WRITE_SIZE(mtd) >= 2048) {		T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs2\n"));		yaffsVersion = 2;	}	/* Added NCB 26/5/2006 for completeness */	if (yaffsVersion == 2 && !options.inband_tags && WRITE_SIZE(mtd) == 512) {		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) {#endif			T(YAFFS_TRACE_ALWAYS,			  ("yaffs: MTD device does not support required "			   "functions\n"));;			return NULL;		}		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||		    mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&		    !options.inband_tags) {			T(YAFFS_TRACE_ALWAYS,			  ("yaffs: MTD device does not have the "			   "right page sizes\n"));			return NULL;		}	} else {		/* Check for V1 style functions */		if (!mtd->erase ||		    !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) {#endif			T(YAFFS_TRACE_ALWAYS,			  ("yaffs: MTD device does not support required "			   "functions\n"));;			return NULL;		}		if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK ||		    mtd->oobsize != YAFFS_BYTES_PER_SPARE) {			T(YAFFS_TRACE_ALWAYS,			  ("yaffs: MTD device does not support have the "			   "right page sizes\n"));			return NULL;		}	}	/* OK, so if we got here, we have an MTD that's NAND and looks	 * like it has the right capabilities	 * Set the yaffs_Device up for mtd	 */#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))	sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);#else	sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);#endif	if (!dev) {		/* Deep shit could not allocate device structure */		T(YAFFS_TRACE_ALWAYS,		  ("yaffs_read_super: Failed trying to allocate "		   "yaffs_Device. \n"));		return NULL;	}	memset(dev, 0, sizeof(yaffs_Device));	dev->genericDevice = mtd;	dev->name = mtd->name;	/* Set up the memory size parameters.... */	nBlocks = YCALCBLOCKS(mtd->size, (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));	dev->startBlock = 0;	dev->endBlock = nBlocks - 1;	dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;	dev->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK;	dev->nReservedBlocks = 5;	dev->nShortOpCaches = (options.no_cache) ? 0 : 10;

⌨️ 快捷键说明

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