Conditionally define old style info structures
[yaffs2.git] / yaffs_fs.c
index 15c27832ef4f233db22e3f97470610522bdacb8c..eceb34f3c0e23bd1f771d690255bdae2801497a2 100644 (file)
@@ -23,7 +23,7 @@
  * This is the file system front-end to YAFFS that hooks it up to
  * the VFS.
  *
- * Special notes: 
+ * Special notes:
  * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with
  *         this superblock
  * >> 2.6: sb->s_fs_info  points to the yaffs_Device associated with this
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.60 2007-05-15 20:07:40 charles Exp $";
+    "$Id: yaffs_fs.c,v 1.65 2007-12-13 15:35:17 wookey Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -89,13 +89,23 @@ extern const char *yaffs_guts_c_version;
 #include "yportenv.h"
 #include "yaffs_guts.h"
 
-unsigned yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS
-                          /* | 0xFFFFFFFF */; 
-
 #include <linux/mtd/mtd.h>
 #include "yaffs_mtdif.h"
+#include "yaffs_mtdif1.h"
 #include "yaffs_mtdif2.h"
 
+unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS;
+unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
+
+/* Module Parameters */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+module_param(yaffs_traceMask,uint,0644);
+module_param(yaffs_wr_attempts,uint,0644);
+#else
+MODULE_PARM(yaffs_traceMask,"i");
+MODULE_PARM(yaffs_wr_attempts,"i");
+#endif
+
 /*#define T(x) printk x */
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
@@ -203,24 +213,45 @@ static struct address_space_operations yaffs_file_address_operations = {
        .commit_write = yaffs_commit_write,
 };
 
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
 static struct file_operations yaffs_file_operations = {
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
        .read = do_sync_read,
        .write = do_sync_write,
        .aio_read = generic_file_aio_read,
        .aio_write = generic_file_aio_write,
+       .mmap = generic_file_mmap,
+       .flush = yaffs_file_flush,
+       .fsync = yaffs_sync_object,
+       .splice_read = generic_file_splice_read,
+       .splice_write = generic_file_splice_write,
+};
+
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+
+static struct file_operations yaffs_file_operations = {
+       .read = do_sync_read,
+       .write = do_sync_write,
+       .aio_read = generic_file_aio_read,
+       .aio_write = generic_file_aio_write,
+       .mmap = generic_file_mmap,
+       .flush = yaffs_file_flush,
+       .fsync = yaffs_sync_object,
+       .sendfile = generic_file_sendfile,
+};
+
 #else
+
+static struct file_operations yaffs_file_operations = {
        .read = generic_file_read,
        .write = generic_file_write,
-#endif
        .mmap = generic_file_mmap,
        .flush = yaffs_file_flush,
        .fsync = yaffs_sync_object,
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
        .sendfile = generic_file_sendfile,
 #endif
-
 };
+#endif
 
 static struct inode_operations yaffs_file_inode_operations = {
        .setattr = yaffs_setattr,
@@ -360,7 +391,7 @@ static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
                                   dentry->d_name.name);
 
        obj = yaffs_GetEquivalentObject(obj);   /* in case it was a hardlink */
-       
+
        /* Can't hold gross lock when calling yaffs_get_inode() */
        yaffs_GrossUnlock(dev);
 
@@ -698,21 +729,21 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj)
                                obj->yst_mode &= ~S_IFMT;
                                obj->yst_mode |= S_IFREG;
                        }
+
                        break;
                case YAFFS_OBJECT_TYPE_SYMLINK :
                        if( ! S_ISLNK(mode) ){
                                obj->yst_mode &= ~S_IFMT;
                                obj->yst_mode |= S_IFLNK;
                        }
+
                        break;
                case YAFFS_OBJECT_TYPE_DIRECTORY :
                        if( ! S_ISDIR(mode) ){
                                obj->yst_mode &= ~S_IFMT;
                                obj->yst_mode |= S_IFDIR;
                        }
+
                        break;
                case YAFFS_OBJECT_TYPE_UNKNOWN :
                case YAFFS_OBJECT_TYPE_HARDLINK :
@@ -989,7 +1020,7 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
        int error = -ENOSPC;
        uid_t uid = current->fsuid;
        gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-       
+
        if((dir->i_mode & S_ISGID) && S_ISDIR(mode))
                mode |= S_ISGID;
 
@@ -1044,7 +1075,7 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
                obj = NULL;     /* Do we ever get here? */
                break;
        }
-       
+
        /* Can not call yaffs_get_inode() with gross lock held */
        yaffs_GrossUnlock(dev);
 
@@ -1233,13 +1264,13 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
        target =
            yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),
                                   new_dentry->d_name.name);
-       
-       
+
+
 
        if (target &&
            target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
            !list_empty(&target->variant.directoryVariant.children)) {
-           
+
                T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));
 
                retVal = YAFFS_FAIL;
