*** empty log message ***
[yaffs/.git] / yaffs_fs.c
index 125d66913b100b019b15cc7f132b4cda178896e6..d669793752559559e71b3083f781b01927ae5c93 100644 (file)
  * Special notes: 
  * >> sb->u.generic_sbp 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 patches marked NCB.
+ * * Some code bodily lifted from JFFS2.
  */
 
 
 
 #include "yaffs_guts.h"
 
-#ifdef YAFFS_RAM_ENABLED
+#ifdef CONFIG_YAFFS_RAM_ENABLED
 #include "yaffs_nandemul.h" 
 // 2 MB of RAM for emulation
 #define YAFFS_RAM_EMULATION_SIZE  0x200000
-#endif // YAFFS_RAM_ENABLED
+#endif //CONFIG_YAFFS_RAM_ENABLED
 
-#ifdef YAFFS_MTD_ENABLED
+#ifdef CONFIG_YAFFS_MTD_ENABLED
 #include <linux/mtd/mtd.h>
 #include "yaffs_mtdif.h"
-#endif //YAFFS_MTD_ENABLED
+#endif //CONFIG_YAFFS_MTD_ENABLED
 
 #define T(x) printk x
 
 
 
 
+static void yaffs_put_super(struct super_block *sb);
+
 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);
+static int yaffs_file_flush(struct file* file);
 
 static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync);
 
@@ -81,20 +90,35 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
 static void yaffs_read_inode (struct inode *inode);
 static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent);
 static void yaffs_put_inode (struct inode *inode);
+static int yaffs_readpage(struct file *file, struct page * page);
+
+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 *buffer, int buflen);
+static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
+
 
-//static int yaffs_readpage(struct file*,struct page *
 
-static struct address_space_operations yaffs_address_ops = {
-//     readpage:               yaffs_readpage,
-//     prepare_write:  yaffs_prepare_write,
-//     commit_write:   yaffs_commit_write
+
+
+static struct address_space_operations yaffs_file_address_operations = {
+       readpage:               yaffs_readpage,
+       prepare_write:  yaffs_prepare_write,
+       commit_write:   yaffs_commit_write
 };
 
 
 static struct file_operations yaffs_file_operations = {
+#ifdef CONFIG_YAFFS_USE_GENERIC_RW
+       read:           generic_file_read,
+       write:          generic_file_write,
+#else
        read:           yaffs_file_read,
        write:          yaffs_file_write,
-//     mmap:           generic_file_mmap,
+#endif
+       mmap:           generic_file_mmap,
+       flush:          yaffs_file_flush,
        fsync:          yaffs_sync_object,
 };
 
@@ -104,11 +128,11 @@ static struct inode_operations yaffs_file_inode_operations = {
 };
 
 
-
-static struct file_operations yaffs_dir_operations = {
-       read:           generic_read_dir,
-       readdir:        yaffs_readdir,
-       fsync:          yaffs_sync_object,
+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 = {
@@ -124,16 +148,57 @@ static struct inode_operations yaffs_dir_inode_operations = {
        setattr:        yaffs_setattr,
 };
 
+static struct file_operations yaffs_dir_operations = {
+       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,
 //     read_inode:
 //     remount_fs:
 //     clear_inode:
 };
 
 
+
+
+
+static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+       unsigned char *alias;
+       int ret;
+
+       alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
+       
+       if(!alias)
+               return -ENOMEM;
+
+       ret = vfs_readlink(dentry, buffer, buflen, alias);
+       kfree(alias);
+       return ret;
+}
+
+static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       unsigned char *alias;
+       int ret;
+       alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
+       
+       if(!alias)
+               return -ENOMEM;
+
+       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);
 
 /*
@@ -149,6 +214,8 @@ static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry)
        
        obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),dentry->d_name.name);
        
+       obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink
+       
        if(obj)
        {
                T((KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId));
@@ -177,37 +244,126 @@ static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry)
 static void yaffs_put_inode(struct inode *inode)
 {
        T(("yaffs_put_inode: ino %d, count %d\n",(int)inode->i_ino, atomic_read(&inode->i_count)));
+       
+       // yaffs_FlushFile(yaffs_InodeToObject(inode));
+       
 }
 
-#ifdef YAFFS_ADDRESS_OPS
-static int yaffs_readpage(struct file *file, struct page * page)
+
+static int yaffs_file_flush(struct file* file)
 {
-       T((KERN_DEBUG"yaffs_readpage\n"));
+       yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry);
+       
+       T((KERN_DEBUG"yaffs_file_flush object %d (%s)\n",obj->objectId,
+                               obj->dirty ? "dirty" : "clean"));
 
-       // TODO
-       return 0;
+    yaffs_FlushFile(obj);
+
+    return 0;
 }
 
-static int yaffs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+
+
+static int yaffs_readpage_nolock(struct file *f, struct page * pg)
 {
-       T((KERN_DEBUG"yaffs_prepare_write\n"));
+       // Lifted from jffs2
+       
+       yaffs_Object *obj;
+       unsigned char *pg_buf;  
+       int ret;
+       
+       T((KERN_DEBUG"yaffs_readpage at %08x, size %08x\n", 
+                     pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE));
 
-       //TODO
-       return 0;
+       obj  = yaffs_DentryToObject(f->f_dentry);
+
+       //down(obj->sem);
+       
+       if (!PageLocked(pg))
+                PAGE_BUG(pg);
+
+       pg_buf = kmap(pg);
+       /* FIXME: Can kmap fail? */
+
+       ret = yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
+
+       if(ret >= 0) ret = 0;
+
+       if (ret) {
+               ClearPageUptodate(pg);
+               SetPageError(pg);
+       } else {
+               SetPageUptodate(pg);
+               ClearPageError(pg);
+       }
+
+       flush_dcache_page(pg);
+       kunmap(pg);
+
+
+
+       //up(&obj->sem);
+
+       T((KERN_DEBUG"yaffs_readpage done\n"));
+       return ret;
 }
 
