Add Waldemar's patches for Linux 3.2
authorCharles Manning <cdhmanning@gmail.com>
Mon, 13 Feb 2012 02:30:01 +0000 (15:30 +1300)
committerCharles Manning <cdhmanning@gmail.com>
Mon, 13 Feb 2012 02:30:01 +0000 (15:30 +1300)
Also rolled in some suggestions for the multi-version code.

Signed-off-by: Charles Manning <cdhmanning@gmail.com>
.gitignore
Makefile
yaffs_mtdif1_multi.c
yaffs_mtdif1_single.c
yaffs_mtdif2_multi.c
yaffs_mtdif2_single.c
yaffs_vfs_multi.c
yaffs_vfs_single.c
yportenv.h [new file with mode: 0644]

index 97f1da3..d4f60ef 100644 (file)
@@ -5,4 +5,12 @@
 *.pyc
 DEADJOE
 *.mod.c
+*.order
 
+/Module.symvers
+/.tmp_versions
+
+#
+# cscope files
+#
+cscope.*
index db1b5c2..6722182 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@
 
 ifdef YAFFS_CURRENT
        YAFFS_O := yaffs2.o
+       EXTRA_CFLAGS += -DYAFFS_CURRENT
 else
        YAFFS_O := yaffs2multi.o
 endif
index 3673891..14d5c6f 100644 (file)
 #include "linux/types.h"
 #include "linux/mtd/mtd.h"
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
 /* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
 #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
 
@@ -124,7 +129,7 @@ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
        }
 
        memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.len = (data) ? chunk_bytes : 0;
        ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
        ops.datbuf = (u8 *) data;
@@ -177,7 +182,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
        int deleted;
 
        memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.len = (data) ? chunk_bytes : 0;
        ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
        ops.datbuf = data;
index 467a031..a6907bf 100644 (file)
@@ -97,7 +97,7 @@ int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
         }
 
        memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.len = (data) ? chunk_bytes : 0;
        ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
        ops.datbuf = (u8 *) data;
@@ -150,7 +150,7 @@ int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
        int deleted;
 
        memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.len = (data) ? chunk_bytes : 0;
        ops.ooblen =  dev->param.tags_9bytes ? 9 : 8;
        ops.datbuf = data;
@@ -259,7 +259,7 @@ int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no)
  *
  * Returns YAFFS_OK or YAFFS_FAIL.
  */
-static int nandmtd1_test_prerequists(struct mtd_info *mtd)
+static int nandmtd1_test_prerequists(struct yaffs_dev *dev, struct mtd_info *mtd)
 {
        /* 2.6.18 has mtd->ecclayout->oobavail */
        /* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
@@ -268,7 +268,7 @@ static int nandmtd1_test_prerequists(struct mtd_info *mtd)
        if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) {
                yaffs_trace(YAFFS_TRACE_ERROR,
                        "mtd device has only %d bytes for tags, need %d",
-                       oobavail, (dev->param.tags_9bytes ? 9 : 8);
+                       oobavail, (dev->param.tags_9bytes ? 9 : 8));
                return YAFFS_FAIL;
        }
        return YAFFS_OK;
@@ -297,7 +297,7 @@ int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
        /* We don't yet have a good place to test for MTD config prerequists.
         * Do it here as we are called during the initial scan.
         */
-       if (nandmtd1_test_prerequists(mtd) != YAFFS_OK)
+       if (nandmtd1_test_prerequists(dev, mtd) != YAFFS_OK)
                return YAFFS_FAIL;
 
        retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
index 684ed2a..18ac992 100644 (file)
 
 #include "yaffs_linux.h"
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
+
 /* NB For use with inband tags....
  * We assume that the data buffer is of size total_bytes_per_chunk so
  * that we can also use it to load the tags.
@@ -75,7 +81,7 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
        }
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
        ops.len = dev->param.total_bytes_per_chunk;
        ops.ooboffs = 0;
@@ -139,7 +145,7 @@ int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
                retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
                                   &dummy, data);
        else if (tags) {
-               ops.mode = MTD_OOB_AUTO;
+               ops.mode = MTD_OPS_AUTO_OOB;
                ops.ooblen = packed_tags_size;
                ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
                ops.ooboffs = 0;
index c013232..f92c49f 100644 (file)
@@ -21,6 +21,7 @@
 #include "linux/mtd/mtd.h"
 #include "linux/types.h"
 #include "linux/time.h"
+#include "mtd/mtd-abi.h"
 
 
 /* NB For use with inband tags....
@@ -64,7 +65,7 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
                yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
        }
 
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
        ops.len = dev->param.total_bytes_per_chunk;
        ops.ooboffs = 0;
@@ -106,7 +107,7 @@ int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
                retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
                                   &dummy, data);
        } else if (tags) {
-               ops.mode = MTD_OOB_AUTO;
+               ops.mode = MTD_OPS_AUTO_OOB;
                ops.ooblen = packed_tags_size;
                ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
                ops.ooboffs = 0;
index b8e5124..fdb0137 100644 (file)
 #define YAFFS_USE_WRITE_BEGIN_END 0
 #endif
 
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define set_nlink(inode, count)  do { (inode)->i_nlink = (count); } while(0)
+#endif
+
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
 static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
 {
@@ -1330,7 +1336,7 @@ static void yaffs_fill_inode_from_obj(struct inode *inode,
                inode->i_size = yaffs_get_obj_length(obj);
                inode->i_blocks = (inode->i_size + 511) >> 9;
 
-               inode->i_nlink = yaffs_get_obj_link_count(obj);
+               set_nlink(inode, yaffs_get_obj_link_count(obj));
 
                yaffs_trace(YAFFS_TRACE_OS,
                        "yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
@@ -1744,10 +1750,9 @@ static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
        ret_val = yaffs_unlinker(obj, dentry->d_name.name);
 
        if (ret_val == YAFFS_OK) {
-               dentry->d_inode->i_nlink--;
+               inode_dec_link_count(dentry->d_inode);
                dir->i_version++;
                yaffs_gross_unlock(dev);
-               mark_inode_dirty(dentry->d_inode);
                update_dir_time(dir);
                return 0;
        }
@@ -1779,7 +1784,7 @@ static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
                                   obj);
 
        if (link) {
-               old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+               set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
                d_instantiate(dentry, old_dentry->d_inode);
                atomic_inc(&old_dentry->d_inode->i_count);
                yaffs_trace(YAFFS_TRACE_OS,
@@ -1809,6 +1814,14 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
 
        yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
 
+       if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
+                               YAFFS_MAX_NAME_LENGTH)
+               return -ENAMETOOLONG;
+
+       if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
+                               YAFFS_MAX_ALIAS_LENGTH)
+               return -ENAMETOOLONG;
+
        dev = yaffs_inode_to_obj(dir)->my_dev;
        yaffs_gross_lock(dev);
        obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
@@ -1897,10 +1910,8 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
        yaffs_gross_unlock(dev);
 
        if (ret_val == YAFFS_OK) {
-               if (target) {
-                       new_dentry->d_inode->i_nlink--;
-                       mark_inode_dirty(new_dentry->d_inode);
-               }
+               if (target)
+                       inode_dec_link_count(new_dentry->d_inode);
 
                update_dir_time(old_dir);
                if (old_dir != new_dir)
index f822845..d8379d4 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/mtd/mtd.h>
 #include <linux/interrupt.h>
@@ -307,7 +306,7 @@ static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
                                   obj);
 
        if (link) {
-               old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+               set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
                d_instantiate(dentry, old_dentry->d_inode);
                atomic_inc(&old_dentry->d_inode->i_count);
                yaffs_trace(YAFFS_TRACE_OS,
@@ -338,6 +337,14 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
 
        yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
 
+       if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
+                               YAFFS_MAX_NAME_LENGTH)
+               return -ENAMETOOLONG;
+
+       if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
+                               YAFFS_MAX_ALIAS_LENGTH)
+               return -ENAMETOOLONG;
+
        dev = yaffs_inode_to_obj(dir)->my_dev;
        yaffs_gross_lock(dev);
        obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
@@ -419,10 +426,9 @@ static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
        ret_val = yaffs_unlinker(obj, dentry->d_name.name);
 
        if (ret_val == YAFFS_OK) {
-               dentry->d_inode->i_nlink--;
+               inode_dec_link_count(dentry->d_inode);
                dir->i_version++;
                yaffs_gross_unlock(dev);
-               mark_inode_dirty(dentry->d_inode);
                update_dir_time(dir);
                return 0;
        }
@@ -430,7 +436,7 @@ static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
        return -ENOTEMPTY;
 }
 
-static int yaffs_sync_object(struct file *file, int datasync)
+static int yaffs_sync_object(struct file *file, loff_t start, loff_t end, int datasync)
 {
 
        struct yaffs_obj *obj;
@@ -486,10 +492,8 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
        yaffs_gross_unlock(dev);
 
        if (ret_val == YAFFS_OK) {
-               if (target) {
-                       new_dentry->d_inode->i_nlink--;
-                       mark_inode_dirty(new_dentry->d_inode);
-               }
+               if (target)
+                       inode_dec_link_count(new_dentry->d_inode);
 
                update_dir_time(old_dir);
                if (old_dir != new_dir)
@@ -1873,7 +1877,7 @@ static void yaffs_fill_inode_from_obj(struct inode *inode,
        inode->i_ctime.tv_nsec = 0;
        inode->i_size = yaffs_get_obj_length(obj);
        inode->i_blocks = (inode->i_size + 511) >> 9;
-       inode->i_nlink = yaffs_get_obj_link_count(obj);
+       set_nlink(inode, yaffs_get_obj_link_count(obj));
        yaffs_trace(YAFFS_TRACE_OS,
                "yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
                inode->i_mode, inode->i_uid, inode->i_gid,
@@ -2292,19 +2296,18 @@ static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
        return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
 }
 
-static int yaffs_read_super(struct file_system_type *fs,
+static struct dentry *yaffs_mount(struct file_system_type *fs,
                            int flags, const char *dev_name,
-                           void *data, struct vfsmount *mnt)
+                           void *data)
 {
-
-       return get_sb_bdev(fs, flags, dev_name, data,
-                          yaffs_internal_read_super_mtd, mnt);
+       return mount_bdev(fs, flags, dev_name, data,
+                          yaffs_internal_read_super_mtd);
 }
 
 static struct file_system_type yaffs_fs_type = {
        .owner = THIS_MODULE,
        .name = "yaffs",
-       .get_sb = yaffs_read_super,
+       .mount = yaffs_mount,
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
@@ -2315,18 +2318,17 @@ static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
        return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
 }
 
-static int yaffs2_read_super(struct file_system_type *fs,
-                            int flags, const char *dev_name, void *data,
-                            struct vfsmount *mnt)
+static struct dentry *yaffs2_mount(struct file_system_type *fs,
+                            int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs, flags, dev_name, data,
-                          yaffs2_internal_read_super_mtd, mnt);
+       return mount_bdev(fs, flags, dev_name, data,
+                          yaffs2_internal_read_super_mtd);
 }
 
 static struct file_system_type yaffs2_fs_type = {
        .owner = THIS_MODULE,
        .name = "yaffs2",
-       .get_sb = yaffs2_read_super,
+       .mount = yaffs2_mount,
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
diff --git a/yportenv.h b/yportenv.h
new file mode 100644 (file)
index 0000000..d4a9178
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Waldemar Rymarkiewicz <waldemar.rymarkiewicz@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifdef YAFFS_CURRENT
+       #include "yportenv_single.h"
+#else
+       #include "yportenv_multi.h"
+#endif