linux内核版本:2.6.36.1

OS:ubuntu 10.4

开发板:友善mini2440

bootloader: supervivi

在输入make zImage后,出现如下错误:

fs/yaffs2/yaffs_fs.c:310: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_fs.c:380: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_fs.c:393: error: unknown field 'delete_inode' specified in initializer
fs/yaffs2/yaffs_fs.c:393: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_fs.c:394: error: unknown field 'clear_inode' specified in initializer
fs/yaffs2/yaffs_fs.c:394: warning: initialization from incompatible pointer type
fs/yaffs2/yaffs_fs.c: In function 'yaffs_delete_inode':
fs/yaffs2/yaffs_fs.c:725: error: implicit declaration of function 'clear_inode'
fs/yaffs2/yaffs_fs.c: In function 'yaffs_setattr':
fs/yaffs2/yaffs_fs.c:1703: error: implicit declaration of function 'inode_setattr'
make[2]: *** [fs/yaffs2/yaffs_fs.o] Error 1
make[1]: *** [fs/yaffs2] Error 2
make: *** [fs] Error 2

错误说明:在初始化的时候,没找到delete_inode。

找到出错的那行如下:

static const struct super_operations yaffs_super_ops = {
    .statfs = yaffs_statfs,

#ifndef YAFFS_USE_OWN_IGET
    .read_inode = yaffs_read_inode,
#endif
#ifdef YAFFS_HAS_PUT_INODE
    .put_inode = yaffs_put_inode,
#endif
    .put_super = yaffs_put_super,
    .delete_inode = yaffs_delete_inode,
    .clear_inode = yaffs_clear_inode,
    .sync_fs = yaffs_sync_fs,
    .write_super = yaffs_write_super,
};

其中使用了结构体:super_operations

查找linux2.6.36.1/include/linux/fs.h 发现:

struct super_operations {
       struct inode *(*alloc_inode)(struct super_block *sb);
    void (*destroy_inode)(struct inode *);

       void (*dirty_inode) (struct inode *);
    int (*write_inode) (struct inode *, struct writeback_control *wbc);
    int (*drop_inode) (struct inode *);
    void (*evict_inode) (struct inode *);
    void (*put_super) (struct super_block *);
    void (*write_super) (struct super_block *);
    int (*sync_fs)(struct super_block *sb, int wait);
    int (*freeze_fs) (struct super_block *);
    int (*unfreeze_fs) (struct super_block *);
    int (*statfs) (struct dentry *, struct kstatfs *);
    int (*remount_fs) (struct super_block *, int *, char *);
    void (*umount_begin) (struct super_block *);

    int (*show_options)(struct seq_file *, struct vfsmount *);
    int (*show_stats)(struct seq_file *, struct vfsmount *);
#ifdef CONFIG_QUOTA
    ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
    ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
#endif
    int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
};
其中的回调函数并不包含delete_inode和clear_inode.只好对照着找了。

从google上搜索得到下面的结论:

delete_inode和clear_inode都已经被evict_inode代替。

这是linux内核修改内容的地址:http://kerneltrap.org/mailarchive/linux-kernel/2010/8/10/4604990

太晚了,yaffs_fs.c还不知道如何修改。该睡觉了。

===============无聊的分割线===================

这个周末又查了一下,看到一个关于这个版本的补丁,如果有需要大家可以自己打上。

下面是patch文件的内容:

---
 yaffs_fs.c |  116 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 102 insertions(+), 14 deletions(-)

diff --git a/yaffs_fs.c b/yaffs_fs.c
index 8e39ce2..430bed5 100644
--- a/yaffs_fs.c
+++ b/yaffs_fs.c
@@ -41,6 +41,19 @@
 #define YAFFS_COMPILE_EXPORTFS
 #endif
 
+#define YAFFS_LINUS_TORVALDS_MAINLINE
+#if defined(YAFFS_LINUS_TORVALDS_MAINLINE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+#define YAFFS_USE_SETATTR_COPY
+#define YAFFS_HAS_EVICT_INODE
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
+#define YAFFS_USE_SETATTR_COPY
+#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
+#define YAFFS_HAS_EVICT_INODE
+#endif
+
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
 #define YAFFS_NEW_FOLLOW_LINK 1
 #else
@@ -267,8 +280,12 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
 static void yaffs_put_inode(struct inode *inode);
 #endif
 
+#ifdef YAFFS_HAS_EVICT_INODE
+static void yaffs_evict_inode(struct inode *);
+#else
 static void yaffs_delete_inode(struct inode *);
 static void yaffs_clear_inode(struct inode *);
+#endif
 
 static int yaffs_readpage(struct file *file, struct page *page);
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
@@ -315,6 +332,9 @@ static void yaffs_MarkSuperBlockDirty(yaffs_Device *dev);
 
 static loff_t yaffs_dir_llseek(struct file *file, loff_t offset, int origin);
 
