yaffs2移植到内核linux-4.4.16的修改记录

yaffs2更新的比较慢,跟不上内核的更新速度.所以只能自己做些修改

first step

刚开始从官网下载下来的直接打补丁后会出现一系列的错误.如下:

**fs/yaffs2/yaffs_vfs.c: In function 'yaffs_readpage_nolock':
fs/yaffs2/yaffs_vfs.c:286:34: error: 'struct file' has no member named 'f_dentry'
  obj = yaffs_dentry_to_obj(f->f_dentry);
                                  ^
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_hold_space':
fs/yaffs2/yaffs_vfs.c:484:34: error: 'struct file' has no member named 'f_dentry'
  obj = yaffs_dentry_to_obj(f->f_dentry);
                                  ^
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_release_space':
fs/yaffs2/yaffs_vfs.c:502:34: error: 'struct file' has no member named 'f_dentry'
  obj = yaffs_dentry_to_obj(f->f_dentry);
                                  ^
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_file_write':
fs/yaffs2/yaffs_vfs.c:594:34: error: 'struct file' has no member named 'f_dentry'
  obj = yaffs_dentry_to_obj(f->f_dentry);
                                  ^
fs/yaffs2/yaffs_vfs.c:606:11: error: 'struct file' has no member named 'f_dentry'
  inode = f->f_dentry->d_inode;
           ^
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_file_flush':
fs/yaffs2/yaffs_vfs.c:730:55: error: 'struct file' has no member named 'f_dentry'
  struct yaffs_obj *obj = yaffs_dentry_to_obj(file->f_dentry);


         ^
fs/yaffs2/yaffs_vfs.c: At top level:
fs/yaffs2/yaffs_vfs.c:780:10: error: 'new_sync_read' undeclared here (not in a function)
  .read = new_sync_read,
          ^
fs/yaffs2/yaffs_vfs.c:781:11: error: 'new_sync_write' undeclared here (not in a function)
  .write = new_sync_write,
           ^
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_follow_link':
fs/yaffs2/yaffs_vfs.c:1078:2: error: implicit declaration of function 'nd_set_link' [-Werror=implicit-function-declaration]
  nd_set_link(nd, alias);
  ^
fs/yaffs2/yaffs_vfs.c: At top level:
fs/yaffs2/yaffs_vfs.c:1118:17: warning: initialization from incompatible pointer type
  .follow_link = yaffs_follow_link,
                 ^
fs/yaffs2/yaffs_vfs.c:1118:17: warning: (near initialization for 'yaffs_symlink_inode_operations.follow_link')
fs/yaffs2/yaffs_vfs.c:1120:14: warning: initialization from incompatible pointer type
  .put_link = yaffs_put_link,
              ^
fs/yaffs2/yaffs_vfs.c:1120:14: warning: (near initialization for 'yaffs_symlink_inode_operations.put_link')
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_iterate':
fs/yaffs2/yaffs_vfs.c:1730:34: error: 'struct file' has no member named 'f_dentry'
  obj = yaffs_dentry_to_obj(f->f_dentry);
                                  ^
cc1: some warnings being treated as errors
make[4]: *** [fs/yaffs2/yaffs_vfs.o] Error 1
make[3]: *** [fs/yaffs2] Error 2
make[2]: *** [fs] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/.stamp_built] Error 2
make: *** [_all] Error 2**

上面有三个问题要解决

  • 1: error: ‘struct file’ has no member named ‘f_dentry’
  • 2: error: ‘new_sync_read/write’ undeclared here
  • 3: error: implicit declaration of function ‘nd_set_link’

1 ‘struct file’ has no member named ‘f_dentry’

第一个是由于新内核的file结构体发生了变化,把dentry这个成员放到了path结构体里,这里只要更改下就行.

struct file {
    union {
        struct llist_node   fu_llist;
        struct rcu_head     fu_rcuhead;
    } f_u;
    struct path     f_path;
struct path {
    struct vfsmount *mnt;
    struct dentry *dentry;
};

直接在yaffs_vfs.c里加上下列定义就行,或者全部替换

#define f_dentry f_path.dentry
#define f_vfsmnt f_path.mnt

2 ‘new_sync_read/write’ undeclared here

对于第2个问题是由于新内核没有”new_sync_read/write”这两个导出函数了,改成

