linux 3.4 添加yaffs文件系统支持

本文提供了解决YAFFS文件系统在Linux 3.4内核中因API变更导致无法编译通过的方法,通过应用两个补丁即可解决问题。包括对yaffs_mtdif.c和yaffs_vfs.c文件的修改,涉及内存管理、块操作等关键部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

yaffs文件系统在3.4内核不能编译通过都是因为kernel api变化导致的。

顺序打这两个补丁就OK了。

patch 1

commit 0859182f495438901a29de7ebf186e69314503d6
Author: Leran0222 <leran0222@XXXXXXXX>
Date:   Tue Jul 17 20:03:50 2012 +0800

    Fix for YAFFS to work
    
    yaffs used some abandoned APIs

diff --git a/fs/yaffs2/yaffs_mtdif.c b/fs/yaffs2/yaffs_mtdif.c
index 7cf53b3..f6bf8e5 100644
--- a/fs/yaffs2/yaffs_mtdif.c
+++ b/fs/yaffs2/yaffs_mtdif.c
@@ -40,7 +40,7 @@ int nandmtd_erase_block(struct yaffs_dev *dev, int block_no)
     ei.callback = NULL;
     ei.priv = (u_long) dev;
 
-    retval = mtd->erase(mtd, &ei);
+    retval = mtd_erase(mtd, &ei);
 
     if (retval == 0)
         return YAFFS_OK;
diff --git a/fs/yaffs2/yaffs_mtdif1.c b/fs/yaffs2/yaffs_mtdif1.c
index 5108369..bac6d20 100644
--- a/fs/yaffs2/yaffs_mtdif1.c
+++ b/fs/yaffs2/yaffs_mtdif1.c
@@ -103,13 +103,13 @@ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
 #endif
 
     memset(&ops, 0, sizeof(ops));
-    ops.mode = MTD_OOB_AUTO;
+    ops.mode = MTD_OPS_AUTO_OOB;
     ops.len = (data) ? chunk_bytes : 0;
     ops.ooblen = YTAG1_SIZE;
     ops.datbuf = (u8 *) data;
     ops.oobbuf = (u8 *) & pt1;
 
-    retval = mtd->write_oob(mtd, addr, &ops);
+    retval = mtd_write_oob(mtd, addr, &ops);
     if (retval) {
         yaffs_trace(YAFFS_TRACE_MTD,
             "write_oob failed, chunk %d, mtd error %d",
@@ -156,7 +156,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
     int deleted;
 
     memset(&ops, 0, sizeof(ops));
-    ops.mode = MTD_OOB_AUTO;
+    ops.mode = MTD_OPS_AUTO_OOB;
     ops.len = (data) ? chunk_bytes : 0;
     ops.ooblen = YTAG1_SIZE;
     ops.datbuf = data;
@@ -165,7 +165,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
     /* Read page and oob using MTD.
      * Check status and determine ECC result.
      */
-    retval = mtd->read_oob(mtd, addr, &ops);
+    retval = mtd_read_oob(mtd, addr, &ops);
     if (retval) {
         yaffs_trace(YAFFS_TRACE_MTD,
             "read_oob failed, chunk %d, mtd error %d",
@@ -189,7 +189,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
         /* fall into... */
     default:
         rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0);
-        etags->block_bad = (mtd->block_isbad) (mtd, addr);
+        etags->block_bad = (mtd_block_isbad) (mtd, addr);
         return YAFFS_FAIL;
     }
 
@@ -257,7 +257,7 @@ int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no)
     yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
         "marking block %d bad", block_no);
 
-    retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no);
+    retval = mtd_block_markbad(mtd, (loff_t) blocksize * block_no);
     return (retval) ? YAFFS_FAIL : YAFFS_OK;
 }
 
@@ -307,7 +307,7 @@ int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
         return YAFFS_FAIL;
 
     retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