@@ -1247,7 +1278,7 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
                /* Now does unlinking internally using shadowing mechanism */
                T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n"));
-               
+
                retVal =
                    yaffs_RenameObject(yaffs_InodeToObject(old_dir),
                                       old_dentry->d_name.name,
@@ -1359,7 +1390,7 @@ static int yaffs_do_sync_fs(struct super_block *sb)
 
                if(dev)
                        yaffs_CheckpointSave(dev);
-               
+
                yaffs_GrossUnlock(dev);
 
                sb->s_dirt = 0;
@@ -1390,16 +1421,16 @@ 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);*/
-       
+
 }
 
 
 static void yaffs_read_inode(struct inode *inode)
 {
        /* NB This is called as a side effect of other functions, but
-        * we had to release the lock to prevent deadlocks, so 
+        * we had to release the lock to prevent deadlocks, so
         * need to lock again.
         */
 
@@ -1410,7 +1441,7 @@ static void yaffs_read_inode(struct inode *inode)
          (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino));
 
        yaffs_GrossLock(dev);
-       
+
        obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
 
        yaffs_FillInodeFromObject(inode, obj);
@@ -1420,34 +1451,36 @@ static void yaffs_read_inode(struct inode *inode)
 
 static LIST_HEAD(yaffs_dev_list);
 
+#if 0 // not used
 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
 {
        yaffs_Device    *dev = yaffs_SuperToDevice(sb);
 
        if( *flags & MS_RDONLY ) {
                struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
-           
+
                T(YAFFS_TRACE_OS,
                        (KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name ));
 
                yaffs_GrossLock(dev);
-        
+
                yaffs_FlushEntireDeviceCache(dev);
-       
+
                yaffs_CheckpointSave(dev);
+
                if (mtd->sync)
                        mtd->sync(mtd);
 
                yaffs_GrossUnlock(dev);
        }
        else {
-               T(YAFFS_TRACE_OS, 
+               T(YAFFS_TRACE_OS,
                        (KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name ));
        }
+
        return 0;
 }
+#endif
 
 static void yaffs_put_super(struct super_block *sb)
 {
@@ -1456,7 +1489,7 @@ static void yaffs_put_super(struct super_block *sb)
        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n"));
 
        yaffs_GrossLock(dev);
-       
+
        yaffs_FlushEntireDeviceCache(dev);
 
        yaffs_CheckpointSave(dev);
@@ -1466,12 +1499,12 @@ static void yaffs_put_super(struct super_block *sb)
        }
 
        yaffs_Deinitialise(dev);
-       
+
        yaffs_GrossUnlock(dev);
 
        /* we assume this is protected by lock_kernel() in mount/umount */
        list_del(&dev->devList);
-       
+
        if(dev->spareBuffer){
                YFREE(dev->spareBuffer);
                dev->spareBuffer = NULL;
@@ -1497,7 +1530,7 @@ static void yaffs_MTDPutSuper(struct super_block *sb)
 static void yaffs_MarkSuperBlockDirty(void *vsb)
 {
        struct super_block *sb = (struct super_block *)vsb;
-       
+
        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb));
 //     if(sb)
 //             sb->s_dirt = 1;
@@ -1516,13 +1549,13 @@ static int yaffs_parse_options(yaffs_options *options, const char *options_str)
        char cur_opt[MAX_OPT_LEN+1];
        int p;
        int error = 0;
-       
+
        /* Parse through the options which is a comma seperated list */
-       
+
        while(options_str && *options_str && !error){
                memset(cur_opt,0,MAX_OPT_LEN+1);
                p = 0;
-               
+
                while(*options_str && *options_str != ','){
                        if(p < MAX_OPT_LEN){
                                cur_opt[p] = *options_str;
@@ -1530,7 +1563,7 @@ static int yaffs_parse_options(yaffs_options *options, const char *options_str)
                        }
                        options_str++;
                }
-               
+
                if(!strcmp(cur_opt,"inband-tags"))
                        options->inband_tags = 1;
                else if(!strcmp(cur_opt,"no-cache"))
@@ -1546,7 +1579,7 @@ static int yaffs_parse_options(yaffs_options *options, const char *options_str)
                        printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",cur_opt);
                        error = 1;
                }
-               
+
        }
 
        return error;
@@ -1564,7 +1597,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        struct mtd_info *mtd;
        int err;
        char *data_str = (char *)data;
-       
+
        yaffs_options options;
 
        sb->s_magic = YAFFS_MAGIC;
@@ -1580,14 +1613,14 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
                printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n",
                       sb->s_dev,
                       yaffs_devname(sb, devname_buf));
-                   
+
        if(!data_str)
                data_str = "";
-   
+
        printk(KERN_INFO "yaffs: passed flags \"%s\"\n",data_str);
-       
+
        memset(&options,0,sizeof(options));
-       
+
        if(yaffs_parse_options(&options,data_str)){
                /* Option parsing failed */
                return NULL;
@@ -1641,10 +1674,10 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize));
        T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize));
        T(YAFFS_TRACE_OS, (" size %d\n", mtd->size));
-       
+
 #ifdef CONFIG_YAFFS_AUTO_YAFFS2
 
-       if (yaffsVersion == 1 && 
+       if (yaffsVersion == 1 &&
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
            mtd->writesize >= 2048) {
 #else
@@ -1652,10 +1685,10 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
 #endif
            T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n"));
            yaffsVersion = 2;
-       }       
-       
+       }
+
        /* Added NCB 26/5/2006 for completeness */
-       if (yaffsVersion == 2 && 
+       if (yaffsVersion == 2 &&
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
            mtd->writesize == 512) {
 #else
@@ -1663,7 +1696,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
 #endif
            T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n"));
            yaffsVersion = 1;
-       }       
+       }
 
 #endif
 
@@ -1774,12 +1807,21 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
 #endif
                nBlocks = mtd->size / mtd->erasesize;
 
-               dev->nCheckpointReservedBlocks = CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS;
                dev->startBlock = 0;
                dev->endBlock = nBlocks - 1;
        } else {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+               /* use the MTD interface in yaffs_mtdif1.c */
+               dev->writeChunkWithTagsToNAND =
+                       nandmtd1_WriteChunkWithTagsToNAND;
+               dev->readChunkWithTagsFromNAND =
+                       nandmtd1_ReadChunkWithTagsFromNAND;
+               dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad;
+               dev->queryNANDBlock = nandmtd1_QueryNANDBlock;
+#else
                dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
                dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
+#endif
                dev->isYaffs2 = 0;
        }
        /* ... and common functions */
@@ -1787,10 +1829,10 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        dev->initialiseNAND = nandmtd_InitialiseNAND;
 
        dev->putSuperFunc = yaffs_MTDPutSuper;
-       
+
        dev->superBlock = (void *)sb;
        dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;
-       
+
 
 #ifndef CONFIG_YAFFS_DOES_ECC
        dev->useNANDECC = 1;
@@ -1802,7 +1844,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
 
        dev->skipCheckpointRead = options.skip_checkpoint_read;
        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);
 
@@ -1815,7 +1857,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        T(YAFFS_TRACE_OS,
          ("yaffs_read_super: guts initialised %s\n",
           (err == YAFFS_OK) ? "OK" : "FAILED"));
-       
+
        /* Release lock before yaffs_get_inode() */
        yaffs_GrossUnlock(dev);
 
@@ -1952,7 +1994,6 @@ static char *yaffs_dump_dev(char *buf, yaffs_Device * dev)
        buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);
        buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks);
        buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks);
-       buf += sprintf(buf, "nCheckptResBlocks.. %d\n", dev->nCheckpointReservedBlocks);
        buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);
        buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated);
        buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes);
@@ -2075,7 +2116,7 @@ static int yaffs_proc_write(struct file *file, const char *buf,
        unsigned rg = 0, mask_bitfield;
        char *end;
        char *mask_name;
-       char *x; 
+       const char *x;
        char substring[MAX_MASK_NAME_LENGTH+1];
        int i;
        int done = 0;
@@ -2103,22 +2144,21 @@ static int yaffs_proc_write(struct file *file, const char *buf,
                        break;
                }
                mask_name = NULL;
-               
+
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                if (end > buf + pos) {
                        mask_name = "numeral";
                        len = end - (buf + pos);
+                       pos += len;
                        done = 0;
                } else {
-                       for(x = buf + pos, i = 0; 
+                       for(x = buf + pos, i = 0;
                            (*x == '_' || (*x >='a' && *x <= 'z')) &&
                            i <MAX_MASK_NAME_LENGTH; x++, i++, pos++)
                            substring[i] = *x;
                        substring[i] = '\0';
-                       
+
                        for (i = 0; mask_flags[i].mask_name != NULL; i++) {
-                               //len = strlen(mask_flags[i].mask_name);
-                               //if (strncmp(buf + pos, mask_flags[i].mask_name, len) == 0) {
                                if(strcmp(substring,mask_flags[i].mask_name) == 0){
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
@@ -2129,7 +2169,6 @@ static int yaffs_proc_write(struct file *file, const char *buf,
                }
 
                if (mask_name != NULL) {
-                       // pos += len;
                        done = 0;
                        switch(add) {
                        case '-':
@@ -2149,9 +2188,9 @@ static int yaffs_proc_write(struct file *file, const char *buf,
        }
 
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
-       
+
        printk("new trace = 0x%08X\n",yaffs_traceMask);
-       
+
        if (rg & YAFFS_TRACE_ALWAYS) {
                for (i = 0; mask_flags[i].mask_name != NULL; i++) {
                        char flag;