*** empty log message ***
authorcharles <charles>
Tue, 20 Aug 2002 23:59:44 +0000 (23:59 +0000)
committercharles <charles>
Tue, 20 Aug 2002 23:59:44 +0000 (23:59 +0000)
Makefile
yaffs_fs.c

index c8731295c701aa1daadccf9be291ff02c49a3775..ceea8f7c1b58a4f439bf9296120ba38b48a79afb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -18,9 +18,9 @@
 KERNELDIR = /usr/src/kernel-headers-2.4.18
 USE_RAM_FOR_TEST = -DYAFFS_RAM_ENABLED
 USE_MTD = -DYAFFS_MTD_ENABLED
+YAFFS_CONFIGS = -DCONFIG_YAFFS_USE_GENERIC_RW
 
-
-CFLAGS = -D__KERNEL__ -DMODULE $(USE_RAM_FOR_TEST) $(USE_MTD)  -I$(KERNELDIR)/include -O2 -Wall
+CFLAGS = -D__KERNEL__ -DMODULE $(USE_RAM_FOR_TEST) $(USE_MTD) $(YAFFS_CONFIGS)  -I$(KERNELDIR)/include -O2 -Wall
 
 
 OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o nand_ecc.o
index 1a9460e85c10545e71caaf23024058bb4e408b06..8bea30d64da5090206be08bca0b13668efa8f90f 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 O_APPEND patch.
+ * * Nick Bane for patches marked NCB.
+ * * Some code bodily lifted from JFFS2.
  */
 
 
@@ -85,6 +91,8 @@ static struct super_block *yaffs_read_super(struct super_block * sb, void * data
 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);
@@ -94,15 +102,20 @@ static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
 
 
 static struct address_space_operations yaffs_file_address_operations = {
-       readpage:               yaffs_readpage,
-//     prepare_write:  yaffs_prepare_write,
-//     commit_write:   yaffs_commit_write
+       readpage:       yaffs_readpage,
+       prepare_write:  yaffs_prepare_write,
+       commit_write:   yaffs_commit_write
 };
 
 
 static struct file_operations yaffs_file_operations = {
+#if CONFIG_YAFFS_USE_GENERIC_RW
+       read:           generic_file_read,
+       write:          generic_file_write,
+#else
        read:           yaffs_file_read,
        write:          yaffs_file_write,
+#endif
        mmap:           generic_file_mmap,
        fsync:          yaffs_sync_object,
 };
@@ -236,8 +249,10 @@ static void yaffs_put_inode(struct inode *inode)
 
 
 
-static int yaffs_readpage(struct file *f, struct page * pg)
+static int yaffs_readpage_nolock(struct file *f, struct page * pg)
 {
+       // Lifted from jffs2
+       
        yaffs_Object *obj;
        unsigned char *pg_buf;  
        int ret;
@@ -270,7 +285,7 @@ static int yaffs_readpage(struct file *f, struct page * pg)
        flush_dcache_page(pg);
        kunmap(pg);
 
-       UnlockPage(pg);
+
 
        //up(&obj->sem);
 
@@ -278,28 +293,58 @@ static int yaffs_readpage(struct file *f, struct page * pg)
        return ret;
 }
 
-#ifdef YAFFS_ADDRESS_OPS
+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_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+static int yaffs_readpage(struct file *f, struct page * pg)
 {
-       T((KERN_DEBUG"yaffs_prepare_write\n"));
+       return yaffs_readpage_unlock(f,pg);
+}
+
+
+static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to)
+{
+
+       T((KERN_DEBUG"yaffs_prepair_write\n"));
+       if(!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
+               return  yaffs_readpage_nolock(f,pg);    
 
-       //TODO
        return 0;
+       
 }
 
-static int yaffs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to)
 {
 
-       struct inode *inode = page->mapping->host;
-       loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + 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);
+       }
 
-       T((KERN_DEBUG"yaffs_commit_write\n"));
+       T((KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten));
+       
+       return nWritten /* != nBytes ? -ENOMEM : 0 */ ;
 
-       return 0;
 }
 
-#endif //YAFFS_ADDRESS_OPS
 
 
 static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
@@ -310,7 +355,7 @@ 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 = obj->st_rdev;;
                inode->i_atime = obj->st_atime;
@@ -408,17 +453,39 @@ 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));
                }
                
        }
@@ -711,12 +778,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 = buf->f_bfree = 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;
 }
 
@@ -767,10 +837,6 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
        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;
        
@@ -784,6 +850,16 @@ 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));
 
        
+
+#if 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));
+
        
        if(useRam)
        {
@@ -974,6 +1050,13 @@ static int __init init_yaffs_fs(void)
        int error = 0;
        
        printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n");
+#if 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,