mtd/fs/jffs2 gc.c,1.98,1.99

David Woodhouse dwmw2 at infradead.org
Wed Jan 22 07:08:00 EST 2003


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv26695

Modified Files:
	gc.c 
Log Message:
Fix GC of REF_PRISTINE dirent nodes. If you treat them like they're a data node
then the CRC is _going_ to fail :)


Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.98
retrieving revision 1.99
diff -u -r1.98 -r1.99
--- gc.c	21 Jan 2003 18:11:28 -0000	1.98
+++ gc.c	22 Jan 2003 12:07:58 -0000	1.99
@@ -458,7 +458,7 @@
 					  struct jffs2_inode_cache *ic,
 					  struct jffs2_raw_node_ref *raw)
 {
-	struct jffs2_raw_inode *ri;
+	union jffs2_node_union *node;
 	struct jffs2_raw_node_ref *nraw;
 	size_t retlen;
 	int ret;
@@ -467,7 +467,10 @@
 
 	D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw)));
 
-	ret = jffs2_reserve_space_gc(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN,
+	/* Ask for a small amount of space (or the totlen if smaller) because we
+	   don't want to force wastage of the end of a block if splitting would
+	   work. */
+	ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN, raw->totlen),
 				     &phys_ofs, &alloclen);
 	if (ret)
 		return ret;
@@ -477,43 +480,69 @@
 		return -EBADFD;
 	}
 
-	ri = kmalloc(raw->totlen, GFP_KERNEL);
-	if (!ri)
+	node = kmalloc(raw->totlen, GFP_KERNEL);
+	if (!node)
                return -ENOMEM;
 
-	ret = jffs2_flash_read(c, ref_offset(raw), raw->totlen, &retlen, (char *)ri);
+	ret = jffs2_flash_read(c, ref_offset(raw), raw->totlen, &retlen, (char *)node);
 	if (!ret && retlen != raw->totlen)
 		ret = -EIO;
 	if (ret)
-		goto out_ri;
+		goto out_node;
 
-	crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
-	if (je32_to_cpu(ri->hdr_crc) != crc) {
+	crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4);
+	if (je32_to_cpu(node->u.hdr_crc) != crc) {
 		printk(KERN_WARNING "Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-		       ref_offset(raw), je32_to_cpu(ri->hdr_crc), crc);
+		       ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc);
 		goto bail;
 	}
 
-	crc = crc32(0, ri, sizeof(*ri)-8);
-	if (je32_to_cpu(ri->node_crc) != crc) {
-		printk(KERN_WARNING "Node CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-		       ref_offset(raw), je32_to_cpu(ri->node_crc), crc);
-		goto bail;
-	}
+	switch(je16_to_cpu(node->u.nodetype)) {
+	case JFFS2_NODETYPE_INODE:
+		crc = crc32(0, node, sizeof(node->i)-8);
+		if (je32_to_cpu(node->i.node_crc) != crc) {
+			printk(KERN_WARNING "Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
+			       ref_offset(raw), je32_to_cpu(node->i.node_crc), crc);
+			goto bail;
+		}
 
-	if (je32_to_cpu(ri->dsize)) {
-		crc = crc32(0, &ri[1], je32_to_cpu(ri->csize));
-		if (je32_to_cpu(ri->data_crc) != crc) {
-			printk(KERN_WARNING "Data CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-			       ref_offset(raw), je32_to_cpu(ri->data_crc), crc);
+		if (je32_to_cpu(node->i.dsize)) {
+			crc = crc32(0, node->i.data, je32_to_cpu(node->i.csize));
+			if (je32_to_cpu(node->i.data_crc) != crc) {
+				printk(KERN_WARNING "Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
+				       ref_offset(raw), je32_to_cpu(node->i.data_crc), crc);
+				goto bail;
+			}
+		}
+		break;
+
+	case JFFS2_NODETYPE_DIRENT:
+		crc = crc32(0, node, sizeof(node->d)-8);
+		if (je32_to_cpu(node->d.node_crc) != crc) {
+			printk(KERN_WARNING "Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
+			       ref_offset(raw), je32_to_cpu(node->d.node_crc), crc);
 			goto bail;
 		}
+
+		if (node->d.nsize) {
+			crc = crc32(0, node->d.name, node->d.nsize);
+			if (je32_to_cpu(node->d.name_crc) != crc) {
+				printk(KERN_WARNING "Name CRC failed on REF_PRISTINE dirent ode at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
+				       ref_offset(raw), je32_to_cpu(node->d.name_crc), crc);
+				goto bail;
+			}
+		}
+		break;
+	default:
+		printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", 
+		       ref_offset(raw), je16_to_cpu(node->u.nodetype));
+		goto bail;
 	}
 
 	nraw = jffs2_alloc_raw_node_ref();
 	if (!nraw) {
 		ret = -ENOMEM;
-		goto out_ri;
+		goto out_node;
 	}
 	nraw->flash_offset = phys_ofs;
 	nraw->totlen = raw->totlen;
@@ -521,7 +550,7 @@
 
 	/* OK, all the CRCs are good; this node can just be copied as-is. */
 
-	ret = jffs2_flash_write(c, phys_ofs, raw->totlen, &retlen, (char *)ri);
+	ret = jffs2_flash_write(c, phys_ofs, raw->totlen, &retlen, (char *)node);
 	if (ret || (retlen != raw->totlen)) {
 		printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
                        raw->totlen, phys_ofs, ret, retlen);
@@ -538,25 +567,27 @@
 		}
 		if (!ret)
 			ret = -EIO;
-		goto out_ri;
+		goto out_node;
 	}
 	nraw->flash_offset |= REF_PRISTINE;
 	jffs2_add_physical_node_ref(c, nraw);
 
 	/* Link into per-inode list. This is safe because of the ic
-	   state being INO_STATE_GC. */
+	   state being INO_STATE_GC. Note that if we're doing this
+	   for an inode which is in-code, the 'nraw' pointer is then
+	   going to be fetched from ic->nodes by our caller. */
         nraw->next_in_ino = ic->nodes;
         ic->nodes = nraw;
 
 	jffs2_mark_node_obsolete(c, raw);
-	D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw)));
+	D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw)));
 
- out_ri:
-	kfree(ri);
+ out_node:
+	kfree(node);
 	return ret;
  bail:
 	ret = -EBADFD;
-	goto out_ri;
+	goto out_node;
 }
 
 static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 





More information about the linux-mtd-cvs mailing list