mtd/fs/jffs2 background.c,1.23,1.24 fs.c,1.7,1.8 wbuf.c,1.10,1.11
gleixner at infradead.org
gleixner at infradead.org
Sun Apr 28 09:43:05 EDT 2002
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv9266/mtd/fs/jffs2
Modified Files:
background.c fs.c wbuf.c
Log Message:
timed wbuf flush on NAND devices added
Index: background.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/background.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- background.c 6 Mar 2002 12:37:08 -0000 1.23
+++ background.c 28 Apr 2002 13:43:03 -0000 1.24
@@ -38,12 +38,12 @@
#define __KERNEL_SYSCALLS__
#include <linux/kernel.h>
-#include <linux/unistd.h>
#include <linux/jffs2.h>
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/mtd/compatmac.h> /* recalc_sigpending() */
+#include <linux/unistd.h>
#include "nodelist.h"
@@ -86,6 +86,13 @@
void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
{
+ if (c->mtd->type == MTD_NANDFLASH) {
+ /* stop a eventually scheduled wbuf flush timer */
+ del_timer_sync(&c->wbuf_timer);
+ /* make sure, that a scheduled wbuf flush task is completed */
+ flush_scheduled_tasks();
+ }
+
spin_lock_bh(&c->erase_completion_lock);
if (c->gc_task) {
D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid));
Index: fs.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/fs.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- fs.c 3 Apr 2002 09:03:09 -0000 1.7
+++ fs.c 28 Apr 2002 13:43:03 -0000 1.8
@@ -408,16 +408,19 @@
c->sector_size = c->mtd->erasesize;
c->flash_size = c->mtd->size;
+#if 0
if (c->sector_size < 0x10000) {
printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using 64KiB instead\n",
c->sector_size / 1024);
c->sector_size = 0x10000;
}
+#endif
if (c->flash_size < 5*c->sector_size) {
printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n",
c->flash_size / c->sector_size);
return -EINVAL;
}
+
if (c->mtd->type == MTD_NANDFLASH) {
/* Initialise write buffer */
c->wbuf_pagesize = c->mtd->oobblock;
@@ -425,6 +428,13 @@
c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
if (!c->wbuf)
goto out_mtd;
+
+ /* Initialize process for timed wbuf flush */
+ INIT_TQUEUE(&c->wbuf_task,(void*) jffs2_wbuf_process, (void *)c);
+ /* Initialize timer for timed wbuf flush */
+ init_timer(&c->wbuf_timer);
+ c->wbuf_timer.function = jffs2_wbuf_timeout;
+ c->wbuf_timer.data = (unsigned long) c;
}
if (jffs2_do_mount_fs(c))
Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- wbuf.c 28 Mar 2002 11:05:27 -0000 1.10
+++ wbuf.c 28 Apr 2002 13:43:03 -0000 1.11
@@ -40,19 +40,15 @@
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
#include <linux/crc32.h>
+#include <linux/mtd/nand.h>
#include "nodelist.h"
-/* FIXME duplicated defines in wbuf.c and nand.c
- * Constants for out of band layout
- */
-#define NAND_JFFS2_OOB_BADBPOS 5
-#define NAND_JFFS2_OOB8_FSDAPOS 6
-#define NAND_JFFS2_OOB16_FSDAPOS 8
-#define NAND_JFFS2_OOB8_FSDALEN 2
-#define NAND_JFFS2_OOB16_FSDALEN 8
-
+/* max. erase failures before we mark a block bad */
#define MAX_ERASE_FAILURES 5
+/* two seconds timeout for timed wbuf-flushing */
+#define WBUF_FLUSH_TIMEOUT 2 * HZ
+
static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
{
struct list_head *this, *next;
@@ -82,6 +78,46 @@
}
}
+/*
+* Timed flushing of wbuf. If we have no consecutive write to wbuf, within
+* the specified time, we flush the contents with padding !
+*/
+void jffs2_wbuf_timeout (unsigned long data)
+{
+ struct jffs2_sb_info *c = (struct jffs2_sb_info *) data;
+ /*
+ * Wake up the flush process, we need process context to have the right
+ * to sleep on flash write
+ */
+ D1(printk(KERN_DEBUG "jffs2_wbuf_timeout(): timer expired\n"));
+ schedule_task(&c->wbuf_task);
+}
+
+/*
+* Process for timed wbuf flush
+*
+* FIXME What happens, if we have a write failure there ????
+*/
+void jffs2_wbuf_process (void *data)
+{
+ struct jffs2_sb_info *c = (struct jffs2_sb_info *) data;
+
+ D1(printk(KERN_DEBUG "jffs2_wbuf_process() entered\n"));
+
+ if (!down_trylock(&c->alloc_sem)) {
+ D1(printk (KERN_DEBUG "jffs2_wbuf_process() alloc_sem got\n"));
+
+ if(!c->nextblock || (c->nextblock->free_size < (c->wbuf_pagesize - c->wbuf_len)))
+ jffs2_flush_wbuf(c, 1); /* pad only */
+ else
+ jffs2_flush_wbuf(c, 2); /* pad and adjust nextblock */
+ up(&c->alloc_sem);
+ } else {
+ D1(printk (KERN_DEBUG "jffs2_wbuf_process() alloc_sem already occupied\n"));
+ }
+}
+
+
/* Meaning of pad argument:
0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway.
1: Pad, do not adjust nextblock free_size
@@ -98,6 +134,9 @@
BUG();
}
+ /* delete a eventually started timed wbuf flush */
+ del_timer_sync(&c->wbuf_timer);
+
if(!c->wbuf || !c->wbuf_len)
return 0;
@@ -366,6 +405,11 @@
alldone:
*retlen = donelen;
+ /* Setup timed wbuf flush, if buffer len != 0 */
+ if (c->wbuf_len) {
+ D1(printk (KERN_DEBUG "jffs2_flash_writev: mod wbuf_timer\n"));
+ mod_timer(&c->wbuf_timer, jiffies + WBUF_FLUSH_TIMEOUT);
+ }
return 0;
}
More information about the linux-mtd-cvs
mailing list