patch-2.4.11-dontuse linux/fs/jffs2/scan.c

Next file: linux/fs/jffs2/super.c
Previous file: linux/fs/jffs2/pushpull.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/scan.c linux/fs/jffs2/scan.c
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: scan.c,v 1.44 2001/04/13 00:46:41 nico Exp $
+ * $Id: scan.c,v 1.51 2001/09/19 00:06:35 dwmw2 Exp $
  *
  */
 #include <linux/kernel.h>
@@ -76,6 +76,8 @@
 int jffs2_scan_medium(struct jffs2_sb_info *c)
 {
 	int i, ret;
+	__u32 empty_blocks = 0;
+
 	if (!c->blocks) {
 		printk(KERN_WARNING "EEEK! c->blocks is NULL!\n");
 		return -EINVAL;
@@ -84,13 +86,24 @@
 		struct jffs2_eraseblock *jeb = &c->blocks[i];
 
 		ret = jffs2_scan_eraseblock(c, jeb);
-		if (ret)
+		if (ret < 0)
 			return ret;
 
 		ACCT_PARANOIA_CHECK(jeb);
 
-		   /* Now decide which list to put it on */
-		if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
+		/* Now decide which list to put it on */
+		if (ret == 1) {
+			/* 
+			 * Empty block.   Since we can't be sure it 
+			 * was entirely erased, we just queue it for erase
+			 * again.  It will be marked as such when the erase
+			 * is complete.  Meanwhile we still count it as empty
+			 * for later checks.
+			 */
+			list_add(&jeb->list, &c->erase_pending_list);
+			empty_blocks++;
+			c->nr_erasing_blocks++;
+		} else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
 			/* Only a CLEANMARKER node is valid */
 			if (!jeb->dirty_size) {
 				/* It's actually free */
@@ -127,11 +140,15 @@
 			printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset);
                         list_add(&jeb->list, &c->erase_pending_list);
 			c->nr_erasing_blocks++;
-                }
-        }
-	if (c->nr_erasing_blocks)
+		}
+	}
+	if (c->nr_erasing_blocks) {
+		if (!c->used_size && empty_blocks != c->nr_blocks) {
+			printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
+			return -EIO;
+		}
 		jffs2_erase_pending_trigger(c);
-
+	}
 	return 0;
 }
 
@@ -140,13 +157,22 @@
 	__u32 ofs, prevofs;
 	__u32 hdr_crc, nodetype;
 	int err;
-	int noise = 10;
+	int noise = 0;
 
 	ofs = jeb->offset;
 	prevofs = jeb->offset - 1;
 
 	D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
 
+	err = jffs2_scan_empty(c, jeb, &ofs, &noise);
+	if (err) return err;
+	if (ofs == jeb->offset + c->sector_size) {
+		D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
+		return 1;	/* special return code */
+	}
+	
+	noise = 10;
+
 	while(ofs < jeb->offset + c->sector_size) {
 		ssize_t retlen;
 		ACCT_PARANOIA_CHECK(jeb);
@@ -272,6 +298,8 @@
 			case JFFS2_FEATURE_ROCOMPAT:
 				printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
 			        c->flags |= JFFS2_SB_FLAG_RO;
+				if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY))
+					return -EROFS;
 				DIRTY_SPACE(PAD(node.totlen));
 				ofs += PAD(node.totlen);
 				continue;
@@ -306,7 +334,7 @@
 	__u32 scanlen = (jeb->offset + c->sector_size) - *startofs;
 	__u32 curofs = *startofs;
 	
-	buf = kmalloc(min(PAGE_SIZE, scanlen), GFP_KERNEL);
+	buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL);
 	if (!buf) {
 		printk(KERN_WARNING "Scan buffer allocation failed\n");
 		return -ENOMEM;
@@ -315,9 +343,9 @@
 		ssize_t retlen;
 		int ret, i;
 		
-		ret = c->mtd->read(c->mtd, curofs, min(PAGE_SIZE, scanlen), &retlen, (char *)buf);
+		ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf);
 		if(ret) {
-			D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%lx bytes at 0x%08x returned %d\n", min(PAGE_SIZE, scanlen), curofs, ret));
+			D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret));
 			kfree(buf);
 			return ret;
 		}
@@ -606,6 +634,8 @@
 	if (crc != rd.name_crc) {
 		printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
 		       *ofs, rd.name_crc, crc);	
+		fd->name[rd.nsize]=0;
+		D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));
 		jffs2_free_full_dirent(fd);
 		/* FIXME: Why do we believe totlen? */
 		DIRTY_SPACE(PAD(rd.totlen));

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)