[Yaffs] [PATCH] YAFFS2 to work with current MTD

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Vitaly Wool
Date:  
To: yaffs
Subject: [Yaffs] [PATCH] YAFFS2 to work with current MTD
Hi folks,

inlined is the patch that make YAFFS2 work for me with the Linus's git version of the MTD tree. Please note that I've made YAFFS2 structures smaller -- that's just because I wouldn't have succeeded otherwise, I have only 23 bytes spare OOB area out of 2k page.
Any comments/remarks are welcome.

Vitaly

Index: linux-2.6.git/fs/yaffs2/yaffs_ecc.h
===================================================================
--- linux-2.6.git.orig/fs/yaffs2/yaffs_ecc.h
+++ linux-2.6.git/fs/yaffs2/yaffs_ecc.h
@@ -26,10 +26,10 @@
#ifndef __YAFFS_ECC_H__
#define __YAFFS_ECC_H__

-typedef struct {
+typedef struct __attribute__((packed)) {
     unsigned char colParity;
-    unsigned lineParity;
-    unsigned lineParityPrime;
+    unsigned short lineParity;
+    unsigned short lineParityPrime;
 } yaffs_ECCOther;


 void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc);
Index: linux-2.6.git/fs/yaffs2/yaffs_fs.c
===================================================================
--- linux-2.6.git.orig/fs/yaffs2/yaffs_fs.c
+++ linux-2.6.git/fs/yaffs2/yaffs_fs.c
@@ -103,7 +103,7 @@ static void yaffs_put_super(struct super
 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, fl_owner_t id);

 static int yaffs_sync_object(struct file *file, struct dentry *dentry,
                  int datasync);
@@ -137,10 +137,12 @@ static int yaffs_rename(struct inode *ol
             struct inode *new_dir, struct dentry *new_dentry);
 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);


-static int yaffs_sync_fs(struct super_block *sb);
-static int yaffs_write_super(struct super_block *sb);
+static int yaffs_sync_fs(struct super_block *sb, int wait);
+static void yaffs_write_super(struct super_block *sb);

-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16))
+static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf);
+#elif (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);
@@ -438,7 +440,7 @@ static void yaffs_delete_inode(struct in
     clear_inode(inode);
 }


-static int yaffs_file_flush(struct file *file)
+static int yaffs_file_flush(struct file *file, fl_owner_t id)
 {
     yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry);


@@ -1223,14 +1225,21 @@ static int yaffs_setattr(struct dentry *
     return error;
 }


-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16))
+static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+    yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
+    struct super_block *sb = dentry->d_sb;
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
+{
+    yaffs_Device *dev = yaffs_SuperToDevice(sb);
 #else
 static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
-#endif
 {
-
     yaffs_Device *dev = yaffs_SuperToDevice(sb);
+#endif
+
     T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n"));


     yaffs_GrossLock(dev);
@@ -1287,16 +1296,14 @@ static int yaffs_do_sync_fs(struct super
 }



-static int yaffs_write_super(struct super_block *sb)
+static void yaffs_write_super(struct super_block *sb)
{

     T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n"));
-    return 0; /* yaffs_do_sync_fs(sb);*/
-    
 }



-static int yaffs_sync_fs(struct super_block *sb)
+static int yaffs_sync_fs(struct super_block *sb, int wait)
{

     T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n"));
@@ -1452,7 +1459,7 @@ static struct super_block *yaffs_interna
     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, (" eccsize %d\n", mtd->eccsize));
     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));
@@ -1460,14 +1467,14 @@ static struct super_block *yaffs_interna
 #ifdef CONFIG_YAFFS_AUTO_YAFFS2


     if (yaffsVersion == 1 && 
-        mtd->oobblock >= 2048) {
+        mtd->writesize >= 2048) {
         T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n"));
         yaffsVersion = 2;
     }    

    
     /* Added NCB 26/5/2006 for completeness */
     if (yaffsVersion == 2 && 
-        mtd->oobblock == 512) {
+        mtd->writesize == 512) {
         T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n"));
         yaffsVersion = 1;
     }    