-    etags.block_bad = (mtd->block_isbad) (mtd, addr);
+    etags.block_bad = (mtd_block_isbad) (mtd, addr);
     if (etags.block_bad) {
         yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
             "block %d is marked bad", block_no);
diff --git a/fs/yaffs2/yaffs_mtdif2.c b/fs/yaffs2/yaffs_mtdif2.c
index d1643df..df69281 100644
--- a/fs/yaffs2/yaffs_mtdif2.c
+++ b/fs/yaffs2/yaffs_mtdif2.c
@@ -70,13 +70,13 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
         yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
         }
 
-    ops.mode = MTD_OOB_AUTO;
+    ops.mode = MTD_OPS_AUTO_OOB;
     ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
     ops.len = dev->param.total_bytes_per_chunk;
     ops.ooboffs = 0;
     ops.datbuf = (u8 *) data;
     ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
-    retval = mtd->write_oob(mtd, addr, &ops);
+    retval = mtd_write_oob(mtd, addr, &ops);
 
     if (retval == 0)
         return YAFFS_OK;
@@ -117,16 +117,16 @@ int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
     }
 
     if (dev->param.inband_tags || (data && !tags))
-        retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
+        retval = mtd_read(mtd, addr, dev->param.total_bytes_per_chunk,
                    &dummy, data);
     else if (tags) {
-        ops.mode = MTD_OOB_AUTO;
+        ops.mode = MTD_OPS_AUTO_OOB;
         ops.ooblen = packed_tags_size;
         ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
         ops.ooboffs = 0;
         ops.datbuf = data;
         ops.oobbuf = yaffs_dev_to_lc(dev)->spare_buffer;
-        retval = mtd->read_oob(mtd, addr, &ops);
+        retval = mtd_read_oob(mtd, addr, &ops);
     }
 
     if (dev->param.inband_tags) {
@@ -173,7 +173,7 @@ int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no)
         "nandmtd2_mark_block_bad %d", block_no);
 
     retval =
