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