generic: make yaffs work on 3.6
Signed-off-by: Gabor Juhos <juhosg@openwrt.org> SVN-Revision: 34054
This commit is contained in:
parent
ffcb4b0fe1
commit
0005762690
5 changed files with 341 additions and 0 deletions
|
@ -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")));
|
|
@ -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")));
|
||||
|
|
@ -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;
|
|
@ -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))
|
|
@ -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 <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/xattr.h>
|
||||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
|
||||
+#include <linux/workqueue.h>
|
||||
+#endif
|
||||
|
||||
#define YCHAR char
|
||||
#define YUCHAR unsigned char
|
Loading…
Reference in a new issue