-        mtd->block_markbad(mtd,
+        mtd_block_markbad(mtd,
                    block_no * dev->param.chunks_per_block *
                    dev->param.total_bytes_per_chunk);
 
@@ -192,7 +192,7 @@ int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
 
     yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_query_block %d", block_no);
     retval =
-        mtd->block_isbad(mtd,
+        mtd_block_isbad(mtd,
                  block_no * dev->param.chunks_per_block *
                  dev->param.total_bytes_per_chunk);
 
diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index d5b8753..032a5ef 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -43,12 +43,14 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
+// ZYZ no longer exist
+// #include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/mtd/mtd.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
+#include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/exportfs.h>
 #include <linux/kthread.h>
@@ -314,7 +316,9 @@ static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
                    obj);
 
     if (link) {
-        old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+        // ZYZ, sind i_nlink is read-only, modify it by set_nlink
+        // old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+        set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
         d_instantiate(dentry, old_dentry->d_inode);
         atomic_inc(&old_dentry->d_inode->i_count);
         yaffs_trace(YAFFS_TRACE_OS,
@@ -429,7 +433,9 @@ static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
     ret_val = yaffs_unlinker(obj, dentry->d_name.name);
 
     if (ret_val == YAFFS_OK) {
-        dentry->d_inode->i_nlink--;
+        // ZYZ drop_nlink
+        // dentry->d_inode->i_nlink--;
+        drop_nlink(dentry->d_inode);
         dir->i_version++;
         yaffs_gross_unlock(dev);
         mark_inode_dirty(dentry->d_inode);
@@ -497,7 +503,9 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
     if (ret_val == YAFFS_OK) {
         if (target) {
-            new_dentry->d_inode->i_nlink--;
+            // ZYZ drop_nlink
+            // new_dentry->d_inode->i_nlink--;
+            drop_nlink(new_dentry->d_inode);
             mark_inode_dirty(new_dentry->d_inode);
         }
 
@@ -1917,7 +1925,9 @@ static void yaffs_fill_inode_from_obj(struct inode *inode,
         inode->i_size = yaffs_get_obj_length(obj);
         inode->i_blocks = (inode->i_size + 511) >> 9;
 
-        inode->i_nlink = yaffs_get_obj_link_count(obj);
+        // ZYZ set_nlink
+        // inode->i_nlink = yaffs_get_obj_link_count(obj);
+        set_nlink(inode, yaffs_get_obj_link_count(obj));
 
         yaffs_trace(YAFFS_TRACE_OS,
             "yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
@@ -1992,8 +2002,7 @@ static void yaffs_mtd_put_super(struct super_block *sb)
 {
     struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb));
 
-    if (mtd->sync)
-        mtd->sync(mtd);
+    mtd_sync(mtd);
 
     put_mtd_device(mtd);
 }
@@ -2094,13 +2103,13 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
         return NULL;
     }
 
-    yaffs_trace(YAFFS_TRACE_OS, " erase %p", mtd->erase);
-    yaffs_trace(YAFFS_TRACE_OS, " read %p", mtd->read);
-    yaffs_trace(YAFFS_TRACE_OS, " write %p", mtd->write);
-    yaffs_trace(YAFFS_TRACE_OS, " readoob %p", mtd->read_oob);
-    yaffs_trace(YAFFS_TRACE_OS, " writeoob %p", mtd->write_oob);
-    yaffs_trace(YAFFS_TRACE_OS, " block_isbad %p", mtd->block_isbad);
-    yaffs_trace(YAFFS_TRACE_OS, " block_markbad %p", mtd->block_markbad);
+    yaffs_trace(YAFFS_TRACE_OS, " erase %p", mtd->_erase);
+    yaffs_trace(YAFFS_TRACE_OS, " read %p", mtd->_read);
+    yaffs_trace(YAFFS_TRACE_OS, " write %p", mtd->_write);
+    yaffs_trace(YAFFS_TRACE_OS, " readoob %p", mtd->_read_oob);
+    yaffs_trace(YAFFS_TRACE_OS, " writeoob %p", mtd->_write_oob);
+    yaffs_trace(YAFFS_TRACE_OS, " block_isbad %p", mtd->_block_isbad);
+    yaffs_trace(YAFFS_TRACE_OS, " block_markbad %p", mtd->_block_markbad);
     yaffs_trace(YAFFS_TRACE_OS, " %s %d", WRITE_SIZE_STR, WRITE_SIZE(mtd));
     yaffs_trace(YAFFS_TRACE_OS, " oobsize %d", mtd->oobsize);
     yaffs_trace(YAFFS_TRACE_OS, " erasesize %d", mtd->erasesize);
@@ -2123,11 +2132,11 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
 
     if (yaffs_version == 2) {
         /* Check for version 2 style functions */
-        if (!mtd->erase ||
-            !mtd->block_isbad ||
-            !mtd->block_markbad ||
-            !mtd->read ||
-            !mtd->write || !mtd->read_oob || !mtd->write_oob) {
+        if (!mtd->_erase ||
+            !mtd->_block_isbad ||
+            !mtd->_block_markbad ||
+            !mtd->_read ||
+            !mtd->_write || !mtd->_read_oob || !mtd->_write_oob) {
             yaffs_trace(YAFFS_TRACE_ALWAYS,
                 "MTD device does not support required functions");
             return NULL;
@@ -2142,9 +2151,9 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
         }
     } else {
         /* Check for V1 style functions */
-        if (!mtd->erase ||
-            !mtd->read ||
-            !mtd->write || !mtd->read_oob || !mtd->write_oob) {
+        if (!mtd->_erase ||
+            !mtd->_read ||
+            !mtd->_write || !mtd->_read_oob || !mtd->_write_oob) {
             yaffs_trace(YAFFS_TRACE_ALWAYS,
                 "MTD device does not support required functions");
             return NULL;
@@ -2349,11 +2358,11 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
     inode->i_op = &yaffs_dir_inode_operations;
     inode->i_fop = &yaffs_dir_operations;
 
-    yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode");
+    yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got make inode");
 
-    root = d_alloc_root(inode);
+    root = (struct dentry *)d_make_root(inode);
 
-    yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: d_alloc_root done");
+    yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: d_make_root done");
 
     if (!root) {
         iput(inode);
@@ -2379,15 +2388,24 @@ static int yaffs_read_super(struct file_system_type *fs,
                 int flags, const char *dev_name,
                 void *data, struct vfsmount *mnt)
 {
-
+#if 0
     return get_sb_bdev(fs, flags, dev_name, data,
                yaffs_internal_read_super_mtd, mnt);
+#else
+    struct dentry *root;
+    root = mount_bdev(fs, flags, dev_name, data, yaffs_internal_read_super_mtd);
+    if (IS_ERR(root))
+        return PTR_ERR(root);
+    mnt->mnt_root = root;
+    mnt->mnt_sb = root->d_sb;
+    return 0;
+#endif
 }
 
 static struct file_system_type yaffs_fs_type = {
     .owner = THIS_MODULE,
     .name = "yaffs",
-    .get_sb = yaffs_read_super,
+    .mount = yaffs_read_super,
     .kill_sb = kill_block_super,
     .fs_flags = FS_REQUIRES_DEV,
 };
@@ -2404,14 +2422,24 @@ static int yaffs2_read_super(struct file_system_type *fs,
                  int flags, const char *dev_name, void *data,
                  struct vfsmount *mnt)
 {
+#if 0
     return get_sb_bdev(fs, flags, dev_name, data,
                yaffs2_internal_read_super_mtd, mnt);
+#else
+    struct dentry *root;
+    root = mount_bdev(fs, flags, dev_name, data, yaffs_internal_read_super_mtd);
+    if (IS_ERR(root))
+        return PTR_ERR(root);
+    mnt->mnt_root = root;
+    mnt->mnt_sb = root->d_sb;
+    return 0;
+#endif
 }
 
 static struct file_system_type yaffs2_fs_type = {
     .owner = THIS_MODULE,
     .name = "yaffs2",
-    .get_sb = yaffs2_read_super,
+    .mount = yaffs2_read_super,
     .kill_sb = kill_block_super,
     .fs_flags = FS_REQUIRES_DEV,
 };

 

 

============================================================================================================

patch 2

commit a89e9fec2be5d869368757379e604d03ce6e2fe7
Author: Leran0222 <leran0222@XXXXXXXX>
Date:   Wed Jul 18 20:34:19 2012 +0800

    Fix to make yaffs work, avoiding a NULL pointer

diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index 032a5ef..d434c5b 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -2388,9 +2388,9 @@ static int yaffs_read_super(struct file_system_type *fs,
                 int flags, const char *dev_name,
                 void *data, struct vfsmount *mnt)
 {
-#if 0
-    return get_sb_bdev(fs, flags, dev_name, data,
-               yaffs_internal_read_super_mtd, mnt);
+#if 1
+    return mount_bdev(fs, flags, dev_name, data,
+               yaffs_internal_read_super_mtd);
 #else
     struct dentry *root;
     root = mount_bdev(fs, flags, dev_name, data, yaffs_internal_read_super_mtd);
@@ -2422,9 +2422,9 @@ static int yaffs2_read_super(struct file_system_type *fs,
                  int flags, const char *dev_name, void *data,
                  struct vfsmount *mnt)
 {
-#if 0
-    return get_sb_bdev(fs, flags, dev_name, data,
-               yaffs2_internal_read_super_mtd, mnt);
+#if 1
+    return mount_bdev(fs, flags, dev_name, data,
+               yaffs2_internal_read_super_mtd);
 #else
     struct dentry *root;
     root = mount_bdev(fs, flags, dev_name, data, yaffs_internal_read_super_mtd);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值