Fix compilation on Linux 2.6.26, fix compilation warnings
[yaffs2.git] / yaffs_fs.c
index ab6a3a7e00b19c16a1be25f72db29e74976f7316..2d0f8a068ef0755038db472a9068e4aee4944f9a 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.66 2008-05-05 07:58:58 charles Exp $";
+    "$Id: yaffs_fs.c,v 1.68 2008-07-23 03:35:12 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -43,7 +43,6 @@ extern const char *yaffs_guts_c_version;
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/list.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
@@ -78,6 +77,12 @@ extern const char *yaffs_guts_c_version;
 
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26))
+#define YPROC_ROOT  &proc_root
+#else
+#define YPROC_ROOT  NULL
+#endif
+
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
 #define WRITE_SIZE_STR "writesize"
 #define WRITE_SIZE(mtd) (mtd)->writesize
@@ -108,6 +113,19 @@ MODULE_PARM(yaffs_traceMask,"i");
 MODULE_PARM(yaffs_wr_attempts,"i");
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25))
+/* use iget and read_inode */
+#define Y_IGET(sb,inum) iget((sb),(inum))
+static void yaffs_read_inode(struct inode *inode);
+
+#else
+/* Call local equivalent */
+#define YAFFS_USE_OWN_IGET
+#define Y_IGET(sb,inum) yaffs_iget((sb),(inum))
+
+static struct inode * yaffs_iget(struct super_block *sb, unsigned long ino);
+#endif
+
 /*#define T(x) printk x */
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
@@ -183,9 +201,11 @@ static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
 #else
 static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
 #endif
-static void yaffs_read_inode(struct inode *inode);
 
+#ifdef YAFFS_HAS_PUT_INODE
 static void yaffs_put_inode(struct inode *inode);
+#endif
+
 static void yaffs_delete_inode(struct inode *);
 static void yaffs_clear_inode(struct inode *);
 
@@ -286,8 +306,13 @@ static struct file_operations yaffs_dir_operations = {
 
 static 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,
@@ -431,6 +456,9 @@ static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
 
 }
 
+
+#ifdef YAFFS_HAS_PUT_INODE
+
 /* For now put inode is just for debugging
  * Put inode is called when the inode **structure** is put.
  */
@@ -441,6 +469,7 @@ static void yaffs_put_inode(struct inode *inode)
           atomic_read(&inode->i_count)));
 
 }
+#endif
 
 /* clear is called to tell the fs to release any per-inode data it holds */
 static void yaffs_clear_inode(struct inode *inode)
@@ -848,7 +877,9 @@ struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
        T(YAFFS_TRACE_OS,
          (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId));
 
-       inode = iget(sb, obj->objectId);
+       inode = Y_IGET(sb, obj->objectId);
+       if(IS_ERR(inode))
+         return NULL;
 
        /* NB Side effect: iget calls back to yaffs_read_inode(). */
        /* iget also increments the inode's i_count */
@@ -920,7 +951,7 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
        yaffs_Device *dev;
        struct inode *inode = f->f_dentry->d_inode;
        unsigned long offset, curoffs;
-       struct list_head *i;
+       struct ylist_head *i;
        yaffs_Object *l;
 
        char name[YAFFS_MAX_NAME_LENGTH + 1];
@@ -969,10 +1000,10 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
                f->f_version = inode->i_version;
        }
 
-       list_for_each(i, &obj->variant.directoryVariant.children) {
+       ylist_for_each(i, &obj->variant.directoryVariant.children) {
                curoffs++;
                if (curoffs >= offset) {
-                       l = list_entry(i, yaffs_Object, siblings);
+                       l = ylist_entry(i, yaffs_Object, siblings);
 
                        yaffs_GetObjectName(l, name,
                                            YAFFS_MAX_NAME_LENGTH + 1);
@@ -1273,7 +1304,7 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        if (target &&
            target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
-           !list_empty(&target->variant.directoryVariant.children)) {
+           !ylist_empty(&target->variant.directoryVariant.children)) {
 
                T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));
 
@@ -1404,7 +1435,6 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
 }
 
 
-/**
 static int yaffs_do_sync_fs(struct super_block *sb)
 {
 
@@ -1414,8 +1444,10 @@ static int yaffs_do_sync_fs(struct super_block *sb)
        if(sb->s_dirt) {
                yaffs_GrossLock(dev);
 
-               if(dev)
+               if(dev){
+                       yaffs_FlushEntireDeviceCache(dev);
                        yaffs_CheckpointSave(dev);
+               }
 
                yaffs_GrossUnlock(dev);
 
@@ -1423,7 +1455,7 @@ static int yaffs_do_sync_fs(struct super_block *sb)
        }
        return 0;
 }
-**/
+
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
 static void yaffs_write_super(struct super_block *sb)
@@ -1433,8 +1465,9 @@ static int yaffs_write_super(struct super_block *sb)
 {
 
        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n"));
+       yaffs_do_sync_fs(sb);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
-       return 0; /* yaffs_do_sync_fs(sb);*/
+       return 0; 
 #endif
 }
 
@@ -1448,10 +1481,47 @@ static int yaffs_sync_fs(struct super_block *sb)
 
        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n"));
 
-       return 0; /* yaffs_do_sync_fs(sb);*/
+       yaffs_do_sync_fs(sb);
+       
+       return 0; 
 
 }
 