-static int yaffs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+static int yaffs_readpage_unlock(struct file *f, struct page *pg)
 {
+       int ret = yaffs_readpage_nolock(f,pg);
+       UnlockPage(pg);
+       return ret;
+}
+
+static int yaffs_readpage(struct file *f, struct page * pg)
+{
+       return yaffs_readpage_unlock(f,pg);
+}
+
 
-       struct inode *inode = page->mapping->host;
-       loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to)
+{
 
-       T((KERN_DEBUG"yaffs_commit_write\n"));
+       T((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)
+{
+
+       void *addr = page_address(pg) + offset;
+       loff_t pos = (((loff_t)pg->index) << PAGE_CACHE_SHIFT) + offset;
+       int nBytes = to - offset;
+       int nWritten;
+       
+       unsigned spos = pos;
+       unsigned saddr = addr;
+
+       T((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((KERN_DEBUG"yaffs_commit_write not same size nWritten %d  nBytes %d\n",nWritten,nBytes));
+               SetPageError(pg);
+               ClearPageUptodate(pg);
+       }
+       else
+       {
+               SetPageUptodate(pg);
+       }
+
+       T((KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten));
+       
+       return nWritten;
+
 }
 
-#endif //YAFFS_ADDRESS_OPS
 
 
 static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
@@ -218,10 +374,9 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
                inode->i_mode = obj->st_mode;
                inode->i_uid = obj->st_uid;
                inode->i_gid = obj->st_gid;
-               inode->i_blksize = YAFFS_BYTES_PER_CHUNK;
+               inode->i_blksize = inode->i_sb->s_blocksize;
                inode->i_blocks = 0;
-               inode->i_rdev = NODEV;
-               inode->i_mapping->a_ops = &yaffs_address_ops;
+               inode->i_rdev = obj->st_rdev;;
                inode->i_atime = obj->st_atime;
                inode->i_mtime = obj->st_mtime;
                inode->i_ctime = obj->st_ctime;
@@ -233,19 +388,20 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
                
                switch (obj->st_mode & S_IFMT) 
                {
-                       default:
-                       //      init_special_inode(inode, mode, dev);
+                       default: // fifo, device or socket
+                               init_special_inode(inode, obj->st_mode, obj->st_rdev);
                                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 = &page_symlink_inode_operations;
+                               inode->i_op = &yaffs_symlink_inode_operations;
                                break;
                }
                
@@ -308,6 +464,7 @@ 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;
@@ -316,21 +473,43 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_
        
        obj  = yaffs_DentryToObject(f->f_dentry);
        inode = f->f_dentry->d_inode;
-       nWritten = yaffs_WriteDataToFile(obj,buf,*pos,n);
-       ipos = *pos;
+
+       if(!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
+       {
+               ipos = inode->i_size;
+       }
+       else
+       {
+               ipos = *pos;
+       }
+       
+       
+       if(!obj)
+       {
+               T((KERN_DEBUG"yaffs_file_write: hey obj is null!\n"));
+       }
+       else
+       {
+               T((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);
+
        T((KERN_DEBUG"yaffs_file_write writing %d bytes, %d written at %d\n",n,nWritten,ipos));
        if(nWritten > 0)
        {
-               *pos += nWritten;
-               ipos = *pos;
-               if(*pos > inode->i_size)
+               ipos += nWritten;
+               *pos = ipos;
+               if(ipos > inode->i_size)
                {
-                       inode->i_size = *pos;
-                       T((KERN_DEBUG"yaffs_file_write size updated to %d\n",ipos));
+                       inode->i_size = ipos;
+                       inode->i_blocks = (ipos + inode->i_blksize - 1)/ inode->i_blksize;
+                       
+                       T((KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,inode->i_blocks));
                }
                
        }
-       return nWritten;        
+       return nWritten != n ? -ENOSPC : nWritten;      
 }
 
 
@@ -434,13 +613,15 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d
                return -EPERM;
        }
        
-       T(("yaffs_mknod: making oject for %s, mode %x\n",
-                               dentry->d_name.name, mode));
+       T(("yaffs_mknod: making oject for %s, mode %x dev %x\n",
+                               dentry->d_name.name, mode,dev));
 
        switch (mode & S_IFMT) 
        {
                default:
-               
+                       // Special (socket, fifo, device...)
+                       T((KERN_DEBUG"yaffs_mknod: making special\n"));
+                       obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,current->uid, current->gid,dev);
                        break;
                case S_IFREG:   // file         
                        T((KERN_DEBUG"yaffs_mknod: making file\n"));
@@ -452,16 +633,13 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d
                        break;
                case S_IFLNK:   // symlink
                        T((KERN_DEBUG"yaffs_mknod: making file\n"));
-                       obj = NULL; // Todo
+                       obj = NULL; // Do we ever get here?
                        break;
        }
        
        if(obj)
        {
                inode = yaffs_get_inode(dir->i_sb, mode, dev, obj);
-
-// did not fix dir bug         if((mode & S_IFMT) == S_IFDIR)  atomic_inc(&inode->i_count);
-
                d_instantiate(dentry, inode);
                T((KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count)));
                error = 0;
@@ -501,7 +679,7 @@ static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
 static int yaffs_unlink(struct inode * dir, struct dentry *dentry)
 {
        
-       T((KERN_DEBUG"yaffs_unlink\n"));
+       T((KERN_DEBUG"yaffs_unlink %d:%s\n",dir->i_ino,dentry->d_name.name));
        
        if(yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name) == YAFFS_OK)
        {
@@ -515,36 +693,52 @@ static int yaffs_unlink(struct inode * dir, struct dentry *dentry)
 
 
 /*
- * Link a file..
+ * Create a link...
  */
 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;
        
        T((KERN_DEBUG"yaffs_link\n"));
        
-       return -EPERM; //Todo
+       obj = yaffs_InodeToObject(inode);
        
-
-       if (S_ISDIR(inode->i_mode))
-               return -EPERM;
-
-
-       return 0;
+       link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj);
+       
+       if(link)
+       {
+               return 0;
+       }
+       
+       
+       return -EPERM; 
 }
 
 
 static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
 {
-       int error;
+       yaffs_Object *obj;
        
        T((KERN_DEBUG"yaffs_symlink\n"));
-
        
-       return -ENOMEM; //Todo
+       obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, 
+                                                        S_IFLNK | S_IRWXUGO, current->uid, current->gid,
+                                                        symname);
 
-       error = yaffs_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
-       return error;
+       if(obj)
+       {
+               T((KERN_DEBUG"symlink created OK\n"));
+               return 0;
+       }
+       else
+       {
+               T((KERN_DEBUG"symlink not created\n"));
+
+       }
+       
+       return -ENOMEM;
 }
 
 static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync)
