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

📄 yaffs_fs.c

📁 yaffs2 lastest sourcecode~~
💻 C
📖 第 1 页 / 共 5 页
字号:
	dev->inbandTags = options.inband_tags;	/* ... and the functions. */	if (yaffsVersion == 2) {		dev->writeChunkWithTagsToNAND =		    nandmtd2_WriteChunkWithTagsToNAND;		dev->readChunkWithTagsFromNAND =		    nandmtd2_ReadChunkWithTagsFromNAND;		dev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;		dev->queryNANDBlock = nandmtd2_QueryNANDBlock;		dev->spareBuffer = YMALLOC(mtd->oobsize);		dev->isYaffs2 = 1;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))		dev->totalBytesPerChunk = mtd->writesize;		dev->nChunksPerBlock = mtd->erasesize / mtd->writesize;#else		dev->totalBytesPerChunk = mtd->oobblock;		dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;#endif		nBlocks = YCALCBLOCKS(mtd->size, mtd->erasesize);		dev->startBlock = 0;		dev->endBlock = nBlocks - 1;	} else {#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))		/* use the MTD interface in yaffs_mtdif1.c */		dev->writeChunkWithTagsToNAND =			nandmtd1_WriteChunkWithTagsToNAND;		dev->readChunkWithTagsFromNAND =			nandmtd1_ReadChunkWithTagsFromNAND;		dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad;		dev->queryNANDBlock = nandmtd1_QueryNANDBlock;#else		dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;		dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;#endif		dev->isYaffs2 = 0;	}	/* ... and common functions */	dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;	dev->initialiseNAND = nandmtd_InitialiseNAND;	dev->putSuperFunc = yaffs_MTDPutSuper;	dev->superBlock = (void *)sb;	dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;#ifndef CONFIG_YAFFS_DOES_ECC	dev->useNANDECC = 1;#endif#ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES	dev->wideTnodesDisabled = 1;#endif	dev->skipCheckpointRead = options.skip_checkpoint_read;	dev->skipCheckpointWrite = options.skip_checkpoint_write;	/* we assume this is protected by lock_kernel() in mount/umount */	ylist_add_tail(&dev->devList, &yaffs_dev_list);	init_MUTEX(&dev->grossLock);	yaffs_GrossLock(dev);	err = yaffs_GutsInitialise(dev);	T(YAFFS_TRACE_OS,	  ("yaffs_read_super: guts initialised %s\n",	   (err == YAFFS_OK) ? "OK" : "FAILED"));	/* Release lock before yaffs_get_inode() */	yaffs_GrossUnlock(dev);	/* Create root inode */	if (err == YAFFS_OK)		inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,					yaffs_Root(dev));	if (!inode)		return NULL;	inode->i_op = &yaffs_dir_inode_operations;	inode->i_fop = &yaffs_dir_operations;	T(YAFFS_TRACE_OS, ("yaffs_read_super: got root inode\n"));	root = d_alloc_root(inode);	T(YAFFS_TRACE_OS, ("yaffs_read_super: d_alloc_root done\n"));	if (!root) {		iput(inode);		return NULL;	}	sb->s_root = root;	sb->s_dirt = !dev->isCheckpointed;	T(YAFFS_TRACE_ALWAYS,	  ("yaffs_read_super: isCheckpointed %d\n", dev->isCheckpointed));	T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n"));	return sb;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,					 int silent){	return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))static int yaffs_read_super(struct file_system_type *fs,			    int flags, const char *dev_name,			    void *data, struct vfsmount *mnt){	return get_sb_bdev(fs, flags, dev_name, data,			   yaffs_internal_read_super_mtd, mnt);}#elsestatic struct super_block *yaffs_read_super(struct file_system_type *fs,					    int flags, const char *dev_name,					    void *data){	return get_sb_bdev(fs, flags, dev_name, data,			   yaffs_internal_read_super_mtd);}#endifstatic struct file_system_type yaffs_fs_type = {	.owner = THIS_MODULE,	.name = "yaffs",	.get_sb = yaffs_read_super,	.kill_sb = kill_block_super,	.fs_flags = FS_REQUIRES_DEV,};#elsestatic struct super_block *yaffs_read_super(struct super_block *sb, void *data,					    int silent){	return yaffs_internal_read_super(1, sb, data, silent);}static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,		      FS_REQUIRES_DEV);#endif#ifdef CONFIG_YAFFS_YAFFS2#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,					  int silent){	return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))static int yaffs2_read_super(struct file_system_type *fs,			int flags, const char *dev_name, void *data,			struct vfsmount *mnt){	return get_sb_bdev(fs, flags, dev_name, data,			yaffs2_internal_read_super_mtd, mnt);}#elsestatic struct super_block *yaffs2_read_super(struct file_system_type *fs,					     int flags, const char *dev_name,					     void *data){	return get_sb_bdev(fs, flags, dev_name, data,			   yaffs2_internal_read_super_mtd);}#endifstatic struct file_system_type yaffs2_fs_type = {	.owner = THIS_MODULE,	.name = "yaffs2",	.get_sb = yaffs2_read_super,	.kill_sb = kill_block_super,	.fs_flags = FS_REQUIRES_DEV,};#elsestatic struct super_block *yaffs2_read_super(struct super_block *sb,					     void *data, int silent){	return yaffs_internal_read_super(2, sb, data, silent);}static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,		      FS_REQUIRES_DEV);#endif#endif				/* CONFIG_YAFFS_YAFFS2 */static struct proc_dir_entry *my_proc_entry;static char *yaffs_dump_dev(char *buf, yaffs_Device * dev){	buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock);	buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock);	buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->totalBytesPerChunk);	buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk);	buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits);	buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);	buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks);	buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks);	buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);	buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated);	buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes);	buf += sprintf(buf, "nObjectsCreated.... %d\n", dev->nObjectsCreated);	buf += sprintf(buf, "nFreeObjects....... %d\n", dev->nFreeObjects);	buf += sprintf(buf, "nFreeChunks........ %d\n", dev->nFreeChunks);	buf += sprintf(buf, "nPageWrites........ %d\n", dev->nPageWrites);	buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads);	buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures);	buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies);	buf += sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);	buf += sprintf(buf, "passiveGCs......... %d\n",		    dev->passiveGarbageCollections);	buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites);	buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches);	buf += sprintf(buf, "nRetireBlocks...... %d\n", dev->nRetiredBlocks);	buf += sprintf(buf, "eccFixed........... %d\n", dev->eccFixed);	buf += sprintf(buf, "eccUnfixed......... %d\n", dev->eccUnfixed);	buf += sprintf(buf, "tagsEccFixed....... %d\n", dev->tagsEccFixed);	buf += sprintf(buf, "tagsEccUnfixed..... %d\n", dev->tagsEccUnfixed);	buf += sprintf(buf, "cacheHits.......... %d\n", dev->cacheHits);	buf += sprintf(buf, "nDeletedFiles...... %d\n", dev->nDeletedFiles);	buf += sprintf(buf, "nUnlinkedFiles..... %d\n", dev->nUnlinkedFiles);	buf +=	    sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions);	buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);	buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);	buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);	return buf;}static int yaffs_proc_read(char *page,			   char **start,			   off_t offset, int count, int *eof, void *data){	struct ylist_head *item;	char *buf = page;	int step = offset;	int n = 0;	/* Get proc_file_read() to step 'offset' by one on each sucessive call.	 * We use 'offset' (*ppos) to indicate where we are in devList.	 * This also assumes the user has posted a read buffer large	 * enough to hold the complete output; but that's life in /proc.	 */	*(int *)start = 1;	/* Print header first */	if (step == 0) {		buf += sprintf(buf, "YAFFS built:" __DATE__ " " __TIME__			       "\n%s\n%s\n", yaffs_fs_c_version,			       yaffs_guts_c_version);	}	/* hold lock_kernel while traversing yaffs_dev_list */	lock_kernel();	/* Locate and print the Nth entry.  Order N-squared but N is small. */	ylist_for_each(item, &yaffs_dev_list) {		yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList);		if (n < step) {			n++;			continue;		}		buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->name);		buf = yaffs_dump_dev(buf, dev);		break;	}	unlock_kernel();	return buf - page < count ? buf - page : count;}/** * Set the verbosity of the warnings and error messages. * * Note that the names can only be a..z or _ with the current code. */static struct {	char *mask_name;	unsigned mask_bitfield;} mask_flags[] = {	{"allocate", YAFFS_TRACE_ALLOCATE},	{"always", YAFFS_TRACE_ALWAYS},	{"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},	{"buffers", YAFFS_TRACE_BUFFERS},	{"bug", YAFFS_TRACE_BUG},	{"checkpt", YAFFS_TRACE_CHECKPOINT},	{"deletion", YAFFS_TRACE_DELETION},	{"erase", YAFFS_TRACE_ERASE},	{"error", YAFFS_TRACE_ERROR},	{"gc_detail", YAFFS_TRACE_GC_DETAIL},	{"gc", YAFFS_TRACE_GC},	{"mtd", YAFFS_TRACE_MTD},	{"nandaccess", YAFFS_TRACE_NANDACCESS},	{"os", YAFFS_TRACE_OS},	{"scan_debug", YAFFS_TRACE_SCAN_DEBUG},	{"scan", YAFFS_TRACE_SCAN},	{"tracing", YAFFS_TRACE_TRACING},	{"verify", YAFFS_TRACE_VERIFY},	{"verify_nand", YAFFS_TRACE_VERIFY_NAND},	{"verify_full", YAFFS_TRACE_VERIFY_FULL},	{"verify_all", YAFFS_TRACE_VERIFY_ALL},	{"write", YAFFS_TRACE_WRITE},	{"all", 0xffffffff},	{"none", 0},	{NULL, 0},};#define MAX_MASK_NAME_LENGTH 40static int yaffs_proc_write(struct file *file, const char *buf,					 unsigned long count, void *data){	unsigned rg = 0, mask_bitfield;	char *end;	char *mask_name;	const char *x;	char substring[MAX_MASK_NAME_LENGTH + 1];	int i;	int done = 0;	int add, len = 0;	int pos = 0;	rg = yaffs_traceMask;	while (!done && (pos < count)) {		done = 1;		while ((pos < count) && isspace(buf[pos]))			pos++;		switch (buf[pos]) {		case '+':		case '-':		case '=':			add = buf[pos];			pos++;			break;		default:			add = ' ';			break;		}		mask_name = NULL;		mask_bitfield = simple_strtoul(buf + pos, &end, 0);		if (end > buf + pos) {			mask_name = "numeral";			len = end - (buf + pos);			pos += len;			done = 0;		} else {			for (x = buf + pos, i = 0;			    (*x == '_' || (*x >= 'a' && *x <= 'z')) &&			    i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)				substring[i] = *x;			substring[i] = '\0';			for (i = 0; mask_flags[i].mask_name != NULL; i++) {				if (strcmp(substring, mask_flags[i].mask_name) == 0) {					mask_name = mask_flags[i].mask_name;					mask_bitfield = mask_flags[i].mask_bitfield;					done = 0;					break;				}			}		}		if (mask_name != NULL) {			done = 0;			switch (add) {			case '-':				rg &= ~mask_bitfield;				break;			case '+':				rg |= mask_bitfield;				break;			case '=':				rg = mask_bitfield;				break;			default:				rg |= mask_bitfield;				break;			}		}	}	yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;	printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_traceMask);	if (rg & YAFFS_TRACE_ALWAYS) {		for (i = 0; mask_flags[i].mask_name != NULL; i++) {			char flag;			flag = ((rg & mask_flags[i].mask_bitfield) == mask_flags[i].mask_bitfield) ? '+' : '-';			printk(KERN_DEBUG "%c%s\n", flag, mask_flags[i].mask_name);		}	}	return count;}/* Stuff to handle installation of file systems */struct file_system_to_install {	struct file_system_type *fst;	int installed;};static struct file_system_to_install fs_to_install[] = {	{&yaffs_fs_type, 0},	{&yaffs2_fs_type, 0},	{NULL, 0}};static int __init init_yaffs_fs(void){	int error = 0;	struct file_system_to_install *fsinst;	T(YAFFS_TRACE_ALWAYS,	  ("yaffs " __DATE__ " " __TIME__ " Installing. \n"));	/* Install the proc_fs entry */	my_proc_entry = create_proc_entry("yaffs",					       S_IRUGO | S_IFREG,					       YPROC_ROOT);	if (my_proc_entry) {		my_proc_entry->write_proc = yaffs_proc_write;		my_proc_entry->read_proc = yaffs_proc_read;		my_proc_entry->data = NULL;	} else		return -ENOMEM;	/* Now add the file system entries */	fsinst = fs_to_install;	while (fsinst->fst && !error) {		error = register_filesystem(fsinst->fst);		if (!error)			fsinst->installed = 1;		fsinst++;	}	/* Any errors? uninstall  */	if (error) {		fsinst = fs_to_install;		while (fsinst->fst) {			if (fsinst->installed) {				unregister_filesystem(fsinst->fst);				fsinst->installed = 0;			}			fsinst++;		}	}	return error;}static void __exit exit_yaffs_fs(void){	struct file_system_to_install *fsinst;	T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__			       " removing. \n"));	remove_proc_entry("yaffs", YPROC_ROOT);	fsinst = fs_to_install;	while (fsinst->fst) {		if (fsinst->installed) {			unregister_filesystem(fsinst->fst);			fsinst->installed = 0;		}		fsinst++;	}}module_init(init_yaffs_fs)module_exit(exit_yaffs_fs)MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2006");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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