+#ifdef YAFFS_USE_OWN_IGET
+
+static struct inode * yaffs_iget(struct super_block *sb, unsigned long ino)
+{
+       struct inode *inode;
+       yaffs_Object *obj;
+       yaffs_Device *dev = yaffs_SuperToDevice(sb);
+
+       T(YAFFS_TRACE_OS,
+         (KERN_DEBUG "yaffs_iget for %lu\n", ino));
+
+       inode = iget_locked(sb, ino);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
+
+       /* NB This is called as a side effect of other functions, but
+       * we had to release the lock to prevent deadlocks, so
+       * need to lock again.
+       */
+    
+       yaffs_GrossLock(dev);
+
+       obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
+
+       yaffs_FillInodeFromObject(inode, obj);
+
+       yaffs_GrossUnlock(dev);
+       
+       unlock_new_inode(inode);
+       return inode;
+}
+
+#else
 
 static void yaffs_read_inode(struct inode *inode)
 {
@@ -1475,7 +1545,9 @@ static void yaffs_read_inode(struct inode *inode)
        yaffs_GrossUnlock(dev);
 }
 
-static LIST_HEAD(yaffs_dev_list);
+#endif
+
+static YLIST_HEAD(yaffs_dev_list);
 
 #if 0 // not used
 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
@@ -1529,7 +1601,7 @@ static void yaffs_put_super(struct super_block *sb)
        yaffs_GrossUnlock(dev);
 
        /* we assume this is protected by lock_kernel() in mount/umount */
-       list_del(&dev->devList);
+       ylist_del(&dev->devList);
 
        if(dev->spareBuffer){
                YFREE(dev->spareBuffer);
@@ -1864,7 +1936,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        dev->skipCheckpointWrite = options.skip_checkpoint_write;
 
        /* we assume this is protected by lock_kernel() in mount/umount */
-       list_add_tail(&dev->devList, &yaffs_dev_list);
+       ylist_add_tail(&dev->devList, &yaffs_dev_list);
 
        init_MUTEX(&dev->grossLock);
 
@@ -2049,7 +2121,7 @@ static int yaffs_proc_read(char *page,
                           char **start,
                           off_t offset, int count, int *eof, void *data)
 {
-       struct list_head *item;
+       struct ylist_head *item;
        char *buf = page;
        int step = offset;
        int n = 0;
@@ -2073,8 +2145,8 @@ static int yaffs_proc_read(char *page,
        lock_kernel();
 
        /* Locate and print the Nth entry.  Order N-squared but N is small. */
-       list_for_each(item, &yaffs_dev_list) {
-               yaffs_Device *dev = list_entry(item, yaffs_Device, devList);
+       ylist_for_each(item, &yaffs_dev_list) {
+               yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList);
                if (n < step) {
                        n++;
                        continue;
@@ -2247,7 +2319,7 @@ static int __init init_yaffs_fs(void)
        /* Install the proc_fs entry */
        my_proc_entry = create_proc_entry("yaffs",
                                               S_IRUGO | S_IFREG,
-                                              &proc_root);
+                                              YPROC_ROOT);
 
        if (my_proc_entry) {
                my_proc_entry->write_proc = yaffs_proc_write;
@@ -2293,7 +2365,7 @@ static void __exit exit_yaffs_fs(void)
        T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__
                               " removing. \n"));
 
-       remove_proc_entry("yaffs", &proc_root);
+       remove_proc_entry("yaffs", YPROC_ROOT);
 
        fsinst = fs_to_install;