    .read = __vfs_read,//new_sync_read
    .write = __vfs_write,  //new_sync_write

linux官网查询发现4.4.16内核里已经不用nd_set_link这个函数了,
因此要修改用到这个函数的地方.主要就是yaffs_follow_link这个函数啦,yaffs_follow_link的定义主要参考你的include/linux/fs.h里的struct inode_operations.follow_link来定义.
以前的alias是保存在 nd->saved_names里,现在这个成员已经被删除了,直接通过函数返回值返回,并且保存在*cookie中

@@ -1053,7 +1062,11 @@
 }

 #if (YAFFS_NEW_FOLLOW_LINK == 1)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 16)
 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
+#else
+static const char *yaffs_follow_link(struct dentry *dentry,void **cookie)
+#endif
 {
    void *ret;
 #else
@@ -1075,7 +1088,11 @@
        goto out;
    }
 #if (YAFFS_NEW_FOLLOW_LINK == 1)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 16)
    nd_set_link(nd, alias);
+#else
+   *cookie = alias;
+#endif
    ret = alias;
 out:
    if (ret_int)
@@ -1107,10 +1124,17 @@
 #endif

 #if (YAFFS_NEW_FOLLOW_LINK == 1)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 16)
 void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias)
 {
    kfree(alias);
 }
+#else
+void yaffs_put_link(struct inode *inode,void *alias)
+{
+   kfree(alias);
+}
+#endif
 #endif

 static const struct inode_operations yaffs_symlink_inode_operations = {  

second step

以上修改完后在编译时还会出现下列的错误:

In file included from fs/yaffs2/yaffs_nameval.c:28:0:
fs/yaffs2/yaffs_nameval.h:21:21: warning: 'struct yaffs_dev' declared inside parameter list
 int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR * name);
                     ^
fs/yaffs2/yaffs_nameval.h:21:21: warning: its scope is only this definition or declaration, which is probably not what you want
fs/yaffs2/yaffs_nameval.h:24:7: warning: 'struct yaffs_dev' declared inside parameter list
       int bsize, int flags);
       ^
fs/yaffs2/yaffs_nameval.h:27:7: warning: 'struct yaffs_dev' declared inside parameter list
       int bsize);
       ^
fs/yaffs2/yaffs_nameval.h:29:8: warning: 'struct yaffs_dev' declared inside parameter list
        const char *xb, int xb_size, char *buf, int bsize);
        ^
fs/yaffs2/yaffs_nameval.h:30:27: warning: 'struct yaffs_dev' declared inside parameter list
 int nval_hasvalues(struct yaffs_dev *dev, const char *xb, int xb_size);
                           ^
fs/yaffs2/yaffs_nameval.c:82:5: error: conflicting types for 'nval_del'
 int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR *name)
     ^
In file included from fs/yaffs2/yaffs_nameval.c:28:0:
fs/yaffs2/yaffs_nameval.h:21:5: note: previous declaration of 'nval_del' was here
 int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR * name);
     ^
fs/yaffs2/yaffs_nameval.c:100:5: error: conflicting types for 'nval_set'
 int nval_set(struct yaffs_dev *dev,
     ^
In file included from fs/yaffs2/yaffs_nameval.c:28:0:
fs/yaffs2/yaffs_nameval.h:22:5: note: previous declaration of 'nval_set' was here
 int nval_set(struct yaffs_dev *dev,
     ^
fs/yaffs2/yaffs_nameval.c:145:5: error: conflicting types for 'nval_get'
 int nval_get(struct yaffs_dev *dev,
     ^
In file included from fs/yaffs2/yaffs_nameval.c:28:0:
fs/yaffs2/yaffs_nameval.h:25:5: note: previous declaration of 'nval_get' was here
 int nval_get(struct yaffs_dev *dev,
     ^
fs/yaffs2/yaffs_nameval.c:185:5: error: conflicting types for 'nval_list'
 int nval_list(struct yaffs_dev *dev, const char *xb, int xb_size, char *buf, int bsize)
     ^
In file included from fs/yaffs2/yaffs_nameval.c:28:0:
fs/yaffs2/yaffs_nameval.h:28:5: note: previous declaration of 'nval_list' was here
 int nval_list(struct yaffs_dev *dev,
     ^
fs/yaffs2/yaffs_nameval.c:227:5: error: conflicting types for 'nval_hasvalues'
 int nval_hasvalues(struct yaffs_dev *dev, const char *xb, int xb_size)
     ^
In file included from fs/yaffs2/yaffs_nameval.c:28:0:
fs/yaffs2/yaffs_nameval.h:30:5: note: previous declaration of 'nval_hasvalues' was here
 int nval_hasvalues(struct yaffs_dev *dev, const char *xb, int xb_size);
     ^
make[4]: *** [fs/yaffs2/yaffs_nameval.o] Error 1
make[3]: *** [fs/yaffs2] Error 2
make[2]: *** [fs] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/.stamp_built] Error 2
make: *** [_all] Error 2

解释:error: conflicting types for ‘nval_del’,查看nval_del几个函数,这里我看不出有什么类型冲突错误,网上搜了下主要是第一个WARNING那里引起的.
在yaffs_nameval.h中,结构体struct yaffs_dev的定义出现在参数列表中,而在此之前没有定义,这样会导致函数不识别这个结构体引发上面的错误,查询了下struct yaffs_dev在”yaffs_guts.h”中被定义,因此在yaffs_nameval.h文件中include下”yaffs_guts.h”就OK了

third step

通过上两个修改后可能还会遇到下面的两个错误:

error: unknown type name ‘Y_LOFF_T’

In file included from fs/yaffs2/yaffs_guts.c:18:0:
fs/yaffs2/yaffs_endian.h:32:86: error: unknown type name 'Y_LOFF_T'
 static inline Y_LOFF_T swap_loff_t(Y_LOFF_T lval)
                                                                                      ^
fs/yaffs2/yaffs_endian.h:32:107: error: unknown type name 'Y_LOFF_T'
 static inline Y_LOFF_T swap_loff_t(Y_LOFF_T lval)
                                                                                                           ^
make[4]: *** [fs/yaffs2/yaffs_guts.o] Error 1
make[3]: *** [fs/yaffs2] Error 2
make[2]: *** [fs] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/.stamp_built] Error 2
make: *** [_all] Error 2

这个好解决,在yaffs_endian.h中加上如下定义:

#ifndef Y_LOFF_T
#define Y_LOFF_T loff_t               
#endif

yaffs_guts.c:line: undefined reference to function

fs/built-in.o: In function `yaffs_check_obj_details_loaded':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:3254: undefined reference to `yaffs_do_endian_oh'
fs/built-in.o: In function `yaffs_oh_size_load':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:5165: undefined reference to `yaffs_do_endian_u32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:5166: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs_update_oh':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:3401: undefined reference to `yaffs_do_endian_oh'
fs/built-in.o: In function `yaffs_guts_initialise':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:4912: undefined reference to `yaffs_endian_config'
fs/built-in.o: In function `yaffs_oh_size_load':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:5165: undefined reference to `yaffs_do_endian_u32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:5166: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs_oh_to_size':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:5181: undefined reference to `yaffs_do_endian_u32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:5182: undefined reference to `yaffs_do_endian_u32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_guts.c:5190: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs_pack_tags2_tags_only':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_packedtags2.c:111: undefined reference to `yaffs_do_endian_packed_tags2'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_packedtags2.c:111: undefined reference to `yaffs_do_endian_packed_tags2'
fs/built-in.o: In function `yaffs_unpack_tags2_tags_only':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_packedtags2.c:137: undefined reference to `yaffs_do_endian_packed_tags2'
fs/built-in.o: In function `yaffs_load_tags_to_spare':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_tagscompat.c:92: undefined reference to `yaffs_do_endian_u32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_tagscompat.c:93: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs_get_tags_from_spare':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_tagscompat.c:122: undefined reference to `yaffs_do_endian_u32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_tagscompat.c:123: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `nval_used':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_nameval.c:69: undefined reference to `yaffs_do_endian_s32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_nameval.c:75: undefined reference to `yaffs_do_endian_s32'
fs/built-in.o: In function `nval_find':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_nameval.c:41: undefined reference to `yaffs_do_endian_s32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_nameval.c:53: undefined reference to `yaffs_do_endian_s32'
fs/built-in.o: In function `nval_del':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_nameval.c:93: undefined reference to `yaffs_do_endian_s32'
fs/built-in.o:/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_nameval.c:136: more undefined references to `yaffs_do_endian_s32' follow
fs/built-in.o: In function `yaffs2_checkpt_tnode_worker':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_yaffs2.c:599: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs2_wr_checkpt_sum':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_yaffs2.c:811: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs2_rd_checkpt_tnodes':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_yaffs2.c:647: undefined reference to `yaffs_do_endian_u32'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_yaffs2.c:671: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs2_rd_checkpt_sum':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_yaffs2.c:835: undefined reference to `yaffs_do_endian_u32'
fs/built-in.o: In function `yaffs2_scan_chunk':
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_yaffs2.c:1302: undefined reference to `yaffs_do_endian_oh'
/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/fs/yaffs2/yaffs_yaffs2.c:1302: undefined reference to `yaffs_do_endian_oh'
make[2]: *** [vmlinux] Error 1
make[1]: *** [/home/anzyelay/Downloads/buildroot-2016.05/output/build/linux-4.4.16/.stamp_built] Error 2
make: *** [_all] Error 2
anzyelay@ubuntu:buildroot-2016.05$ 

这个看了下明明这些函数都有定义有实现怎么就是不识别呢??头文件这些也包函了,网上找了下说编译器没有编译到譔文件可有导致其它函数引用时无法识别,我看了下编译情况, 其它的.c文件都编译成.o了,然后打开Makefile一看果然没有加进来,yaffs真的不省心,在Makefile.kernel里增加如下 :

yaffs-y += yaffs_endian.o

这回万恶的错误都没了吧.编译后是OK的了,至于启动后有没有其它原因导致的错误就不得而知了.


yaffs的补丁文件如下:

diff -Nur yaffs2/Makefile.kernel yaffs2.anzyelay/Makefile.kernel
--- yaffs2/Makefile.kernel  2016-07-29 14:01:01.778572877 +0800
+++ yaffs2.anzyelay/Makefile.kernel 2016-08-03 10:29:07.361276458 +0800
@@ -15,4 +15,5 @@
 yaffs-y += yaffs_bitmap.o
 yaffs-y += yaffs_summary.o
 yaffs-y += yaffs_verify.o
+yaffs-y += yaffs_endian.o

diff -Nur yaffs2/yaffs_endian.h yaffs2.anzyelay/yaffs_endian.h
--- yaffs2/yaffs_endian.h   2016-07-29 14:01:01.814572879 +0800
+++ yaffs2.anzyelay/yaffs_endian.h  2016-08-03 11:18:12.633411085 +0800
@@ -29,6 +29,9 @@
 #define swap_s32(val) \
    (s32)(swap_u32((u32)(val)))

+#ifndef Y_LOFF_T
+#define Y_LOFF_T loff_t                                                                         
+#endif
 static inline Y_LOFF_T swap_loff_t(Y_LOFF_T lval)
 {
    u32 vall = swap_u32((u32) (lval & 0xffffffff));
diff -Nur yaffs2/yaffs_nameval.h yaffs2.anzyelay/yaffs_nameval.h
--- yaffs2/yaffs_nameval.h  2016-07-29 14:01:01.818572879 +0800
+++ yaffs2.anzyelay/yaffs_nameval.h 2016-08-03 11:22:07.409421602 +0800
@@ -17,6 +17,7 @@
 #define __NAMEVAL_H__

 #include "yportenv.h"
+#include "yaffs_guts.h"

 int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR * name);
 int nval_set(struct yaffs_dev *dev,
diff -Nur yaffs2/yaffs_vfs_multi.c yaffs2.anzyelay/yaffs_vfs_multi.c
--- yaffs2/yaffs_vfs_multi.c    2016-07-29 14:01:01.818572879 +0800
+++ yaffs2.anzyelay/yaffs_vfs_multi.c   2016-08-03 11:06:42.877379435 +0800
@@ -76,6 +76,10 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fs.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 16))
+#define f_dentry f_path.dentry
+#define f_vfsmnt f_path.mnt
+#endif
 #include <linux/proc_fs.h>
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
 #include <linux/smp_lock.h>
@@ -777,8 +781,13 @@
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
 static const struct file_operations yaffs_file_operations = {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 16)//anzyelay
+   .read = __vfs_read,
+   .write = __vfs_write,
+#else
    .read = new_sync_read,
    .write = new_sync_write,
+#endif
    .read_iter = generic_file_read_iter,
    .write_iter = generic_file_write_iter,
 #else
@@ -1053,7 +1062,11 @@
 }

 #if (YAFFS_NEW_FOLLOW_LINK == 1)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 16)
 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
+#else
+static const char *yaffs_follow_link(struct dentry *dentry,void **cookie)
+#endif
 {
    void *ret;
 #else
@@ -1075,7 +1088,11 @@
        goto out;
    }
 #if (YAFFS_NEW_FOLLOW_LINK == 1)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 16)
    nd_set_link(nd, alias);
+#else
+   *cookie = alias;
+#endif
    ret = alias;
 out:
    if (ret_int)
@@ -1107,10 +1124,17 @@
 #endif

 #if (YAFFS_NEW_FOLLOW_LINK == 1)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 16)
 void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias)
 {
    kfree(alias);
 }
+#else
+void yaffs_put_link(struct inode *inode,void *alias)
+{
+   kfree(alias);
+}
+#endif
 #endif

 static const struct inode_operations yaffs_symlink_inode_operations = {
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页