+static int yaffs_vfs_setattr(struct inode *, struct iattr *);
+
+
 static struct address_space_operations yaffs_file_address_operations = {
  .readpage = yaffs_readpage,
  .writepage = yaffs_writepage,
@@ -327,6 +347,7 @@ static struct address_space_operations yaffs_file_address_operations = {
 #endif
 };
 
+
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
 static const struct file_operations yaffs_file_operations = {
  .read = do_sync_read,
@@ -440,12 +461,28 @@ static const struct super_operations yaffs_super_ops = {
  .put_inode = yaffs_put_inode,
 #endif
  .put_super = yaffs_put_super,
+#ifdef YAFFS_HAS_EVICT_INODE
+ .evict_inode = yaffs_evict_inode,
+#else
  .delete_inode = yaffs_delete_inode,
  .clear_inode = yaffs_clear_inode,
+#endif
  .sync_fs = yaffs_sync_fs,
  .write_super = yaffs_write_super,
 };
 
+
+static  int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr)
+{
+#ifdef  YAFFS_USE_SETATTR_COPY
+ setattr_copy(inode,attr);
+ return 0;
+#else
+ return inode_setattr(inode, attr);
+#endif
+
+}
+
 static unsigned yaffs_gc_control_callback(yaffs_Device *dev)
 {
  return yaffs_gc_control;
@@ -788,36 +825,85 @@ static void yaffs_put_inode(struct inode *inode)
 }
 #endif
 
-/* clear is called to tell the fs to release any per-inode data it holds */
-static void yaffs_clear_inode(struct inode *inode)
+
+static void yaffs_UnstitchObject(struct inode *inode, yaffs_Object *obj)
+{
+ /* Clear the association between the inode and
+  * the yaffs_Object.
+  */
+ obj->myInode = NULL;
+ yaffs_InodeToObjectLV(inode) = NULL;
+
+ /* If the object freeing was deferred, then the real
+  * free happens now.
+  * This should fix the inode inconsistency problem.
+  */
+ yaffs_HandleDeferedFree(obj);
+}
+
+#ifdef YAFFS_HAS_EVICT_INODE
+/* yaffs_evict_inode combines into one operation what was previously done in
+ * yaffs_clear_inode() and yaffs_delete_inode()
+ *
+ */
+static void yaffs_evict_inode( struct inode *inode)
 {
  yaffs_Object *obj;
  yaffs_Device *dev;
+ int deleteme = 0;
 
  obj = yaffs_InodeToObject(inode);
 
  T(YAFFS_TRACE_OS,
-  (TSTR("yaffs_clear_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
+  (TSTR("yaffs_evict_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
   atomic_read(&inode->i_count),
   obj ? "object exists" : "null object"));
 
+ if (!inode->i_nlink && !is_bad_inode(inode))
+  deleteme = 1;
+ truncate_inode_pages(&inode->i_data,0);
+
+ if(deleteme && obj){
+  dev = obj->myDev;
+  yaffs_GrossLock(dev);
+  yaffs_DeleteObject(obj);
+  yaffs_GrossUnlock(dev);
+ }
+ end_writeback(inode);
  if (obj) {
   dev = obj->myDev;
   yaffs_GrossLock(dev);
+  yaffs_UnstitchObject(inode,obj);
+  yaffs_GrossUnlock(dev);
+ }
 
-  /* Clear the association between the inode and
-   * the yaffs_Object.
-   */
-  obj->myInode = NULL;
-  yaffs_InodeToObjectLV(inode) = NULL;
 
-  /* If the object freeing was deferred, then the real
-   * free happens now.
-   * This should fix the inode inconsistency problem.
-   */
+}
+#else
 
-  yaffs_HandleDeferedFree(obj);
+/* clear is called to tell the fs to release any per-inode data it holds.
+ * The object might still exist on disk and is just being thrown out of the cache
+ * or else the object has actually been deleted and we're being called via
+ * the chain
+ *   yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode()
+ */
 
+static void yaffs_clear_inode(struct inode *inode)
+{
+ yaffs_Object *obj;
+ yaffs_Device *dev;
+
+ obj = yaffs_InodeToObject(inode);
+
+ T(YAFFS_TRACE_OS,
+  (TSTR("yaffs_clear_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
+  atomic_read(&inode->i_count),
+  obj ? "object exists" : "null object"));
+
+ if (obj) {
+  dev = obj->myDev;
+  yaffs_GrossLock(dev);
+  yaffs_UnstitchObject(inode,obj);
   yaffs_GrossUnlock(dev);
  }
 
@@ -849,6 +935,8 @@ static void yaffs_delete_inode(struct inode *inode)
 #endif
  clear_inode(inode);
 }
+#endif
+
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
 static int yaffs_file_flush(struct file *file, fl_owner_t id)
@@ -1881,7 +1969,7 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
  if (error == 0) {
   int result;
   if (!error){
-   error = inode_setattr(inode, attr);
+   error = yaffs_vfs_setattr(inode, attr);
    T(YAFFS_TRACE_OS,(TSTR("inode_setattr called\n")));
    if (attr->ia_valid & ATTR_SIZE)
                          truncate_inode_pages(&inode->i_data,attr->ia_size);
--

 

我大致看了一下,打上基本就没问题了。可是为什么这样改,还不知道,生活一下变得索然无趣了。要学习的东西太多,希望有朋友可以一起交流学习。

Logo

更多推荐