Root/target/linux/generic/patches-3.6/514-yaffs-3.6-use-delayed-work-instead-of-write_super.patch

1--- a/fs/yaffs2/yaffs_vfs_glue.c
2+++ b/fs/yaffs2/yaffs_vfs_glue.c
3@@ -393,6 +393,84 @@ static void yaffs_touch_super(yaffs_dev_
4 static int yaffs_vfs_setattr(struct inode *, struct iattr *);
5 
6 
7+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8+
9+#define yaffs_super_to_dev(sb) ((struct yaffs_dev_s *)sb->s_fs_info)
10+
11+static inline struct yaffs_LinuxContext *
12+yaffs_sb_to_ylc(struct super_block *sb)
13+{
14+ struct yaffs_dev_s *ydev;
15+ struct yaffs_LinuxContext *ylc;
16+
17+ ydev = yaffs_super_to_dev(sb);
18+ ylc = yaffs_dev_to_lc(ydev);
19+ return ylc;
20+}
21+
22+static inline struct super_block *yaffs_work_to_sb(struct work_struct *work)
23+{
24+ struct delayed_work *dwork;
25+ struct yaffs_LinuxContext *ylc;
26+
27+ dwork = container_of(work, struct delayed_work, work);
28+ ylc = container_of(dwork, struct yaffs_LinuxContext, sb_sync_dwork);
29+ return ylc->superBlock;
30+}
31+
32+static void yaffs_sb_sync_dwork_func(struct work_struct *work)
33+{
34+ struct super_block *sb = yaffs_work_to_sb(work);
35+
36+ yaffs_write_super(sb);
37+}
38+
39+static void yaffs_init_sb_sync_dwork(struct yaffs_LinuxContext *ylc)
40+{
41+ INIT_DELAYED_WORK(&ylc->sb_sync_dwork, yaffs_sb_sync_dwork_func);
42+}
43+
44+static void yaffs_cancel_sb_sync_dwork(struct super_block *sb)
45+{
46+ struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb);
47+
48+ cancel_delayed_work_sync(&ylc->sb_sync_dwork);
49+}
50+
51+static inline bool yaffs_sb_is_dirty(struct super_block *sb)
52+{
53+ struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb);
54+
55+ return !!ylc->sb_dirty;
56+}
57+
58+static inline void yaffs_sb_set_dirty(struct super_block *sb, int dirty)
59+{
60+ struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb);
61+
62+ if (ylc->sb_dirty == dirty)
63+ return;
64+
65+ ylc->sb_dirty = dirty;
66+ if (dirty)
67+ queue_delayed_work(system_long_wq, &ylc->sb_sync_dwork,
68+ msecs_to_jiffies(5000));
69+}
70+#else
71+static inline bool yaffs_sb_is_dirty(struct super_block *sb)
72+{
73+ return !!sb->s_dirt;
74+}
75+
76+static inline void yaffs_sb_set_dirty(struct super_block *sb, int dirty)
77+{
78+ sb->s_dirt = dirty;
79+}
80+
81+static inline void yaffs_init_sb_sync_dwork(struct yaffs_LinuxContext *ylc) {}
82+static inline void yaffs_cancel_sb_sync_dwork(struct super_block *sb) {}
83+#endif /* >= 3.6.0 */
84+
85 static struct address_space_operations yaffs_file_address_operations = {
86     .readpage = yaffs_readpage,
87     .writepage = yaffs_writepage,
88@@ -553,7 +631,9 @@ static const struct super_operations yaf
89     .clear_inode = yaffs_clear_inode,
90 #endif
91     .sync_fs = yaffs_sync_fs,
92+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
93     .write_super = yaffs_write_super,
94+#endif
95 };
96 
97 
98@@ -2340,7 +2420,7 @@ static int yaffs_do_sync_fs(struct super
99     T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
100         (TSTR("yaffs_do_sync_fs: gc-urgency %d %s %s%s\n"),
101         gc_urgent,
102- sb->s_dirt ? "dirty" : "clean",
103+ yaffs_sb_is_dirty(sb) ? "dirty" : "clean",
104         request_checkpoint ? "checkpoint requested" : "no checkpoint",
105         oneshot_checkpoint ? " one-shot" : "" ));
106 
107@@ -2349,9 +2429,9 @@ static int yaffs_do_sync_fs(struct super
108             oneshot_checkpoint) &&
109             !dev->is_checkpointed;
110 
111- if (sb->s_dirt || do_checkpoint) {
112+ if (yaffs_sb_is_dirty(sb) || do_checkpoint) {
113         yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint);
114- sb->s_dirt = 0;
115+ yaffs_sb_set_dirty(sb, 0);
116         if(oneshot_checkpoint)
117             yaffs_auto_checkpoint &= ~4;
118     }
119@@ -2627,6 +2707,8 @@ static void yaffs_put_super(struct super
120 
121     yaffs_flush_super(sb,1);
122 
123+ yaffs_cancel_sb_sync_dwork(sb);
124+
125     if (yaffs_dev_to_lc(dev)->putSuperFunc)
126         yaffs_dev_to_lc(dev)->putSuperFunc(sb);
127 
128@@ -2665,7 +2747,7 @@ static void yaffs_touch_super(yaffs_dev_
129 
130     T(YAFFS_TRACE_OS, (TSTR("yaffs_touch_super() sb = %p\n"), sb));
131     if (sb)
132- sb->s_dirt = 1;
133+ yaffs_sb_set_dirty(sb, 1);
134 }
135 
136 typedef struct {
137@@ -2991,6 +3073,8 @@ static struct super_block *yaffs_interna
138     context->dev = dev;
139     context->superBlock = sb;
140 
141+ yaffs_init_sb_sync_dwork(context);
142+
143     dev->read_only = read_only;
144 
145 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
146@@ -3177,7 +3261,7 @@ static struct super_block *yaffs_interna
147         return NULL;
148     }
149     sb->s_root = root;
150- sb->s_dirt = !dev->is_checkpointed;
151+ yaffs_sb_set_dirty(sb, !dev->is_checkpointed);
152     T(YAFFS_TRACE_ALWAYS,
153         (TSTR("yaffs_read_super: is_checkpointed %d\n"),
154         dev->is_checkpointed));
155--- a/fs/yaffs2/yaffs_linux.h
156+++ b/fs/yaffs2/yaffs_linux.h
157@@ -34,6 +34,11 @@ struct yaffs_LinuxContext {
158 
159     struct task_struct *readdirProcess;
160     unsigned mount_id;
161+
162+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
163+ struct delayed_work sb_sync_dwork; /* superblock write-out work */
164+ int sb_dirty; /* superblock is dirty */
165+#endif
166 };
167 
168 #define yaffs_dev_to_lc(dev) ((struct yaffs_LinuxContext *)((dev)->os_context))
169--- a/fs/yaffs2/yportenv.h
170+++ b/fs/yaffs2/yportenv.h
171@@ -49,6 +49,9 @@
172 #include <linux/slab.h>
173 #include <linux/vmalloc.h>
174 #include <linux/xattr.h>
175+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
176+#include <linux/workqueue.h>
177+#endif
178 
179 #define YCHAR char
180 #define YUCHAR unsigned char
181

Archive Download this file



interactive