📄 yaffs_fs.c
字号:
T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device does not support required functions\n"));; return NULL; } if(mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE || mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) { T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device does not support have the right page sizes\n")); return NULL; } } else { // Check for V1 style functions if(!mtd->erase || !mtd->read || !mtd->write ||#ifndef CONFIG_YAFFS_USE_OLD_MTD !mtd->write_ecc || !mtd->read_ecc ||#endif !mtd->read_oob || !mtd->write_oob ) { T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device does not support required functions\n"));; return NULL; } if(mtd->oobblock != 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 defined(CONFIG_KERNEL_2_5)#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; // Set up the memory size parameters.... nBlocks = mtd->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; dev->nShortOpCaches = 10; // Enable short op caching // ... 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; dev->nBytesPerChunk = mtd->oobblock; dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock; nBlocks = mtd->size / mtd->erasesize; dev->startBlock = 1; // Don't use block 0 dev->endBlock = nBlocks - 1; } else { dev->writeChunkToNAND = nandmtd_WriteChunkToNAND; dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; dev->isYaffs2 = 0; } // ... and common functions dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND; dev->initialiseNAND = nandmtd_InitialiseNAND; dev->putSuperFunc = yaffs_MTDPutSuper; #ifdef CONFIG_YAFFS_USE_NANDECC dev->useNANDECC = 1;#endif yaffs_dev = dev; #endif } 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")); // Create root inode if(err == YAFFS_OK) inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,yaffs_Root(dev)); yaffs_GrossUnlock(dev); if (!inode) return NULL; // added NCB 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; T(YAFFS_TRACE_OS,("yaffs_read_super: done\n")); return sb;}static int yaffs_internal_read_super_ram(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(1,1,sb,data,silent) ? 0 : -1;}static int yaffs_internal_read_super_mtd(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(1,0,sb,data,silent) ? 0 : -1;}static int yaffs2_internal_read_super_ram(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(2,1,sb,data,silent) ? 0 : -1;}static int yaffs2_internal_read_super_mtd(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(2,0,sb,data,silent) ? 0 : -1;}#ifdef CONFIG_YAFFS_MTD_ENABLED//#if defined(CONFIG_KERNEL_2_5)#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static 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);}/* changes NCB 2.5.70 *///static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV);static struct file_system_type yaffs_fs_type = { .owner = THIS_MODULE, .name = "yaffs", .get_sb = yaffs_read_super,// .kill_sb = kill_block_super, .kill_sb = kill_litter_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,0,sb,data,silent);}static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV);#endif#endif // CONFIG_YAFFS_MTD_ENABLED#ifdef CONFIG_YAFFS2_MTD_ENABLED#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static 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);}/* changes NCB 2.5.70 *///static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV);static struct file_system_type yaffs2_fs_type = { .owner = THIS_MODULE, .name = "yaffs2", .get_sb = yaffs2_read_super,// .kill_sb = kill_block_super, .kill_sb = kill_litter_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,0,sb,data,silent);}static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, FS_REQUIRES_DEV);#endif#endif // CONFIG_YAFFS2_MTD_ENABLED#ifdef CONFIG_YAFFS_RAM_ENABLED#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static struct super_block *yaffs_ram_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_ram);}static struct file_system_type yaffs_ram_fs_type = { .owner = THIS_MODULE, .name = "yaffsram", .get_sb = yaffs_ram_read_super,// .kill_sb = kill_block_super, .kill_sb = kill_litter_super, .fs_flags = FS_SINGLE,};#elsestatic struct super_block *yaffs_ram_read_super(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(1,1,sb,data,silent);}static DECLARE_FSTYPE(yaffs_ram_fs_type, "yaffsram", yaffs_ram_read_super, FS_SINGLE);#endif#endif // CONFIG_YAFFS_RAM_ENABLED#ifdef CONFIG_YAFFS2_RAM_ENABLED#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static struct super_block *yaffs2_ram_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_ram);}static struct file_system_type yaffs2_ram_fs_type = { .owner = THIS_MODULE, .name = "yaffs2ram", .get_sb = yaffs2_ram_read_super,// .kill_sb = kill_block_super, .kill_sb = kill_litter_super, .fs_flags = FS_SINGLE,};#elsestatic struct super_block *yaffs2_ram_read_super(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(2,1,sb,data,silent);}static DECLARE_FSTYPE(yaffs2_ram_fs_type, "yaffs2ram", yaffs2_ram_read_super, FS_SINGLE);#endif#endif // CONFIG_YAFFS2_RAM_ENABLEDstatic struct proc_dir_entry *my_proc_entry;static struct proc_dir_entry *my_proc_ram_write_entry;static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name){ buf +=sprintf(buf,"\nDevice %s\n",name); buf +=sprintf(buf,"startBlock......... %d\n",dev->startBlock); buf +=sprintf(buf,"endBlock........... %d\n",dev->endBlock); 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,"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,"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); return buf; }static int yaffs_proc_read( char *page, char **start, off_t offset, int count, int *eof, void *data ){ char my_buffer[3000]; char *buf; buf = my_buffer; if (offset > 0) return 0; /* Fill the buffer and get its length */ buf +=sprintf(buf,"YAFFS built:"__DATE__ " "__TIME__"\n%s\n%s\n", yaffs_fs_c_version,yaffs_guts_c_version); if(yaffs_dev) buf = yaffs_dump_dev(buf,yaffs_dev,"yaffs"); if(yaffsram_dev) buf = yaffs_dump_dev(buf,yaffsram_dev,"yaffsram"); strcpy(page,my_buffer); return strlen(my_buffer);}static int yaffs_proc_ram_write( char *page, char **start, off_t offset, int count, int *eof, void *data ){ printk(KERN_DEBUG "yaffs write size %d\n",count); return count;}// Stuff to handle installation of file systemsstruct file_system_to_install{ struct file_system_type *fst; int installed;};static struct file_system_to_install fs_to_install[] ={#ifdef CONFIG_YAFFS_RAM_ENABLED { &yaffs_ram_fs_type, 0},#endif#ifdef CONFIG_YAFFS2_RAM_ENABLED { &yaffs2_ram_fs_type,0},#endif#ifdef CONFIG_YAFFS_MTD_ENABLED { &yaffs_fs_type,0},#endif#ifdef CONFIG_YAFFS2_MTD_ENABLED { &yaffs2_fs_type,0},#endif { NULL,0}};static int __init init_yaffs_fs(void){ int error = 0; struct file_system_to_install *fsinst; yaffs_dev = yaffsram_dev = NULL; T(YAFFS_TRACE_ALWAYS,("yaffs " __DATE__ " " __TIME__ " Installing. \n")); /* Install the proc_fs entry */ my_proc_entry = create_proc_read_entry("yaffs", S_IRUGO | S_IFREG, &proc_root, yaffs_proc_read, NULL); if(!my_proc_entry) { 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",&proc_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,2003,2004");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -