linux-3.12.6 移植yaffs2文件系统记录

来源:互联网 发布:淘宝卖家如何代销上货 编辑:程序博客网 时间:2024/06/05 23:07

这里主要是由于内核中一些接口的改变造成的。

1、问题:fs/yaffs2/yaffs_vfs.c:1786:2: error: unknown field 'readdir' specified ininitializer.

      分析:出现这种错误往往是由于没有定义造成的。我进入源码发现是file_operation 文件操作函数类里的成员,猜测没有这个成员(映像中是有的)。定位到file_operation类的定义(include/linux/fs.h: 1562),发现真的没有这个函数指针了。在疑惑之余,打开旧版本的内核对比发现readdir函数指针不见了,替换的是iterate函数指针。新的函数在参数上有很大的不同,需要对旧版本的软件进行修改才能继续使用。至此得出结论。

       结论:必须修改yaffs2源码或者打补丁(但在官网并没有发现,也没有相关说明)。

       解决:改代码,百度发现已有前人栽树,我这个后人就只好乘凉了。

                  https://dev.openwrt.org/browser/trunk/target/linux/generic/patches-3.12/503-yaffs-3.12-convert-readdir-to-iterate.patch?rev=39084#L1911

下面就粘贴下做个备份:

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))   static int yaffs_iterate(struct file *file, struct dir_context *ctx)   {       struct yaffs_obj *obj;       struct yaffs_dev *dev;       struct yaffs_search_context *sc;       struct inode *inode = file->f_dentry->d_inode;       unsigned long offset, curoffs;       struct yaffs_obj *l;       int ret_val = 0;              char name[YAFFS_MAX_NAME_LENGTH + 1];              obj = yaffs_dentry_to_obj(file->f_dentry);       dev = obj->my_dev;              yaffs_gross_lock(dev);         yaffs_dev_to_lc(dev)->readdir_process = current;          offset = ctx->pos;              sc = yaffs_new_search(obj);       if (!sc) {       ret_val = -ENOMEM;       goto out;       }              yaffs_trace(YAFFS_TRACE_OS,"yaffs_readdir: starting at %d", (int)offset);        if (offset == 0) {       yaffs_trace(YAFFS_TRACE_OS, "yaffs_readdir: entry . ino %d", (int)inode->i_ino);       yaffs_gross_unlock(dev);       if (!dir_emit_dot(file, ctx)) {       yaffs_gross_lock(dev);       goto out;       }       yaffs_gross_lock(dev);       offset++;       ctx->pos++;       }       if (offset == 1) {       yaffs_trace(YAFFS_TRACE_OS, "yaffs_readdir: entry .. ino %d", (int)file->f_dentry->d_parent->d_inode->i_ino);       yaffs_gross_unlock(dev);       if (!dir_emit_dotdot(file, ctx)) {       yaffs_gross_lock(dev);       goto out;       }       yaffs_gross_lock(dev);       offset++;       ctx->pos++;       }         curoffs = 1;           /* If the directory has changed since the open or last call to readdir, rewind to after the 2 canned entries. */       if (file->f_version != inode->i_version) {       offset = 2;       ctx->pos = offset;       file->f_version = inode->i_version;       }          while (sc->next_return) {       curoffs++;       l = sc->next_return;       if (curoffs >= offset) {       int this_inode = yaffs_get_obj_inode(l);       int this_type = yaffs_get_obj_type(l);         yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);       yaffs_trace(YAFFS_TRACE_OS, "yaffs_readdir: %s inode %d", name, yaffs_get_obj_inode(l));              yaffs_gross_unlock(dev);              if (!dir_emit(ctx, name, strlen(name),this_inode, this_type) < 0) {       yaffs_gross_lock(dev);       goto out;       }          yaffs_gross_lock(dev);          offset++;       ctx->pos++;       }       yaffs_search_advance(sc);       }          out:       yaffs_search_end(sc);       yaffs_dev_to_lc(dev)->readdir_process = NULL;       yaffs_gross_unlock(dev);         return ret_val;       }   #else   static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)   {  .....  }  #endif static const struct file_operations yaffs_dir_operations = {      .read = generic_read_dir,  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))           .iterate = yaffs_iterate,   #else           .readdir = yaffs_readdir,   #endif        .fsync = yaffs_sync_object,      .llseek = generic_file_llseek,  }; 

2、问题:fs/yaffs2/yaffs_vfs.c:3501: error: implicit declaration of function 'create_proc_entry'

       解决:http://my.oschina.net/fgq611/blog/173588

@@ -3384,12 +3384,6 @@ static struct file_system_to_install fs_to_install[] = {        {NULL, 0} }; +static const struct file_operations yaffs_fops = {+        .owner = THIS_MODULE,+        .read = yaffs_proc_read,+        .write = yaffs_proc_write,+};+ static int __init init_yaffs_fs(void) {        int error = 0;@@ -3401,9 +3395,9 @@ static int __init init_yaffs_fs(void)        mutex_init(&yaffs_context_lock);         /* Install the proc_fs entries */+       my_proc_entry = proc_create("yaffs",+                                         S_IRUGO | S_IFREG, YPROC_ROOT, &yaffs_fops);+#if 0-       my_proc_entry = create_proc_entry("yaffs",-                                         S_IRUGO | S_IFREG, YPROC_ROOT);-        if (my_proc_entry) {                my_proc_entry->write_proc = yaffs_proc_write;                my_proc_entry->read_proc = yaffs_proc_read;@@ -3411,7 +3405,7 @@ static int __init init_yaffs_fs(void)        } else {                return -ENOMEM;         }+#endif-        /* Now add the file system entries */         fsinst = fs_to_install;

总结:这类由于内核中接口的变化引起的错误或者警告处理方式都是一样的。但第一个问题确实够麻烦的,很大程度上要自己修改,只能希望yaffs的作者们能够更新吧(官网上竟然不能选择版本下载,这个真的有点不爽)。


遗留问题:在对第二个问题,创建file_operation yaffs_fops时,给read和write两个指针赋值时的函数参数并不一致,虽然编译通过(有警告),但个人总觉得这里会有问题:编译时如果把传递的参数丢弃了一部分会造成怎样的错误?如果参数按实际函数的个数和类型传递,这意味着我们可以随意创建底层函数而不必遵守统一的接口。这显然是不成立的。望看官们,给予指点。

给出一个详细的赋值的例子:

 int (* read)(struct file *, char __user *, size_t, loff_t *) = int yaffs_proc_read(char *page, char **start, off_t offset, int count, int *eof, void *data),


0 0