📄 yaffs_fs.c
字号:
}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;}static int yaffs_statfs(struct super_block *sb, struct statfs *buf){ 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);}static 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 useRam, struct super_block * sb, void * data, int silent){ int nBlocks; struct inode * inode; struct dentry * root; yaffs_Device *dev; 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: %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 printk(KERN_DEBUG"yaffs_read_super: Failed trying to allocate yaffs_Device. Terminating debug.\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; dev->writeChunkToNAND = nandemul_WriteChunkToNAND; dev->readChunkFromNAND = nandemul_ReadChunkFromNAND; dev->eraseBlockInNAND = nandemul_EraseBlockInNAND; dev->initialiseNAND = nandemul_InitialiseNAND; yaffsram_dev = dev; #endif } else { #ifdef CONFIG_YAFFS_MTD_ENABLED struct mtd_info *mtd; printk(KERN_DEBUG "yaffs: Attempting MTD mount on %u.%u, \"%s\"\n", MAJOR(sb->s_dev),MINOR(sb->s_dev),kdevname(sb->s_dev)); // Hope it's a NAND mtd mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); if (!mtd) { printk(KERN_DEBUG "yaffs: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev)); return NULL; } if(mtd->type != MTD_NANDFLASH) { printk(KERN_DEBUG "yaffs: MTD device is not NAND it's type %d\n", mtd->type); return NULL; } //printk(KERN_DEBUG" erase %x\n",mtd->erase); //printk(KERN_DEBUG" read %x\n",mtd->read); //printk(KERN_DEBUG" write %x\n",mtd->write); //printk(KERN_DEBUG" readoob %x\n",mtd->read_oob); //printk(KERN_DEBUG" writeoob %x\n",mtd->write_oob); //printk(KERN_DEBUG" oobblock %x\n",mtd->oobblock); //printk(KERN_DEBUG" oobsize %x\n",mtd->oobsize); 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 ) { printk(KERN_DEBUG "yaffs: MTD device does not support required functions\n"); return NULL; } if(mtd->oobblock != YAFFS_BYTES_PER_CHUNK || mtd->oobsize != YAFFS_BYTES_PER_SPARE) { printk(KERN_DEBUG "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 ram emulation sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL); if(!dev) { // Deep shit could not allocate device structure printk(KERN_DEBUG"yaffs_read_super: Failed trying to allocate yaffs_Device. Terminating debug.\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. dev->writeChunkToNAND = nandmtd_WriteChunkToNAND; dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; 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); yaffs_GutsInitialise(yaffs_SuperToDevice(sb)); T(YAFFS_TRACE_OS,("yaffs_read_super: guts initialised\n")); // Create root inode inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,yaffs_Root(yaffs_SuperToDevice(sb))); yaffs_GrossUnlock(dev); if (!inode) return NULL; 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;}#ifdef CONFIG_YAFFS_MTD_ENABLEDstatic struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(0,sb,data,silent);}static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV);#endif#ifdef CONFIG_YAFFS_RAM_ENABLEDstatic struct super_block *yaffs_ram_read_super(struct super_block * sb, void * data, int silent){ return yaffs_internal_read_super(1,sb,data,silent);}static DECLARE_FSTYPE(yaffs_ram_fs_type, "yaffsram", yaffs_ram_read_super, FS_SINGLE);#endif // CONFIG_YAFFS_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); 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;}static int __init init_yaffs_fs(void){ int error = 0; yaffs_dev = yaffsram_dev = NULL; printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n");#ifdef CONFIG_YAFFS_USE_GENERIC_RW printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n");#else printk(KERN_DEBUG "yaffs is using direct read/write (uncached)\n");#endif /* 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; }#ifdef CONFIG_YAFFS_RAM_ENABLED#if 0 my_proc_ram_write_entry = create_proc_entry("yaffs_ram", S_IRUGO | S_IFREG, &proc_root); if(!my_proc_ram_write_entry) { return -ENOMEM; } else { my_proc_ram_write_entry->write_proc = yaffs_proc_ram_write; }#endif error = register_filesystem(&yaffs_ram_fs_type); if(error) { return error; }#endif //CONFIG_YAFFS_RAM_ENABLED#ifdef CONFIG_YAFFS_MTD_ENABLED error = register_filesystem(&yaffs_fs_type); if(error) {#ifdef CONFIG_YAFFS_RAM_ENABLED unregister_filesystem(&yaffs_ram_fs_type);#endif //CONFIG_YAFFS_RAM_ENABLED }#endif // CONFIG_YAFFS_MTD_ENABLED return error;}static void __exit exit_yaffs_fs(void){ printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Clean up\n"); remove_proc_entry("yaffs",&proc_root); #ifdef CONFIG_YAFFS_RAM_ENABLED unregister_filesystem(&yaffs_ram_fs_type);#endif#ifdef CONFIG_YAFFS_MTD_ENABLED unregister_filesystem(&yaffs_fs_type);#endif}module_init(init_yaffs_fs)module_exit(exit_yaffs_fs)MODULE_DESCRIPTION("YAFFS - a NAND specific flash file system");MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -