From f840df94ddcdd184489532c9320b9332319a948c Mon Sep 17 00:00:00 2001 From: juhosg Date: Thu, 1 Nov 2012 11:07:23 +0000 Subject: [PATCH] generic: make yaffs work on 3.6 Signed-off-by: Gabor Juhos git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34054 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- ...-3.4-add-underscore-to-mtd-internal-names.patch | 72 +++++++++ .../510-yaffs-3.4-use-d_make_root.patch | 14 ++ .../511-yaffs-3.5-use-clear_inode.patch | 15 ++ .../512-yaffs-3.6-fix-dir_inode-ops.patch | 60 +++++++ ...6-use-delayed-work-instead-of-write_super.patch | 180 +++++++++++++++++++++ 5 files changed, 341 insertions(+) create mode 100644 target/linux/generic/patches-3.6/509-yaffs-3.4-add-underscore-to-mtd-internal-names.patch create mode 100644 target/linux/generic/patches-3.6/510-yaffs-3.4-use-d_make_root.patch create mode 100644 target/linux/generic/patches-3.6/511-yaffs-3.5-use-clear_inode.patch create mode 100644 target/linux/generic/patches-3.6/512-yaffs-3.6-fix-dir_inode-ops.patch create mode 100644 target/linux/generic/patches-3.6/513-yaffs-3.6-use-delayed-work-instead-of-write_super.patch diff --git a/target/linux/generic/patches-3.6/509-yaffs-3.4-add-underscore-to-mtd-internal-names.patch b/target/linux/generic/patches-3.6/509-yaffs-3.4-add-underscore-to-mtd-internal-names.patch new file mode 100644 index 0000000000..14f342da80 --- /dev/null +++ b/target/linux/generic/patches-3.6/509-yaffs-3.4-add-underscore-to-mtd-internal-names.patch @@ -0,0 +1,72 @@ +--- a/fs/yaffs2/yaffs_vfs_glue.c ++++ b/fs/yaffs2/yaffs_vfs_glue.c +@@ -2793,6 +2793,15 @@ static struct super_block *yaffs_interna + return NULL; + } + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) ++ T(YAFFS_TRACE_OS, (TSTR(" erase %p\n"), mtd->_erase)); ++ T(YAFFS_TRACE_OS, (TSTR(" read %p\n"), mtd->_read)); ++ T(YAFFS_TRACE_OS, (TSTR(" write %p\n"), mtd->_write)); ++ T(YAFFS_TRACE_OS, (TSTR(" readoob %p\n"), mtd->_read_oob)); ++ T(YAFFS_TRACE_OS, (TSTR(" writeoob %p\n"), mtd->_write_oob)); ++ T(YAFFS_TRACE_OS, (TSTR(" block_isbad %p\n"), mtd->_block_isbad)); ++ T(YAFFS_TRACE_OS, (TSTR(" block_markbad %p\n"), mtd->_block_markbad)); ++#else + T(YAFFS_TRACE_OS, (TSTR(" erase %p\n"), mtd->erase)); + T(YAFFS_TRACE_OS, (TSTR(" read %p\n"), mtd->read)); + T(YAFFS_TRACE_OS, (TSTR(" write %p\n"), mtd->write)); +@@ -2800,6 +2809,7 @@ static struct super_block *yaffs_interna + T(YAFFS_TRACE_OS, (TSTR(" writeoob %p\n"), mtd->write_oob)); + T(YAFFS_TRACE_OS, (TSTR(" block_isbad %p\n"), mtd->block_isbad)); + T(YAFFS_TRACE_OS, (TSTR(" block_markbad %p\n"), mtd->block_markbad)); ++#endif + T(YAFFS_TRACE_OS, (TSTR(" %s %d\n"), WRITE_SIZE_STR, WRITE_SIZE(mtd))); + T(YAFFS_TRACE_OS, (TSTR(" oobsize %d\n"), mtd->oobsize)); + T(YAFFS_TRACE_OS, (TSTR(" erasesize %d\n"), mtd->erasesize)); +@@ -2828,6 +2838,15 @@ static struct super_block *yaffs_interna + + if (yaffs_version == 2) { + /* Check for version 2 style functions */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) ++ if (!mtd->_erase || ++ !mtd->_block_isbad || ++ !mtd->_block_markbad || ++ !mtd->_read || ++ !mtd->_write || ++ !mtd->_read_oob || ++ !mtd->_write_oob) { ++#else + if (!mtd->erase || + !mtd->block_isbad || + !mtd->block_markbad || +@@ -2839,6 +2858,7 @@ static struct super_block *yaffs_interna + !mtd->write_ecc || + !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { + #endif ++#endif + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: MTD device does not support required " + "functions\n"))); +@@ -2855,6 +2875,13 @@ static struct super_block *yaffs_interna + } + } else { + /* Check for V1 style functions */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) ++ if (!mtd->_erase || ++ !mtd->_read || ++ !mtd->_write || ++ !mtd->_read_oob || ++ !mtd->_write_oob) { ++#else + if (!mtd->erase || + !mtd->read || + !mtd->write || +@@ -2864,6 +2891,7 @@ static struct super_block *yaffs_interna + !mtd->write_ecc || + !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { + #endif ++#endif + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: MTD device does not support required " + "functions\n"))); diff --git a/target/linux/generic/patches-3.6/510-yaffs-3.4-use-d_make_root.patch b/target/linux/generic/patches-3.6/510-yaffs-3.4-use-d_make_root.patch new file mode 100644 index 0000000000..0ef59d606e --- /dev/null +++ b/target/linux/generic/patches-3.6/510-yaffs-3.4-use-d_make_root.patch @@ -0,0 +1,14 @@ +--- a/fs/yaffs2/yaffs_vfs_glue.c ++++ b/fs/yaffs2/yaffs_vfs_glue.c +@@ -3119,7 +3119,11 @@ static struct super_block *yaffs_interna + + T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: got root inode\n"))); + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) ++ root = d_make_root(inode); ++#else + root = d_alloc_root(inode); ++#endif + + T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: d_alloc_root done\n"))); + diff --git a/target/linux/generic/patches-3.6/511-yaffs-3.5-use-clear_inode.patch b/target/linux/generic/patches-3.6/511-yaffs-3.5-use-clear_inode.patch new file mode 100644 index 0000000000..f4479675a2 --- /dev/null +++ b/target/linux/generic/patches-3.6/511-yaffs-3.5-use-clear_inode.patch @@ -0,0 +1,15 @@ +--- a/fs/yaffs2/yaffs_vfs_glue.c ++++ b/fs/yaffs2/yaffs_vfs_glue.c +@@ -924,7 +924,11 @@ static void yaffs_evict_inode( struct in + if (!inode->i_nlink && !is_bad_inode(inode)) + deleteme = 1; + truncate_inode_pages(&inode->i_data,0); +- end_writeback(inode); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) ++ clear_inode(inode); ++#else ++ end_writeback(inode); ++#endif + + if(deleteme && obj){ + dev = obj->my_dev; diff --git a/target/linux/generic/patches-3.6/512-yaffs-3.6-fix-dir_inode-ops.patch b/target/linux/generic/patches-3.6/512-yaffs-3.6-fix-dir_inode-ops.patch new file mode 100644 index 0000000000..f9db0b3fab --- /dev/null +++ b/target/linux/generic/patches-3.6/512-yaffs-3.6-fix-dir_inode-ops.patch @@ -0,0 +1,60 @@ +--- a/fs/yaffs2/yaffs_vfs_glue.c ++++ b/fs/yaffs2/yaffs_vfs_glue.c +@@ -272,20 +272,29 @@ static int yaffs_sync_object(struct file + + static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir); + +-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool excl); ++#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) + static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, + struct nameidata *n); +-#else ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) + static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *n); ++#else ++static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode); + #endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int flags); ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) + static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *n); + #else +-static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode); + static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry); + #endif ++ + static int yaffs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *dentry); + static int yaffs_unlink(struct inode *dir, struct dentry *dentry); +@@ -811,7 +820,10 @@ struct inode *yaffs_get_inode(struct sup + /* + * Lookup is used to find objects in the fs + */ +-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int flags) ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) + + static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *n) +@@ -1801,7 +1813,10 @@ static int yaffs_mkdir(struct inode *dir + return retVal; + } + +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool excl) ++#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) + static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, + struct nameidata *n) + #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) diff --git a/target/linux/generic/patches-3.6/513-yaffs-3.6-use-delayed-work-instead-of-write_super.patch b/target/linux/generic/patches-3.6/513-yaffs-3.6-use-delayed-work-instead-of-write_super.patch new file mode 100644 index 0000000000..579932c69e --- /dev/null +++ b/target/linux/generic/patches-3.6/513-yaffs-3.6-use-delayed-work-instead-of-write_super.patch @@ -0,0 +1,180 @@ +--- a/fs/yaffs2/yaffs_vfs_glue.c ++++ b/fs/yaffs2/yaffs_vfs_glue.c +@@ -394,6 +394,84 @@ static void yaffs_touch_super(yaffs_dev_ + static int yaffs_vfs_setattr(struct inode *, struct iattr *); + + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++ ++#define yaffs_super_to_dev(sb) ((struct yaffs_dev_s *)sb->s_fs_info) ++ ++static inline struct yaffs_LinuxContext * ++yaffs_sb_to_ylc(struct super_block *sb) ++{ ++ struct yaffs_dev_s *ydev; ++ struct yaffs_LinuxContext *ylc; ++ ++ ydev = yaffs_super_to_dev(sb); ++ ylc = yaffs_dev_to_lc(ydev); ++ return ylc; ++} ++ ++static inline struct super_block *yaffs_work_to_sb(struct work_struct *work) ++{ ++ struct delayed_work *dwork; ++ struct yaffs_LinuxContext *ylc; ++ ++ dwork = container_of(work, struct delayed_work, work); ++ ylc = container_of(dwork, struct yaffs_LinuxContext, sb_sync_dwork); ++ return ylc->superBlock; ++} ++ ++static void yaffs_sb_sync_dwork_func(struct work_struct *work) ++{ ++ struct super_block *sb = yaffs_work_to_sb(work); ++ ++ yaffs_write_super(sb); ++} ++ ++static void yaffs_init_sb_sync_dwork(struct yaffs_LinuxContext *ylc) ++{ ++ INIT_DELAYED_WORK(&ylc->sb_sync_dwork, yaffs_sb_sync_dwork_func); ++} ++ ++static void yaffs_cancel_sb_sync_dwork(struct super_block *sb) ++{ ++ struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb); ++ ++ cancel_delayed_work_sync(&ylc->sb_sync_dwork); ++} ++ ++static inline bool yaffs_sb_is_dirty(struct super_block *sb) ++{ ++ struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb); ++ ++ return !!ylc->sb_dirty; ++} ++ ++static inline void yaffs_sb_set_dirty(struct super_block *sb, int dirty) ++{ ++ struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb); ++ ++ if (ylc->sb_dirty == dirty) ++ return; ++ ++ ylc->sb_dirty = dirty; ++ if (dirty) ++ queue_delayed_work(system_long_wq, &ylc->sb_sync_dwork, ++ msecs_to_jiffies(5000)); ++} ++#else ++static inline bool yaffs_sb_is_dirty(struct super_block *sb) ++{ ++ return !!sb->s_dirt; ++} ++ ++static inline void yaffs_sb_set_dirty(struct super_block *sb, int dirty) ++{ ++ sb->s_dirt = dirty; ++} ++ ++static inline void yaffs_init_sb_sync_dwork(struct yaffs_LinuxContext *ylc) {} ++static inline void yaffs_cancel_sb_sync_dwork(struct super_block *sb) {} ++#endif /* >= 3.6.0 */ ++ + static struct address_space_operations yaffs_file_address_operations = { + .readpage = yaffs_readpage, + .writepage = yaffs_writepage, +@@ -527,7 +605,9 @@ static const struct super_operations yaf + .clear_inode = yaffs_clear_inode, + #endif + .sync_fs = yaffs_sync_fs, ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) + .write_super = yaffs_write_super, ++#endif + }; + + +@@ -2314,7 +2394,7 @@ static int yaffs_do_sync_fs(struct super + T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND, + (TSTR("yaffs_do_sync_fs: gc-urgency %d %s %s%s\n"), + gc_urgent, +- sb->s_dirt ? "dirty" : "clean", ++ yaffs_sb_is_dirty(sb) ? "dirty" : "clean", + request_checkpoint ? "checkpoint requested" : "no checkpoint", + oneshot_checkpoint ? " one-shot" : "" )); + +@@ -2323,9 +2403,9 @@ static int yaffs_do_sync_fs(struct super + oneshot_checkpoint) && + !dev->is_checkpointed; + +- if (sb->s_dirt || do_checkpoint) { ++ if (yaffs_sb_is_dirty(sb) || do_checkpoint) { + yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint); +- sb->s_dirt = 0; ++ yaffs_sb_set_dirty(sb, 0); + if(oneshot_checkpoint) + yaffs_auto_checkpoint &= ~4; + } +@@ -2601,6 +2681,8 @@ static void yaffs_put_super(struct super + + yaffs_flush_super(sb,1); + ++ yaffs_cancel_sb_sync_dwork(sb); ++ + if (yaffs_dev_to_lc(dev)->putSuperFunc) + yaffs_dev_to_lc(dev)->putSuperFunc(sb); + +@@ -2639,7 +2721,7 @@ static void yaffs_touch_super(yaffs_dev_ + + T(YAFFS_TRACE_OS, (TSTR("yaffs_touch_super() sb = %p\n"), sb)); + if (sb) +- sb->s_dirt = 1; ++ yaffs_sb_set_dirty(sb, 1); + } + + typedef struct { +@@ -2965,6 +3047,8 @@ static struct super_block *yaffs_interna + context->dev = dev; + context->superBlock = sb; + ++ yaffs_init_sb_sync_dwork(context); ++ + dev->read_only = read_only; + + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) +@@ -3151,7 +3235,7 @@ static struct super_block *yaffs_interna + return NULL; + } + sb->s_root = root; +- sb->s_dirt = !dev->is_checkpointed; ++ yaffs_sb_set_dirty(sb, !dev->is_checkpointed); + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs_read_super: is_checkpointed %d\n"), + dev->is_checkpointed)); +--- a/fs/yaffs2/yaffs_linux.h ++++ b/fs/yaffs2/yaffs_linux.h +@@ -34,6 +34,11 @@ struct yaffs_LinuxContext { + + struct task_struct *readdirProcess; + unsigned mount_id; ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++ struct delayed_work sb_sync_dwork; /* superblock write-out work */ ++ int sb_dirty; /* superblock is dirty */ ++#endif + }; + + #define yaffs_dev_to_lc(dev) ((struct yaffs_LinuxContext *)((dev)->os_context)) +--- a/fs/yaffs2/yportenv.h ++++ b/fs/yaffs2/yportenv.h +@@ -49,6 +49,9 @@ + #include + #include + #include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++#include ++#endif + + #define YCHAR char + #define YUCHAR unsigned char -- 2.11.0