@@ -580,7 +774,7 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
        
-       T((KERN_DEBUG"yaffs_setattr\n"));
+       T((KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId));
        
        if((error = inode_change_ok(inode,attr)) == 0)
        {
@@ -604,12 +798,15 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
        T((KERN_DEBUG"yaffs_statfs\n"));
 
        buf->f_type = YAFFS_MAGIC;
-       buf->f_bsize = YAFFS_BYTES_PER_CHUNK;
+       buf->f_bsize = sb->s_blocksize;
        buf->f_namelen = 255;
-       buf->f_blocks = yaffs_SuperToDevice(sb)->nBlocks * YAFFS_CHUNKS_PER_BLOCK;
+       buf->f_blocks = yaffs_SuperToDevice(sb)->nBlocks * YAFFS_CHUNKS_PER_BLOCK/
+                                               (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);
        buf->f_files = 0;
        buf->f_ffree = 0;
-       buf->f_bavail = yaffs_GetNumberOfFreeChunks(yaffs_SuperToDevice(sb));
+       buf->f_bfree = yaffs_GetNumberOfFreeChunks(yaffs_SuperToDevice(sb))/
+                                               (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);
+       buf->f_bavail =  buf->f_bfree;
        return 0;
 }
 
@@ -626,16 +823,42 @@ static void yaffs_read_inode (struct inode *inode)
 }
 
 