@@ -1481,15 +1488,14 @@ static struct super_block *yaffs_interna
             !mtd->block_markbad ||
             !mtd->read ||
             !mtd->write ||
-            !mtd->write_ecc ||
-            !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
+            !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 ||
+        if (mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
             mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) {
             T(YAFFS_TRACE_ALWAYS,
               ("yaffs: MTD device does not have the "
@@ -1501,15 +1507,14 @@ static struct super_block *yaffs_interna
         if (!mtd->erase ||
             !mtd->read ||
             !mtd->write ||
-            !mtd->write_ecc ||
-            !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
+            !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 ||
+        if (mtd->writesize != YAFFS_BYTES_PER_CHUNK ||
             mtd->oobsize != YAFFS_BYTES_PER_SPARE) {
             T(YAFFS_TRACE_ALWAYS,
               ("yaffs: MTD device does not support have the "
@@ -1560,8 +1565,8 @@ static struct super_block *yaffs_interna
         dev->queryNANDBlock = nandmtd2_QueryNANDBlock;
         dev->spareBuffer = YMALLOC(mtd->oobsize);
         dev->isYaffs2 = 1;
-        dev->nBytesPerChunk = mtd->oobblock;
-        dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
+        dev->nBytesPerChunk = mtd->writesize;
+        dev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
         nBlocks = mtd->size / mtd->erasesize;


         dev->nCheckpointReservedBlocks = 10;
@@ -1641,6 +1646,16 @@ static int yaffs_internal_read_super_mtd
     return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
 }


+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16))
+static int yaffs_read_super(struct file_system_type *fs,
+                int flags, const char *dev_name,
+                void *data, struct vfsmount *mnt)
+{
+
+    return get_sb_bdev(fs, flags, dev_name, data,
+               yaffs_internal_read_super_mtd, mnt);
+}
+#else
 static struct super_block *yaffs_read_super(struct file_system_type *fs,
                         int flags, const char *dev_name,
                         void *data)
@@ -1649,6 +1664,7 @@ static struct super_block *yaffs_read_su
     return get_sb_bdev(fs, flags, dev_name, data,
                yaffs_internal_read_super_mtd);
 }
+#endif


 static struct file_system_type yaffs_fs_type = {
     .owner = THIS_MODULE,
@@ -1678,6 +1694,15 @@ static int yaffs2_internal_read_super_mt
     return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
 }


+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16))
+static int yaffs2_read_super(struct file_system_type *fs,
+            int flags, const char *dev_name, void *data,
+            struct vfsmount *mnt)
+{
+    return get_sb_bdev(fs, flags, dev_name, data,
+            yaffs2_internal_read_super_mtd, mnt);
+}
+#else
 static struct super_block *yaffs2_read_super(struct file_system_type *fs,
                          int flags, const char *dev_name,
                          void *data)
@@ -1686,6 +1711,7 @@ static struct super_block *yaffs2_read_s
     return get_sb_bdev(fs, flags, dev_name, data,
                yaffs2_internal_read_super_mtd);
 }
