[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch 2] mkfs.jffs2



ECC NOR flash does not allow any page (8 bytes or so) to be written
twice between erases. Since some flashers even write 0xff to flash,
this does make a diffence. The flash looks empty but cannot be written
anymore.
My solution is to pad the output of mkfs.jffs2 with a node, instead of
0xff. Now the erase blocks in question will not be written to, until
garbage collection explicitly erases them.
A command line option is added to turn this behaviour on.

Joern

Index: mkfs.jffs2.1
===================================================================
RCS file: /home/cvs/mtd/util/mkfs.jffs2.1,v
retrieving revision 1.2
diff -u -p -u -r1.2 mkfs.jffs2.1
--- mkfs.jffs2.1	24 Apr 2001 01:48:52 -0000	1.2
+++ mkfs.jffs2.1	11 Jul 2002 13:01:13 -0000
@xxxxxxx.  Default
 Pad output to SIZE bytes with 0xFF.  If SIZE is not specified,
 the output is padded to the end of the final erase block.
 .TP
+.B -n, --nodepad
+Same as --pad, but padding is done with a padding node whenever
+possible.
+.TP
 .B -r, -d, --root=DIR
 Build filesystem from directory DIR.  The default is the current
 directory.


--- mkfs.jffs2.c.orig	Thu Jul 11 14:25:03 2002
+++ mkfs.jffs2.c	Thu Jul 11 14:25:40 2002
@@ -4,6 +4,7 @@
  * Copyright 2001, 2002 Red Hat, Inc.
  *           2001 David A. Schleef <ds@xxxxxxx.com>
  *           2001 Erik Andersen <andersen@xxxxxxx.org>
+ *           2002 Joern Engel <joern@xxxxxxx.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,6 +31,10 @@
  *
  * I also added a sample device table file.  See device_table.txt
  *  -Erik, Septermber 2001
+ *
+ * July 2002, Joern Engel
+ * - fixed some sprintf() to snprintf(). This might be suid root.
+ * - added padding node for ECC'd NOR flashes
  */
 
 /* $Id: mkfs.jffs2.c,v 1.26 2002/07/03 22:20:13 dwmw2 Exp $ */
@@ -105,6 +110,7 @@
 #endif
 
 static int erase_block_size = 65536;
+static int pad_with_nodes = 0;
 static int pad_fs_size = 0;
 static int page_size = 4096;
 static int out_fd = 1;
@@ -497,7 +503,7 @@
 	return (new_entry);
 }
 
-static void padblock(void)
+static void padblock_with_ff(void)
 {
 	while (out_ofs % erase_block_size) {
 		full_write(out_fd, ffbuf, 
@@ -505,6 +511,30 @@
 	}
 }
 
+static void padblock_with_node(void)
+{
+	if (!(out_ofs % erase_block_size))
+		return;
+	if (erase_block_size - (out_ofs % erase_block_size)
+			>= sizeof(struct jffs2_unknown_node)) {
+		struct jffs2_unknown_node pad;
+		pad.magic = cpu_to_target16(JFFS2_MAGIC_BITMASK);
+		pad.nodetype = JFFS2_NODETYPE_PADDING;
+		pad.totlen = erase_block_size - (out_ofs % erase_block_size);
+		pad.hdr_crc = cpu_to_target32(crc32(0, &pad, sizeof(pad) - 4));
+		full_write(out_fd, &pad, sizeof(pad));
+	}
+	padblock_with_ff();
+}
+
+static void padblock(void)
+{
+	if (pad_with_nodes)
+		padblock_with_node();
+	else
+		padblock_with_ff();
+}
+
 static inline void pad_block_if_less_than(int req)
 {
 	if ((out_ofs % erase_block_size) + req > erase_block_size) {
@@ -757,7 +787,7 @@
 	struct directory_entry *parent;
 
 
-	sprintf(path, "%s", dname);
+	snprintf(path, sizeof(path), "%s", dname);
 
 	if (lstat(path, &sb)) {
 		perror_msg_and_die("%s", path);
@@ -776,9 +806,9 @@
 			continue;
 		}
 		if (strcmp(dname, ".") == 0)
-			sprintf(path, "%s", dp->d_name);
+			snprintf(path, sizeof(path), "%s", dp->d_name);
 		else
-			sprintf(path, "%s/%s", dname, dp->d_name);
+			snprintf(path, sizeof(path), "%s/%s", dname, dp->d_name);
 		if (lstat(path, &sb)) {
 			perror_msg_and_die("%s", path);
 		}
@@ -845,7 +875,7 @@
 		error_msg_and_die("Device table entries require absolute paths");
 	}
 	name = xstrdup(path + 1);
-	sprintf(path, "%s/%s", rootdir, name);
+	snprintf(path, sizeof(path), "%s/%s", rootdir, name);
 
 	switch (type) {
 	case 'd':
@@ -869,7 +899,7 @@
 			char buf[80];
 
 			for (i = start; i < count; i++) {
-				sprintf(buf, "%s%d", name, i);
+				snprintf(buf, sizeof(buf), "%s%d", name, i);
 				/* FIXME:  MKDEV uses illicit insider knowledge of kernel 
 				 * major/minor representation...  */
 				rdev = MKDEV(major, minor + (i * increment - start));
@@ -1099,6 +1129,7 @@
 
 static struct option long_options[] = {
 	{"pad", 2, NULL, 'p'},
+	{"nodepad", 0, NULL, 'n'},
 	{"root", 1, NULL, 'r'},
 	{"pagesize", 1, NULL, 's'},
 	{"eraseblock", 1, NULL, 'e'},
@@ -1122,6 +1153,8 @@
 	"  -p, --pad[=SIZE]       Pad output to SIZE bytes with 0xFF. If SIZE is\n"
 	"                         not specified, the output is padded to the end of\n"
 	"                         the final erase block\n"
+	"  -n, --nodepad          Same as --pad, but padding is done with a padding node\n"
+	"                         instead of plain 0xFF, whenever possible\n"
 	"  -r, -d, --root=DIR     Build filesystem from directory DIR (default: cwd)\n"
 	"  -s, --pagesize=SIZE    Use page size (max data node size) SIZE (default: 4KiB)\n"
 	"  -e, --eraseblock=SIZE  Use erase block size SIZE (default: 64KiB)\n"
@@ -1146,7 +1179,7 @@
 	struct stat statbuf;
 	FILE *devtable = NULL;
 
-	while ((opt = getopt_long(argc, argv, "D:p::d:r:s:e:o:blqfh?v", 
+	while ((opt = getopt_long(argc, argv, "D:p::nd:r:s:e:o:blqfh?v", 
 			long_options, &c)) >= 0) {
 		switch (opt) {
 		case 'D':
@@ -1155,6 +1188,10 @@
 				perror_msg_and_die(optarg);
 			if (statbuf.st_size < 10)
 				error_msg_and_die("%s: not a proper device table file", optarg);
+			break;
+		case 'n':
+			pad_with_nodes = 1;
+			pad_fs_size = -1;
 			break;
 		case 'p':
 			if (optarg)

To unsubscribe from this list: send the line "unsubscribe jffs-dev" in
the body of a message to majordomo@xxxxxxx.com