+static void yaffs_put_super(struct super_block *sb)
+{
+       yaffs_Device *dev = yaffs_SuperToDevice(sb);
+       
+       if(dev->putSuperFunc)
+       {
+                dev->putSuperFunc(sb);
+       }
+       yaffs_Deinitialise(dev);
+       kfree(dev);
+}
+
+
+#ifdef CONFIG_YAFFS_MTD_ENABLED
+
+static void  yaffs_MTDPutSuper(struct super_block *sb)
+{
+       
+       struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
+       
+       if(mtd->sync)
+       {
+               mtd->sync(mtd);
+       }
+       
+       put_mtd_device(mtd);
+}
+
+#endif
+
 static struct super_block *yaffs_internal_read_super(int useRam, struct super_block * sb, void * data, int silent)
 {
        struct inode * inode;
        struct dentry * root;
        yaffs_Device *dev;
        
-
-       T(("yaffs_read_super: %s\n", useRam ? "RAM" : "MTD"));
-       sb->s_blocksize = YAFFS_BYTES_PER_CHUNK;
-       sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT;
        sb->s_magic = YAFFS_MAGIC;
        sb->s_op = &yaffs_super_ops;
        
@@ -649,11 +872,26 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                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_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",sb->s_blocksize));
+
+#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY
+       T(("yaffs: Write verification disabled. All guarantees null and void\n");
+#endif
+
+
        
        if(useRam)
        {
 
-#if YAFFS_RAM_ENABLED
+#ifdef CONFIG_YAFFS_RAM_ENABLED
                // Set the yaffs_Device up for ram emulation
 
                sb->u.generic_sbp =     dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL);
@@ -675,12 +913,13 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;
                dev->eraseBlockInNAND = nandemul_EraseBlockInNAND;
                dev->initialiseNAND = nandemul_InitialiseNAND;
+               
 #endif
 
        }
        else
        {       
-#ifdef YAFFS_MTD_ENABLED
+#ifdef CONFIG_YAFFS_MTD_ENABLED
                struct mtd_info *mtd;
                
                printk(KERN_DEBUG "yaffs: Attempting MTD mount on %u.%u, \"%s\"\n",
@@ -755,6 +994,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
                dev->initialiseNAND = nandmtd_InitialiseNAND;
                
+               dev->putSuperFunc = yaffs_MTDPutSuper;
 #endif
        }
 
@@ -785,7 +1025,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
        return sb;
 }
 
-#ifdef YAFFS_MTD_ENABLED
+#ifdef CONFIG_YAFFS_MTD_ENABLED
 static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent)
 {
        return yaffs_internal_read_super(0,sb,data,silent);
@@ -794,7 +1034,7 @@ static struct super_block *yaffs_read_super(struct super_block * sb, void * data
 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV);
 #endif
 
-#ifdef YAFFS_RAM_ENABLED
+#ifdef CONFIG_YAFFS_RAM_ENABLED
 
 static struct super_block *yaffs_ram_read_super(struct super_block * sb, void * data, int silent)
 {
@@ -802,7 +1042,7 @@ static struct super_block *yaffs_ram_read_super(struct super_block * sb, void *
 }
 
 static DECLARE_FSTYPE(yaffs_ram_fs_type, "yaffsram", yaffs_ram_read_super, FS_SINGLE);
-#endif // YAFFS_RAM_ENABLED
+#endif // CONFIG_YAFFS_RAM_ENABLED
 
 
 static struct proc_dir_entry *my_proc_entry;
@@ -837,6 +1077,13 @@ static int __init init_yaffs_fs(void)
        int error = 0;
        
        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,
@@ -848,24 +1095,24 @@ static int __init init_yaffs_fs(void)
        return -ENOMEM;
     }
 
-#ifdef YAFFS_RAM_ENABLED
+#ifdef CONFIG_YAFFS_RAM_ENABLED
 
     error = register_filesystem(&yaffs_ram_fs_type);
     if(error)
     {
        return error;
     }
-#endif //YAFFS_RAM_ENABLED
+#endif //CONFIG_YAFFS_RAM_ENABLED
 
-#ifdef YAFFS_MTD_ENABLED
+#ifdef CONFIG_YAFFS_MTD_ENABLED
        error = register_filesystem(&yaffs_fs_type);
        if(error)
        {
-#ifdef YAFFS_RAM_ENABLED
+#ifdef CONFIG_YAFFS_RAM_ENABLED
                unregister_filesystem(&yaffs_ram_fs_type);
-#endif //YAFFS_RAM_ENABLED
+#endif //CONFIG_YAFFS_RAM_ENABLED
        }
-#endif // YAFFS_MTD_ENABLED
+#endif // CONFIG_YAFFS_MTD_ENABLED
 
        return error;
 }
@@ -876,12 +1123,10 @@ static void __exit exit_yaffs_fs(void)
 
     remove_proc_entry("yaffs",&proc_root);
     
-#ifdef YAFFS_RAM_ENABLED
-// NCB unregister_filesystem(&yaffs_fs_type);
+#ifdef CONFIG_YAFFS_RAM_ENABLED
        unregister_filesystem(&yaffs_ram_fs_type);
 #endif
-#ifdef YAFFS_MTD_ENABLED
-// NCB unregister_filesystem(&yaffs_ram_fs_type);
+#ifdef CONFIG_YAFFS_MTD_ENABLED
        unregister_filesystem(&yaffs_fs_type);
 #endif