X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_fs.c;h=14fd0b8d04906ad39a955fdf506a58f5c24af311;hp=68f28aafe199084c4ccdb9791c0bd731ce82c72d;hb=549731ddfef7956f9c11c87697be04a075af953b;hpb=36c05dc20667149c315e0d2a4aa3c98c2894da9e diff --git a/yaffs_fs.c b/yaffs_fs.c index 68f28aa..14fd0b8 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -15,11 +15,12 @@ * the VFS. * * Special notes: - * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with this superblock - * >> 2.6: sb->s_fs_info points to the yaffs_Device associated with this superblock + * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with + * this superblock + * >> 2.6: sb->s_fs_info points to the yaffs_Device associated with this + * superblock * >> inode->u.generic_ip points to the associated yaffs_Object. * - * * Acknowledgements: * * Luc van OostenRyck for numerous patches. * * Nick Bane for numerous patches. @@ -29,12 +30,10 @@ * * Some code bodily lifted from JFFS2. */ - -const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.16 2005-07-31 03:58:17 marty Exp $"; +const char *yaffs_fs_c_version = + "$Id: yaffs_fs.c,v 1.33 2005-10-27 22:24:04 marty Exp $"; extern const char *yaffs_guts_c_version; - - #include #include #include @@ -50,14 +49,15 @@ extern const char *yaffs_guts_c_version; #include #include - #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) #include /* Added NCB 15-8-2003 */ #include #define UnlockPage(p) unlock_page(p) #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) -#define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) // FIXME: use sb->s_id instead ? + +/* FIXME: use sb->s_id instead ? */ +#define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) #else @@ -72,191 +72,170 @@ extern const char *yaffs_guts_c_version; #include "yportenv.h" #include "yaffs_guts.h" +unsigned yaffs_traceMask = YAFFS_TRACE_ALWAYS | YAFFS_TRACE_BAD_BLOCKS /* | 0xFFFFFFFF */; - - -unsigned yaffs_traceMask = YAFFS_TRACE_ALWAYS | YAFFS_TRACE_BAD_BLOCKS; -//unsigned yaffs_traceMask = 0xFFFFFFFF; - - -#ifdef CONFIG_YAFFS_RAM_ENABLED -#include "yaffs_nandemul.h" -// 2 MB of RAM for emulation -#define YAFFS_RAM_EMULATION_SIZE 0x200000 -#endif //CONFIG_YAFFS_RAM_ENABLED - -#if CONFIG_YAFFS2_RAM_ENABLED -#include "yaffs_nandemul2k.h" -#endif - -#ifdef CONFIG_YAFFS_MTD_ENABLED #include #include "yaffs_mtdif.h" #include "yaffs_mtdif2.h" -#endif //CONFIG_YAFFS_MTD_ENABLED - -//#define T(x) printk x - +/*#define T(x) printk x */ #define yaffs_InodeToObject(iptr) ((yaffs_Object *)((iptr)->u.generic_ip)) #define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode) -//NCB #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp) -//#if defined(CONFIG_KERNEL_2_5) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->s_fs_info) #else #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp) #endif - static void yaffs_put_super(struct super_block *sb); -#if 0 -static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos); -#endif +static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, + loff_t * pos); -static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos); +static int yaffs_file_flush(struct file *file); -static int yaffs_file_flush(struct file* file); - -static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync); +static int yaffs_sync_object(struct file *file, struct dentry *dentry, + int datasync); static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir); -//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *n); -static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *n); +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *n); +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *n); #else static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode); -static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry); +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry); #endif -static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry); -static int yaffs_unlink(struct inode * dir, struct dentry *dentry); -static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname); -static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode); +static int yaffs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *dentry); +static int yaffs_unlink(struct inode *dir, struct dentry *dentry); +static int yaffs_symlink(struct inode *dir, struct dentry *dentry, + const char *symname); +static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode); -//#if defined(CONFIG_KERNEL_2_5) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev); #else -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev); +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + int dev); #endif -static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry); +static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); static int yaffs_setattr(struct dentry *dentry, struct iattr *attr); -//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf); #else static int yaffs_statfs(struct super_block *sb, struct statfs *buf); #endif -static void yaffs_read_inode (struct inode *inode); +static void yaffs_read_inode(struct inode *inode); -static void yaffs_put_inode (struct inode *inode); +static void yaffs_put_inode(struct inode *inode); static void yaffs_delete_inode(struct inode *); static void yaffs_clear_inode(struct inode *); -static int yaffs_readpage(struct file *file, struct page * page); +static int yaffs_readpage(struct file *file, struct page *page); #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) static int yaffs_writepage(struct page *page, struct writeback_control *wbc); #else static int yaffs_writepage(struct page *page); #endif -static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to); -static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to); +static int yaffs_prepare_write(struct file *f, struct page *pg, + unsigned offset, unsigned to); +static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, + unsigned to); -static int yaffs_readlink(struct dentry *dentry, char __user *buffer, int buflen); +static int yaffs_readlink(struct dentry *dentry, char __user * buffer, + int buflen); static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); - - static struct address_space_operations yaffs_file_address_operations = { - .readpage = yaffs_readpage, - .writepage = yaffs_writepage, - .prepare_write = yaffs_prepare_write, - .commit_write = yaffs_commit_write, + .readpage = yaffs_readpage, + .writepage = yaffs_writepage, + .prepare_write = yaffs_prepare_write, + .commit_write = yaffs_commit_write, }; static struct file_operations yaffs_file_operations = { - .read = generic_file_read, - .write = generic_file_write, - .mmap = generic_file_mmap, - .flush = yaffs_file_flush, - .fsync = yaffs_sync_object, + .read = generic_file_read, + .write = generic_file_write, + .mmap = generic_file_mmap, + .flush = yaffs_file_flush, + .fsync = yaffs_sync_object, }; static struct inode_operations yaffs_file_inode_operations = { - .setattr = yaffs_setattr, + .setattr = yaffs_setattr, }; -struct inode_operations yaffs_symlink_inode_operations = { - .readlink = yaffs_readlink, - .follow_link = yaffs_follow_link, - .setattr = yaffs_setattr, +static struct inode_operations yaffs_symlink_inode_operations = { + .readlink = yaffs_readlink, + .follow_link = yaffs_follow_link, + .setattr = yaffs_setattr, }; static struct inode_operations yaffs_dir_inode_operations = { - .create = yaffs_create, - .lookup = yaffs_lookup, - .link = yaffs_link, - .unlink = yaffs_unlink, - .symlink = yaffs_symlink, - .mkdir = yaffs_mkdir, - .rmdir = yaffs_unlink, - .mknod = yaffs_mknod, - .rename = yaffs_rename, - .setattr = yaffs_setattr, + .create = yaffs_create, + .lookup = yaffs_lookup, + .link = yaffs_link, + .unlink = yaffs_unlink, + .symlink = yaffs_symlink, + .mkdir = yaffs_mkdir, + .rmdir = yaffs_unlink, + .mknod = yaffs_mknod, + .rename = yaffs_rename, + .setattr = yaffs_setattr, }; static struct file_operations yaffs_dir_operations = { - .read = generic_read_dir, - .readdir = yaffs_readdir, - .fsync = yaffs_sync_object, + .read = generic_read_dir, + .readdir = yaffs_readdir, + .fsync = yaffs_sync_object, }; static struct super_operations yaffs_super_ops = { - .statfs = yaffs_statfs, - .read_inode = yaffs_read_inode, - .put_inode = yaffs_put_inode, - .put_super = yaffs_put_super, - .delete_inode = yaffs_delete_inode, - .clear_inode = yaffs_clear_inode, + .statfs = yaffs_statfs, + .read_inode = yaffs_read_inode, + .put_inode = yaffs_put_inode, + .put_super = yaffs_put_super, + .delete_inode = yaffs_delete_inode, + .clear_inode = yaffs_clear_inode, }; - - -static void yaffs_GrossLock(yaffs_Device *dev) +static void yaffs_GrossLock(yaffs_Device * dev) { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs locking\n")); + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locking\n")); down(&dev->grossLock); } -static void yaffs_GrossUnlock(yaffs_Device *dev) +static void yaffs_GrossUnlock(yaffs_Device * dev) { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs unlocking\n")); + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs unlocking\n")); up(&dev->grossLock); } -static int yaffs_readlink(struct dentry *dentry, char __user *buffer, int buflen) +static int yaffs_readlink(struct dentry *dentry, char __user * buffer, + int buflen) { unsigned char *alias; int ret; yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; - yaffs_GrossLock(dev); - + alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); - + yaffs_GrossUnlock(dev); - - if(!alias) + + if (!alias) return -ENOMEM; ret = vfs_readlink(dentry, buffer, buflen, alias); @@ -270,143 +249,151 @@ static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) int ret; yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; - yaffs_GrossLock(dev); alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); - + yaffs_GrossUnlock(dev); - - if(!alias) + + if (!alias) return -ENOMEM; - ret = vfs_follow_link(nd,alias); + ret = vfs_follow_link(nd, alias); kfree(alias); return ret; } - -struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj); +struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, + yaffs_Object * obj); /* * Lookup is used to find objects in the fs */ -//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *n) +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *n) #else -static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry) +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) #endif { yaffs_Object *obj; - struct inode *inode = NULL; // NCB 2.5/2.6 needs NULL here - - yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev; + struct inode *inode = NULL; /* NCB 2.5/2.6 needs NULL here */ + yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev; yaffs_GrossLock(dev); - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup for %d:%s\n",yaffs_InodeToObject(dir)->objectId,dentry->d_name.name)); - - obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),dentry->d_name.name); - - obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink - + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_lookup for %d:%s\n", + yaffs_InodeToObject(dir)->objectId, dentry->d_name.name)); - - if(obj) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId)); - - inode = yaffs_get_inode(dir->i_sb, obj->yst_mode,0,obj); - - if(inode) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_loookup dentry \n")); -/* #if 0 asserted by NCB for 2.5/6 compatability - falls through to d_add even if NULL inode */ + obj = + yaffs_FindObjectByName(yaffs_InodeToObject(dir), + dentry->d_name.name); + + obj = yaffs_GetEquivalentObject(obj); /* in case it was a hardlink */ + + if (obj) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_lookup found %d\n", obj->objectId)); + + inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); + + if (inode) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_loookup dentry \n")); +/* #if 0 asserted by NCB for 2.5/6 compatability - falls through to + * d_add even if NULL inode */ #if 0 - //dget(dentry); // try to solve directory bug - d_add(dentry,inode); - + /*dget(dentry); // try to solve directory bug */ + d_add(dentry, inode); + yaffs_GrossUnlock(dev); - // return dentry; + /* return dentry; */ return NULL; #endif } - } - else - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup not found\n")); - + } else { + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n")); + } yaffs_GrossUnlock(dev); -/* added NCB for 2.5/6 compatability - forces add even if inode is NULL which creates dentry hash*/ - d_add(dentry,inode); - +/* added NCB for 2.5/6 compatability - forces add even if inode is + * NULL which creates dentry hash */ + d_add(dentry, inode); + return NULL; - // return (ERR_PTR(-EIO)); - + /* return (ERR_PTR(-EIO)); */ + } -// For now put inode is just for debugging -// Put inode is called when the inode **structure** is put. +/* For now put inode is just for debugging + * Put inode is called when the inode **structure** is put. + */ static void yaffs_put_inode(struct inode *inode) { - T(YAFFS_TRACE_OS,("yaffs_put_inode: ino %d, count %d\n",(int)inode->i_ino, atomic_read(&inode->i_count))); - + T(YAFFS_TRACE_OS, + ("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino, + atomic_read(&inode->i_count))); + } -// clear is called to tell the fs to release any per-inode data it holds +/* clear is called to tell the fs to release any per-inode data it holds */ static void yaffs_clear_inode(struct inode *inode) { yaffs_Object *obj; yaffs_Device *dev; - + obj = yaffs_InodeToObject(inode); - - T(YAFFS_TRACE_OS,("yaffs_clear_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count), - obj ? "object exists" : "null object")); - if(obj) - { + T(YAFFS_TRACE_OS, + ("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino, + atomic_read(&inode->i_count), + obj ? "object exists" : "null object")); + + if (obj) { dev = obj->myDev; yaffs_GrossLock(dev); - - // Clear the association between the inode ant the yaffs_Object. + + /* Clear the association between the inode and + * the yaffs_Object. + */ obj->myInode = NULL; inode->u.generic_ip = NULL; - - // If the object freeing was deferred, then the real free happens now. - // This should fix the inode inconsistency problem. - + + /* If the object freeing was deferred, then the real + * free happens now. + * This should fix the inode inconsistency problem. + */ + yaffs_HandleDeferedFree(obj); - + yaffs_GrossUnlock(dev); } - - + } -// delete is called when the link count is zero and the inode -// is put (ie. nobody wants to know about it anymore, time to -// delete the file). -// NB Must call clear_inode() +/* delete is called when the link count is zero and the inode + * is put (ie. nobody wants to know about it anymore, time to + * delete the file). + * NB Must call clear_inode() + */ static void yaffs_delete_inode(struct inode *inode) { yaffs_Object *obj = yaffs_InodeToObject(inode); yaffs_Device *dev; - T(YAFFS_TRACE_OS,("yaffs_delete_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count), - obj ? "object exists" : "null object")); - - if(obj) - { - dev = obj->myDev; + T(YAFFS_TRACE_OS, + ("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino, + atomic_read(&inode->i_count), + obj ? "object exists" : "null object")); + + if (obj) { + dev = obj->myDev; yaffs_GrossLock(dev); yaffs_DeleteFile(obj); yaffs_GrossUnlock(dev); @@ -414,62 +401,63 @@ static void yaffs_delete_inode(struct inode *inode) clear_inode(inode); } - -static int yaffs_file_flush(struct file* file) +static int yaffs_file_flush(struct file *file) { yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry); - + yaffs_Device *dev = obj->myDev; - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_flush object %d (%s)\n",obj->objectId, - obj->dirty ? "dirty" : "clean")); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_file_flush object %d (%s)\n", obj->objectId, + obj->dirty ? "dirty" : "clean")); yaffs_GrossLock(dev); - - yaffs_FlushFile(obj,1); + + yaffs_FlushFile(obj, 1); yaffs_GrossUnlock(dev); - return 0; + return 0; } - - -static int yaffs_readpage_nolock(struct file *f, struct page * pg) +static int yaffs_readpage_nolock(struct file *f, struct page *pg) { - // Lifted from jffs2 - + /* Lifted from jffs2 */ + yaffs_Object *obj; unsigned char *pg_buf; int ret; yaffs_Device *dev; - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readpage at %08x, size %08x\n", - (unsigned)(pg->index << PAGE_CACHE_SHIFT), (unsigned)PAGE_CACHE_SIZE)); + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage at %08x, size %08x\n", + (unsigned)(pg->index << PAGE_CACHE_SHIFT), + (unsigned)PAGE_CACHE_SIZE)); - obj = yaffs_DentryToObject(f->f_dentry); + obj = yaffs_DentryToObject(f->f_dentry); dev = obj->myDev; - - + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - BUG_ON(!PageLocked(pg)); + BUG_ON(!PageLocked(pg)); #else if (!PageLocked(pg)) - PAGE_BUG(pg); + PAGE_BUG(pg); #endif pg_buf = kmap(pg); /* FIXME: Can kmap fail? */ yaffs_GrossLock(dev); - - ret = yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE); + + ret = + yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE); yaffs_GrossUnlock(dev); - - if(ret >= 0) ret = 0; + + if (ret >= 0) + ret = 0; if (ret) { ClearPageUptodate(pg); @@ -482,25 +470,23 @@ static int yaffs_readpage_nolock(struct file *f, struct page * pg) flush_dcache_page(pg); kunmap(pg); - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readpage done\n")); + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage done\n")); return ret; } static int yaffs_readpage_unlock(struct file *f, struct page *pg) { - int ret = yaffs_readpage_nolock(f,pg); + int ret = yaffs_readpage_nolock(f, pg); UnlockPage(pg); return ret; } -static int yaffs_readpage(struct file *f, struct page * pg) +static int yaffs_readpage(struct file *f, struct page *pg) { - return yaffs_readpage_unlock(f,pg); + return yaffs_readpage_unlock(f, pg); } -// writepage inspired by/stolen from smbfs -// +/* writepage inspired by/stolen from smbfs */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) static int yaffs_writepage(struct page *page, struct writeback_control *wbc) @@ -509,6 +495,7 @@ static int yaffs_writepage(struct page *page) #endif { struct address_space *mapping = page->mapping; + loff_t offset = (loff_t) page->index << PAGE_CACHE_SHIFT; struct inode *inode; unsigned long end_index; char *buffer; @@ -522,108 +509,124 @@ static int yaffs_writepage(struct page *page) if (!inode) BUG(); + if (offset > inode->i_size) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_writepage at %08x, inode size = %08x!!!\n", + (unsigned)(page->index << PAGE_CACHE_SHIFT), + (unsigned)inode->i_size)); + T(YAFFS_TRACE_OS, + (KERN_DEBUG " -> don't care!!\n")); + unlock_page(page); + return 0; + } + end_index = inode->i_size >> PAGE_CACHE_SHIFT; /* easy case */ - if (page->index < end_index) - { + if (page->index < end_index) { nBytes = PAGE_CACHE_SIZE; + } else { + nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1); } - else - { - nBytes = inode->i_size & (PAGE_CACHE_SIZE-1); - } - // What's happening here? - ///* OK, are we completely out? */ - //if (page->index >= end_index+1 || !offset) - // return -EIO; get_page(page); - buffer = kmap(page); obj = yaffs_InodeToObject(inode); yaffs_GrossLock(obj->myDev); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_writepage at %08x, size %08x\n", + (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes)); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "writepag0: obj = %05x, ino = %05x\n", + (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); - nWritten = yaffs_WriteDataToFile(obj,buffer,page->index << PAGE_CACHE_SHIFT,nBytes,0); + nWritten = + yaffs_WriteDataToFile(obj, buffer, page->index << PAGE_CACHE_SHIFT, + nBytes, 0); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "writepag1: obj = %05x, ino = %05x\n", + (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); yaffs_GrossUnlock(obj->myDev); - + kunmap(page); SetPageUptodate(page); UnlockPage(page); put_page(page); - return (nWritten == nBytes) ? 0 : -ENOSPC; + return (nWritten == nBytes) ? 0 : -ENOSPC; } - - -static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to) +static int yaffs_prepare_write(struct file *f, struct page *pg, + unsigned offset, unsigned to) { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_prepair_write\n")); - if(!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) - return yaffs_readpage_nolock(f,pg); + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_prepair_write\n")); + if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) + return yaffs_readpage_nolock(f, pg); return 0; - + } -static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to) +static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, + unsigned to) { void *addr = page_address(pg) + offset; - loff_t pos = (((loff_t)pg->index) << PAGE_CACHE_SHIFT) + offset; + loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset; int nBytes = to - offset; int nWritten; - + unsigned spos = pos; unsigned saddr = (unsigned)addr; - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write addr %x pos %x nBytes %d\n",saddr,spos,nBytes)); - - nWritten = yaffs_file_write(f,addr, nBytes, &pos); - - if(nWritten != nBytes) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write not same size nWritten %d nBytes %d\n",nWritten,nBytes)); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_commit_write addr %x pos %x nBytes %d\n", saddr, + spos, nBytes)); + + nWritten = yaffs_file_write(f, addr, nBytes, &pos); + + if (nWritten != nBytes) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_commit_write not same size nWritten %d nBytes %d\n", + nWritten, nBytes)); SetPageError(pg); ClearPageUptodate(pg); - } - else - { + } else { SetPageUptodate(pg); } - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten)); - - return nWritten; - -} + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_commit_write returning %d\n", + nWritten == nBytes ? 0 : -1)); + return nWritten == nBytes ? 0 : -1; +} -static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj) +static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj) { - if (inode && obj) - { + if (inode && obj) { inode->i_ino = obj->objectId; inode->i_mode = obj->yst_mode; inode->i_uid = obj->yst_uid; inode->i_gid = obj->yst_gid; inode->i_blksize = inode->i_sb->s_blocksize; -//#if defined(CONFIG_KERNEL_2_5) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) inode->i_rdev = old_decode_dev(obj->yst_rdev); - inode->i_atime.tv_sec = (time_t)(obj->yst_atime); + inode->i_atime.tv_sec = (time_t) (obj->yst_atime); inode->i_atime.tv_nsec = 0; - inode->i_mtime.tv_sec = (time_t)obj->yst_mtime; - inode->i_mtime.tv_nsec =0; - inode->i_ctime.tv_sec = (time_t)obj->yst_ctime; + inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; + inode->i_mtime.tv_nsec = 0; + inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; inode->i_ctime.tv_nsec = 0; #else inode->i_rdev = obj->yst_rdev; @@ -635,332 +638,300 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj) inode->i_blocks = (inode->i_size + 511) >> 9; inode->i_nlink = yaffs_GetObjectLinkCount(obj); - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_FillInode mode %x uid %d gid %d size %d count %d\n", - inode->i_mode, inode->i_uid, inode->i_gid, (int)inode->i_size, atomic_read(&inode->i_count))); - - switch (obj->yst_mode & S_IFMT) - { - default: // fifo, device or socket + + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_FillInode mode %x uid %d gid %d size %d count %d\n", + inode->i_mode, inode->i_uid, inode->i_gid, + (int)inode->i_size, atomic_read(&inode->i_count))); + + switch (obj->yst_mode & S_IFMT) { + default: /* fifo, device or socket */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - init_special_inode(inode, obj->yst_mode,old_decode_dev(obj->yst_rdev)); + init_special_inode(inode, obj->yst_mode, + old_decode_dev(obj->yst_rdev)); #else - init_special_inode(inode, obj->yst_mode,(dev_t)(obj->yst_rdev)); -#endif - break; - case S_IFREG: // file - inode->i_op = &yaffs_file_inode_operations; - inode->i_fop = &yaffs_file_operations; - inode->i_mapping->a_ops = &yaffs_file_address_operations; - break; - case S_IFDIR: // directory - inode->i_op = &yaffs_dir_inode_operations; - inode->i_fop = &yaffs_dir_operations; - break; - case S_IFLNK: // symlink - inode->i_op = &yaffs_symlink_inode_operations; - break; + init_special_inode(inode, obj->yst_mode, + (dev_t) (obj->yst_rdev)); +#endif + break; + case S_IFREG: /* file */ + inode->i_op = &yaffs_file_inode_operations; + inode->i_fop = &yaffs_file_operations; + inode->i_mapping->a_ops = + &yaffs_file_address_operations; + break; + case S_IFDIR: /* directory */ + inode->i_op = &yaffs_dir_inode_operations; + inode->i_fop = &yaffs_dir_operations; + break; + case S_IFLNK: /* symlink */ + inode->i_op = &yaffs_symlink_inode_operations; + break; } - - + inode->u.generic_ip = obj; obj->myInode = inode; - - } - else - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_FileInode invalid parameters\n")); + + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_FileInode invalid parameters\n")); } } -struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj) +struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, + yaffs_Object * obj) { - struct inode * inode; - - if(!sb) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_get_inode for NULL super_block!!\n")); - return NULL; - + struct inode *inode; + + if (!sb) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_get_inode for NULL super_block!!\n")); + return NULL; + } - - if(!obj) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_get_inode for NULL object!!\n")); - return NULL; - + + if (!obj) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_get_inode for NULL object!!\n")); + return NULL; + } - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_get_inode for object %d\n",obj->objectId)); - inode = iget(sb,obj->objectId); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId)); + + inode = iget(sb, obj->objectId); + + /* NB Side effect: iget calls back to yaffs_read_inode(). */ + /* iget also increments the inode's i_count */ - // NB Side effect: iget calls back to yaffs_read_inode(). - // iget also increments the inode's i_count - return inode; } -#if 0 - -// No longer used because we use generic rw */ -static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos) +static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, + loff_t * pos) { yaffs_Object *obj; - int nRead,ipos; + int nWritten, ipos; struct inode *inode; yaffs_Device *dev; - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_read\n")); - - obj = yaffs_DentryToObject(f->f_dentry); - - dev = obj->myDev; - - yaffs_GrossLock(dev); - - inode = f->f_dentry->d_inode; - - if (*pos < inode->i_size) - { - if (*pos + n > inode->i_size) - { - n = inode->i_size - *pos; - } - } - else - { - n = 0; - } - - nRead = yaffs_ReadDataFromFile(obj,buf,*pos,n); - if(nRead > 0) - { - f->f_pos += nRead; - } - - yaffs_GrossUnlock(dev); - - ipos = *pos; - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_read read %d bytes, %d read at %d\n",n,nRead,ipos)); - return nRead; - -} -#endif + obj = yaffs_DentryToObject(f->f_dentry); -static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos) -{ - yaffs_Object *obj; - int nWritten,ipos; - struct inode *inode; - yaffs_Device *dev; - - - obj = yaffs_DentryToObject(f->f_dentry); - dev = obj->myDev; - + yaffs_GrossLock(dev); inode = f->f_dentry->d_inode; - if(!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) - { + if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) { ipos = inode->i_size; - } - else - { + } else { ipos = *pos; } - - - if(!obj) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write: hey obj is null!\n")); - } - else - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write about to write writing %d bytes to object %d at %d\n",n,obj->objectId,ipos)); + + if (!obj) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_file_write: hey obj is null!\n")); + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_file_write about to write writing %d bytes" + "to object %d at %d\n", + n, obj->objectId, ipos)); } - nWritten = yaffs_WriteDataToFile(obj,buf,ipos,n,0); + nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0); - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write writing %d bytes, %d written at %d\n",n,nWritten,ipos)); - if(nWritten > 0) - { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_file_write writing %d bytes, %d written at %d\n", + n, nWritten, ipos)); + if (nWritten > 0) { ipos += nWritten; *pos = ipos; - if(ipos > inode->i_size) - { + if (ipos > inode->i_size) { inode->i_size = ipos; - inode->i_blocks = (ipos + 511)>>9; - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,(int)(inode->i_blocks))); + inode->i_blocks = (ipos + 511) >> 9; + + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_file_write size updated to %d bytes, " + "%d blocks\n", + ipos, (int)(inode->i_blocks))); } - + } yaffs_GrossUnlock(dev); - + return nWritten != n ? -ENOSPC : nWritten; } - - static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) { yaffs_Object *obj; yaffs_Device *dev; struct inode *inode = f->f_dentry->d_inode; unsigned long offset, curoffs; - struct list_head *i; + struct list_head *i; yaffs_Object *l; - - char name[YAFFS_MAX_NAME_LENGTH +1]; - - obj = yaffs_DentryToObject(f->f_dentry); + + char name[YAFFS_MAX_NAME_LENGTH + 1]; + + obj = yaffs_DentryToObject(f->f_dentry); dev = obj->myDev; - + yaffs_GrossLock(dev); - + offset = f->f_pos; - - T(YAFFS_TRACE_OS,("yaffs_readdir: starting at %d\n",(int)offset)); - - if(offset == 0) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: entry . ino %d \n",(int)inode->i_ino)); - if(filldir(dirent,".",1,offset,inode->i_ino,DT_DIR) < 0) - { + + T(YAFFS_TRACE_OS, ("yaffs_readdir: starting at %d\n", (int)offset)); + + if (offset == 0) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_readdir: entry . ino %d \n", + (int)inode->i_ino)); + if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) + < 0) { goto out; } offset++; f->f_pos++; } - if(offset == 1) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: entry .. ino %d \n",(int)f->f_dentry->d_parent->d_inode->i_ino)); - if(filldir(dirent,"..",2,offset,f->f_dentry->d_parent->d_inode->i_ino,DT_DIR) < 0) - { + if (offset == 1) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_readdir: entry .. ino %d \n", + (int)f->f_dentry->d_parent->d_inode->i_ino)); + if (filldir + (dirent, "..", 2, offset, + f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { goto out; } offset++; f->f_pos++; } - + curoffs = 1; - - list_for_each(i,&obj->variant.directoryVariant.children) - { + + list_for_each(i, &obj->variant.directoryVariant.children) { curoffs++; - if(curoffs >= offset) - { - l = list_entry(i, yaffs_Object,siblings); - - yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1); - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: %s inode %d\n",name,yaffs_GetObjectInode(l))); - - if(filldir(dirent, - name, - strlen(name), - offset, - yaffs_GetObjectInode(l), - yaffs_GetObjectType(l)) - < 0) - { + if (curoffs >= offset) { + l = list_entry(i, yaffs_Object, siblings); + + yaffs_GetObjectName(l, name, + YAFFS_MAX_NAME_LENGTH + 1); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_readdir: %s inode %d\n", name, + yaffs_GetObjectInode(l))); + + if (filldir(dirent, + name, + strlen(name), + offset, + yaffs_GetObjectInode(l), + yaffs_GetObjectType(l)) + < 0) { goto up_and_out; } - + offset++; - f->f_pos++; + f->f_pos++; } } - up_and_out: - out: - - yaffs_GrossUnlock(dev); - + up_and_out: + out: + + yaffs_GrossUnlock(dev); + return 0; } - /* * File creation. Allocate an inode, and we're done.. */ -//#if defined(CONFIG_KERNEL_2_5) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t rdev) #else -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + int rdev) #endif { struct inode *inode; - + yaffs_Object *obj = NULL; yaffs_Device *dev; - + yaffs_Object *parent = yaffs_InodeToObject(dir); - + int error = -ENOSPC; uid_t uid = current->fsuid; gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - if(parent) - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: parent object %d type %d\n", - parent->objectId,parent->variantType)); - } - else - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: could not get parent object\n")); + if (parent) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod: parent object %d type %d\n", + parent->objectId, parent->variantType)); + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod: could not get parent object\n")); return -EPERM; } - - T(YAFFS_TRACE_OS,("yaffs_mknod: making oject for %s, mode %x dev %x\n", - dentry->d_name.name, mode,rdev)); + + T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, " + "mode %x dev %x\n", + dentry->d_name.name, mode, rdev)); dev = parent->myDev; - + yaffs_GrossLock(dev); - switch (mode & S_IFMT) - { - default: - // Special (socket, fifo, device...) - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making special\n")); + switch (mode & S_IFMT) { + default: + /* Special (socket, fifo, device...) */ + T(YAFFS_TRACE_OS, (KERN_DEBUG + "yaffs_mknod: making special\n")); #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,uid, gid,old_encode_dev(rdev)); + obj = + yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, + gid, old_encode_dev(rdev)); #else - obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,uid, gid,rdev); -#endif - break; - case S_IFREG: // file - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making file\n")); - obj = yaffs_MknodFile(parent,dentry->d_name.name,mode,uid, gid); - break; - case S_IFDIR: // directory - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making directory\n")); - obj = yaffs_MknodDirectory(parent,dentry->d_name.name,mode,uid, gid); - break; - case S_IFLNK: // symlink - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making file\n")); - obj = NULL; // Do we ever get here? - break; + obj = + yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, + gid, rdev); +#endif + break; + case S_IFREG: /* file */ + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n")); + obj = + yaffs_MknodFile(parent, dentry->d_name.name, mode, uid, + gid); + break; + case S_IFDIR: /* directory */ + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod: making directory\n")); + obj = + yaffs_MknodDirectory(parent, dentry->d_name.name, mode, + uid, gid); + break; + case S_IFLNK: /* symlink */ + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n")); + obj = NULL; /* Do we ever get here? */ + break; } - - if(obj) - { + + if (obj) { inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); d_instantiate(dentry, inode); - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count))); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod created object %d count = %d\n", + obj->objectId, atomic_read(&inode->i_count))); error = 0; - } - else - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod failed making object\n")); + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod failed making object\n")); error = -ENOMEM; } @@ -969,160 +940,150 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int r return error; } -static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode) +static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int retVal; - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mkdir\n")); - retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0); + 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) - { + /* attempt to fix dir bug - didn't work */ + if (!retVal) { dget(dentry); } #endif return retVal; } -//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *n) +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *n) #else static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) #endif { - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_create\n")); + 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) +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)); - + + 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); - - + + retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name); + yaffs_GrossUnlock(dev); - - if( retVal == YAFFS_OK) - { + + if (retVal == YAFFS_OK) { dentry->d_inode->i_nlink--; mark_inode_dirty(dentry->d_inode); return 0; - } - else - { + } else { return -ENOTEMPTY; } } - /* * Create a link... */ -static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry) +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_Object *link = NULL; yaffs_Device *dev; - - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_link\n")); - + + 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 + if (!S_ISDIR(inode->i_mode)) /* Don't link directories */ { - link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj); + link = + yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name, + obj); } - - if(link) - { - old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(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))); - + 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) - { - + if (link) { + return 0; } - - - return -EPERM; -} + return -EPERM; +} -static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) +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")); - + + 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); + obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, + S_IFLNK | S_IRWXUGO, uid, gid, symname); yaffs_GrossUnlock(dev); - if(obj) - { + if (obj) { + + struct inode *inode; - 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")); + T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink created OK\n")); return 0; - } - else - { - T(YAFFS_TRACE_OS,(KERN_DEBUG"symlink not created\n")); + } 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) +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")); + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_object\n")); yaffs_GrossLock(dev); - yaffs_FlushFile(obj,1); + yaffs_FlushFile(obj, 1); yaffs_GrossUnlock(dev); return 0; } @@ -1132,54 +1093,56 @@ static int yaffs_sync_object(struct file * file, struct dentry *dentry, int data * * 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) +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; - int removed = 0; 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); - // 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)) - { + + 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 - { - - // Unlink the target if it exists - removed = yaffs_Unlink(yaffs_InodeToObject(new_dir),new_dentry->d_name.name); + } 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); - - 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(removed == YAFFS_OK) - { + + if (retVal == YAFFS_OK) { + if(target) { new_dentry->d_inode->i_nlink--; mark_inode_dirty(new_dentry->d_inode); } - + return 0; - } - else - { + } else { return -ENOTEMPTY; } - } @@ -1188,30 +1151,28 @@ 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) - { - + + 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) - { + if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) == + YAFFS_OK) { error = 0; - } - else - { + } else { error = -EPERM; } yaffs_GrossUnlock(dev); if (!error) - error = inode_setattr(inode,attr); + error = inode_setattr(inode, attr); } return error; } -//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf) #else @@ -1219,53 +1180,56 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf) #endif { - yaffs_Device *dev = yaffs_SuperToDevice(sb); - T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_statfs\n")); + 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->nBytesPerChunk) - { - - buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * dev->nChunksPerBlock/ - (sb->s_blocksize/dev->nBytesPerChunk); - buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev)/ - (sb->s_blocksize/dev->nBytesPerChunk); - } - else - { - - buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * dev->nChunksPerBlock * - (dev->nBytesPerChunk/sb->s_blocksize); - buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev) * - (dev->nBytesPerChunk/sb->s_blocksize); + if (sb->s_blocksize > dev->nBytesPerChunk) { + + buf->f_blocks = + (dev->endBlock - dev->startBlock + + 1) * dev->nChunksPerBlock / (sb->s_blocksize / + dev->nBytesPerChunk); + buf->f_bfree = + yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize / + dev->nBytesPerChunk); + } else { + + buf->f_blocks = + (dev->endBlock - dev->startBlock + + 1) * dev->nChunksPerBlock * (dev->nBytesPerChunk / + sb->s_blocksize); + buf->f_bfree = + yaffs_GetNumberOfFreeChunks(dev) * (dev->nBytesPerChunk / + sb->s_blocksize); } buf->f_files = 0; buf->f_ffree = 0; - buf->f_bavail = buf->f_bfree; - + buf->f_bavail = buf->f_bfree; + yaffs_GrossUnlock(dev); return 0; } -static void yaffs_read_inode (struct inode *inode) +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 ; + /* 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); + 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); } @@ -1274,11 +1238,10 @@ static LIST_HEAD(yaffs_dev_list); static void yaffs_put_super(struct super_block *sb) { yaffs_Device *dev = yaffs_SuperToDevice(sb); - + yaffs_GrossLock(dev); - if(dev->putSuperFunc) - { - dev->putSuperFunc(sb); + if (dev->putSuperFunc) { + dev->putSuperFunc(sb); } yaffs_Deinitialise(dev); yaffs_GrossUnlock(dev); @@ -1290,308 +1253,230 @@ static void yaffs_put_super(struct super_block *sb) } -#ifdef CONFIG_YAFFS_MTD_ENABLED - -static void yaffs_MTDPutSuper(struct super_block *sb) +static void yaffs_MTDPutSuper(struct super_block *sb) { - + struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; - - if(mtd->sync) - { + + if (mtd->sync) { mtd->sync(mtd); } - + put_mtd_device(mtd); } -#endif - -static struct super_block *yaffs_internal_read_super(int yaffsVersion,int useRam, struct super_block * sb, void * data, int silent) +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; + struct inode *inode = NULL; + struct dentry *root; yaffs_Device *dev = 0; - char devname_buf[BDEVNAME_SIZE+1]; + 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)); - + 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)); -#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: Using yaffs%d\n",yaffsVersion)); - T(YAFFS_TRACE_OS,("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",(int)(sb->s_blocksize))); + 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")); + 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))); - - if(useRam) - { - -#ifdef CONFIG_YAFFS_RAM_ENABLED - // Set the yaffs_Device up for ram emulation - - -#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 + /* 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; + } - if(!dev) - { - // Deep shit could not allocate device structure - T(YAFFS_TRACE_OS,("yaffs_read_super: Failed trying to allocate yaffs_Device.\n")); + 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, (" oobblock %d\n", mtd->oobblock)); + 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)); + + if (yaffsVersion == 2) { + /* Check for version 2 style functions */ + if (!mtd->erase || + !mtd->block_isbad || + !mtd->block_markbad || + !mtd->read || + !mtd->write || + !mtd->write_ecc || + !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device does not support required " + "functions\n"));; return NULL; } - memset(dev,0,sizeof(yaffs_Device)); - dev->genericDevice = NULL; // Not used for RAM emulation. - dev->name = sb->s_type->name; - - nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); - dev->startBlock = 0; - dev->endBlock = nBlocks - 1; - dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; - dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; - dev->nReservedBlocks = 5; - - if(yaffsVersion == 2) - { - dev->writeChunkWithTagsToNAND = nandemul2k_WriteChunkWithTagsToNAND; - dev->readChunkWithTagsFromNAND = nandemul2k_ReadChunkWithTagsFromNAND; - dev->markNANDBlockBad = nandemul2k_MarkNANDBlockBad; - dev->queryNANDBlock = nandemul2k_QueryNANDBlock; - dev->eraseBlockInNAND = nandemul2k_EraseBlockInNAND; - dev->initialiseNAND = nandemul2k_InitialiseNAND; - dev->isYaffs2 = 1; - dev->nChunksPerBlock = nandemul2k_GetChunksPerBlock(); - dev->nBytesPerChunk = nandemul2k_GetBytesPerChunk();; - nBlocks = nandemul2k_GetNumberOfBlocks(); - dev->startBlock = 0; - dev->endBlock = nBlocks - 1; - } - else - { - dev->writeChunkToNAND = nandemul_WriteChunkToNAND; - dev->readChunkFromNAND = nandemul_ReadChunkFromNAND; - dev->eraseBlockInNAND = nandemul_EraseBlockInNAND; - dev->initialiseNAND = nandemul_InitialiseNAND; - dev->isYaffs2 = 0; - } -#endif - - } - else - { -#if defined(CONFIG_YAFFS_MTD_ENABLED) || defined(CONFIG_YAFFS2_MTD_ENABLED) - struct mtd_info *mtd; - - 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))); + 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; } - - // 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)); + } else { + /* Check for V1 style functions */ + if (!mtd->erase || + !mtd->read || + !mtd->write || + !mtd->write_ecc || + !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device does not support required " + "functions\n"));; 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,(" oobblock %d\n",mtd->oobblock)); - 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)); - - if(yaffsVersion == 2) - { - // Check for version 2 style functions - if(!mtd->erase || - !mtd->block_isbad || - !mtd->block_markbad || - !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_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; - } + 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 + /* 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); + sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL); #else - sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL); + 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; + 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; + } - // Set up the memory size parameters.... - - nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + memset(dev, 0, sizeof(yaffs_Device)); + dev->genericDevice = mtd; + dev->name = mtd->name; + + /* Set up the memory size parameters.... */ + + nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + dev->startBlock = 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 = 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 - + } else { + dev->writeChunkToNAND = nandmtd_WriteChunkToNAND; + dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; + dev->isYaffs2 = 0; + } + /* ... and common functions */ + dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND; + dev->initialiseNAND = nandmtd_InitialiseNAND; - // ... 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 = 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 + dev->putSuperFunc = yaffs_MTDPutSuper; + +#ifndef CONFIG_YAFFS_DOES_ECC + dev->useNANDECC = 1; #endif - } /* we assume this is protected by lock_kernel() in mount/umount */ list_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")); + 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)); + /* 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")); - + 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")); + T(YAFFS_TRACE_OS, ("yaffs_read_super: d_alloc_root done\n")); if (!root) { iput(inode); @@ -1599,196 +1484,127 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,int useRam } sb->s_root = root; - T(YAFFS_TRACE_OS,("yaffs_read_super: done\n")); + T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n")); return sb; } - -#ifdef CONFIG_YAFFS_MTD_ENABLED - #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_internal_read_super_mtd(struct super_block * sb, void * data, int silent) +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; + return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL; } -static struct super_block *yaffs_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data) +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); + 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, + .owner = THIS_MODULE, + .name = "yaffs", + .get_sb = yaffs_read_super, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, }; #else -static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent) +static struct super_block *yaffs_read_super(struct super_block *sb, void *data, + int silent) { - return yaffs_internal_read_super(1,0,sb,data,silent); + return yaffs_internal_read_super(1, sb, data, silent); } -static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV); +static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, + FS_REQUIRES_DEV); #endif -#endif // CONFIG_YAFFS_MTD_ENABLED -#ifdef CONFIG_YAFFS2_MTD_ENABLED +#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) +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; + return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL; } -static struct super_block *yaffs2_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data) +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); + 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, + .owner = THIS_MODULE, + .name = "yaffs2", + .get_sb = yaffs2_read_super, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, }; #else -static struct super_block *yaffs2_read_super(struct super_block * sb, void * data, int silent) +static struct super_block *yaffs2_read_super(struct super_block *sb, + void *data, int silent) { - return yaffs_internal_read_super(2,0,sb,data,silent); + return yaffs_internal_read_super(2, sb, data, silent); } -static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, FS_REQUIRES_DEV); +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 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 struct super_block *yaffs_ram_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data) -{ - - return get_sb_nodev(fs, flags, 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_litter_super, - .fs_flags = 0 , -}; -#else -static 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 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 struct super_block *yaffs2_ram_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data) -{ - - return get_sb_nodev(fs, flags, 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_litter_super, - .fs_flags = 0 , -}; -#else -static 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_ENABLED - - +#endif /* CONFIG_YAFFS_YAFFS2 */ static 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) +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,"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; + 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 - ) +static int yaffs_proc_read(char *page, + char **start, + off_t offset, int count, int *eof, void *data) { struct list_head *item; char *buf = page; @@ -1805,8 +1621,9 @@ static int yaffs_proc_read( /* 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); + 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 */ @@ -1819,130 +1636,95 @@ static int yaffs_proc_read( n++; continue; } - buf += sprintf(buf,"\nDevice %d \"%s\"\n", n, dev->name); + 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; + return buf - page < count ? buf - page : count; } -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 systems -struct file_system_to_install -{ - struct file_system_type *fst; - int installed; +/* 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[] = -{ -#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 struct file_system_to_install fs_to_install[] = { +//#ifdef CONFIG_YAFFS_YAFFS1 + {&yaffs_fs_type, 0}, +//#endif +//#ifdef CONFIG_YAFFS_YAFFS2 + {&yaffs2_fs_type, 0}, +//#endif + {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_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; + 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_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++; - } + 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++; + } } @@ -1952,5 +1734,3 @@ 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"); - -