+#endif


 static struct file_system_type yaffs2_fs_type = {
     .owner = THIS_MODULE,
Index: linux-2.6.git/fs/yaffs2/yaffs_mtdif.c
===================================================================
--- linux-2.6.git.orig/fs/yaffs2/yaffs_mtdif.c
+++ linux-2.6.git/fs/yaffs2/yaffs_mtdif.c
@@ -26,20 +26,11 @@ const char *yaffs_mtdif_c_version =
 #include "linux/time.h"
 #include "linux/mtd/nand.h"


-static struct nand_oobinfo yaffs_oobinfo = {
-    .useecc = 1,
-    .eccbytes = 6,
-    .eccpos = {8, 9, 10, 13, 14, 15}
-};
-
-static struct nand_oobinfo yaffs_noeccinfo = {
-    .useecc = 0,
-};
-
 int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
                  const __u8 * data, const yaffs_Spare * spare)
 {
     struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+    struct mtd_oob_ops ops;
     size_t dummy;
     int retval = 0;


@@ -47,26 +38,21 @@ int nandmtd_WriteChunkToNAND(yaffs_Devic

     __u8 *spareAsBytes = (__u8 *) spare;


-    if (data && spare) {
+    if (data)
+        retval = mtd->write(mtd, addr, dev->nBytesPerChunk,
+                &dummy, data);
+
+    if (spare) {
         if (dev->useNANDECC)
-            retval =
-                mtd->write_ecc(mtd, addr, dev->nBytesPerChunk,
-                       &dummy, data, spareAsBytes,
-                       &yaffs_oobinfo);
+            ops.mode = MTD_OOB_AUTO;
         else
-            retval =
-                mtd->write_ecc(mtd, addr, dev->nBytesPerChunk,
-                       &dummy, data, spareAsBytes,
-                       &yaffs_noeccinfo);
-    } else {
-        if (data)
-            retval =
-                mtd->write(mtd, addr, dev->nBytesPerChunk, &dummy,
-                       data);
-        if (spare)
-            retval =
-                mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
-                       &dummy, spareAsBytes);
+            ops.mode = MTD_OOB_RAW;
+        ops.len = YAFFS_BYTES_PER_SPARE;
+        ops.ooblen = YAFFS_BYTES_PER_SPARE;
+        ops.datbuf = NULL;
+        ops.ooboffs = 0;
+        ops.oobbuf = spareAsBytes;
+        retval = mtd->write_oob(mtd, addr, &ops);
     }


     if (retval == 0)
@@ -79,6 +65,7 @@ int nandmtd_ReadChunkFromNAND(yaffs_Devi
                   yaffs_Spare * spare)
 {
     struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+    struct mtd_oob_ops ops;
     size_t dummy;
     int retval = 0;


@@ -86,31 +73,21 @@ int nandmtd_ReadChunkFromNAND(yaffs_Devi

     __u8 *spareAsBytes = (__u8 *) spare;


-    if (data && spare) {
-        if (dev->useNANDECC) {    
-            /* Careful, this call adds 2 ints */
-            /* to the end of the spare data.  Calling function */
-            /* should allocate enough memory for spare, */
-            /* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */
-            retval =
-                mtd->read_ecc(mtd, addr, dev->nBytesPerChunk,
-                      &dummy, data, spareAsBytes,
-                      &yaffs_oobinfo);
-        } else {
-            retval =
-                mtd->read_ecc(mtd, addr, dev->nBytesPerChunk,
-                      &dummy, data, spareAsBytes,
-                      &yaffs_noeccinfo);
-        }
-    } else {
-        if (data)
-            retval =
-                mtd->read(mtd, addr, dev->nBytesPerChunk, &dummy,
-                      data);
-        if (spare)
-            retval =
-                mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
-                      &dummy, spareAsBytes);
+    if (data)
+        retval = mtd->read(mtd, addr, dev->nBytesPerChunk, &dummy,
+                data);
+
+    if (spare) {
+        if (dev->useNANDECC)
+            ops.mode = MTD_OOB_AUTO;
+        else
+            ops.mode = MTD_OOB_RAW;
+        ops.len = YAFFS_BYTES_PER_SPARE;
+        ops.ooblen = YAFFS_BYTES_PER_SPARE;
+        ops.datbuf = NULL;
+        ops.ooboffs = 0;
+        ops.oobbuf = spareAsBytes;
+        retval = mtd->read_oob(mtd, addr, &ops);
     }


     if (retval == 0)
Index: linux-2.6.git/fs/yaffs2/yaffs_mtdif2.c
===================================================================
--- linux-2.6.git.orig/fs/yaffs2/yaffs_mtdif2.c
+++ linux-2.6.git/fs/yaffs2/yaffs_mtdif2.c
@@ -34,6 +34,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
                       const yaffs_ExtendedTags * tags)
 {
     struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+    struct mtd_oob_ops ops;
     size_t dummy;
     int retval = 0;


@@ -50,25 +51,24 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
         yaffs_PackTags2(&pt, tags);
     }


-    if (data && tags) {
-        if (dev->useNANDECC)
-            retval =
-                mtd->write_ecc(mtd, addr, dev->nBytesPerChunk,
-                       &dummy, data, (__u8 *) & pt, NULL);
-        else
-            retval =
-                mtd->write_ecc(mtd, addr, dev->nBytesPerChunk,
-                       &dummy, data, (__u8 *) & pt, NULL);
-    } else {
-        if (data)
-            retval =
-                mtd->write(mtd, addr, dev->nBytesPerChunk, &dummy,
-                       data);
-        if (tags)
-            retval =
-                mtd->write_oob(mtd, addr, mtd->oobsize, &dummy,
-                       (__u8 *) & pt);
+    if (data)
+        retval = mtd->write(mtd, addr, dev->nBytesPerChunk,
+                &dummy, data);


+    if (tags) {
+        if (dev->useNANDECC) {
+            ops.mode = MTD_OOB_AUTO;
+            ops.len = sizeof(pt);
+            ops.ooblen = sizeof(pt);
+        } else {
+            ops.mode = MTD_OOB_RAW;
+            ops.len = mtd->oobsize;
+            ops.ooblen = mtd->oobsize;
+        }
+        ops.ooboffs = 0;
+        ops.datbuf = NULL;
+        ops.oobbuf = (void *)&pt;
+        retval = mtd->write_oob(mtd, addr, &ops);
     }


     if (retval == 0)
@@ -81,6 +81,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
                        __u8 * data, yaffs_ExtendedTags * tags)
 {
     struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+    struct mtd_oob_ops ops;
     size_t dummy;
     int retval = 0;


@@ -93,27 +94,24 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
        ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
         TENDSTR), chunkInNAND, data, tags));


-    if (data && tags) {
+    if (data)
+        retval = mtd->read(mtd, addr, dev->nBytesPerChunk,
+                &dummy, data);
+
+    if (tags) {
         if (dev->useNANDECC) {
-            retval =
-                mtd->read_ecc(mtd, addr, dev->nBytesPerChunk,
-                      &dummy, data, dev->spareBuffer,
-                      NULL);
+            ops.mode = MTD_OOB_AUTO;
+            ops.ooblen = sizeof(pt);
+            ops.len = sizeof(pt);
         } else {
-            retval =
-                mtd->read_ecc(mtd, addr, dev->nBytesPerChunk,
-                      &dummy, data, dev->spareBuffer,
-                      NULL);
+            ops.mode = MTD_OOB_RAW;
+            ops.ooblen = mtd->oobsize;
+            ops.len = mtd->oobsize;
         }
-    } else {
-        if (data)
-            retval =
-                mtd->read(mtd, addr, dev->nBytesPerChunk, &dummy,
-                      data);
-        if (tags)
-            retval =
-                mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
-                      dev->spareBuffer);
+        ops.ooboffs = 0;
+        ops.datbuf = NULL;
+        ops.oobbuf = dev->spareBuffer;
+        retval = mtd->read_oob(mtd, addr, &ops);
     }


     memcpy(&pt, dev->spareBuffer, sizeof(pt));
Index: linux-2.6.git/fs/yaffs2/yaffs_packedtags2.h
===================================================================
--- linux-2.6.git.orig/fs/yaffs2/yaffs_packedtags2.h
+++ linux-2.6.git/fs/yaffs2/yaffs_packedtags2.h
@@ -6,14 +6,14 @@
 #include "yaffs_guts.h"
 #include "yaffs_ecc.h"


-typedef struct {
+typedef struct __attribute__((packed)) {
     unsigned sequenceNumber;
-    unsigned objectId;
-    unsigned chunkId;
+    unsigned short objectId;
+    unsigned short chunkId;
     unsigned byteCount;
 } yaffs_PackedTags2TagsPart;


-typedef struct {
+typedef struct __attribute__((packed)) {
     yaffs_PackedTags2TagsPart t;
     yaffs_ECCOther ecc;
 } yaffs_PackedTags2;