mtd/fs/jffs2 gc.c,1.93,1.94

David Woodhouse dwmw2 at infradead.org
Fri Jan 17 19:26:24 EST 2003


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

Modified Files:
	gc.c 
Log Message:
Implement jffs2_garbage_collect_pristine().


Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -r1.93 -r1.94
--- gc.c	17 Jan 2003 16:30:07 -0000	1.93
+++ gc.c	18 Jan 2003 00:26:21 -0000	1.94
@@ -437,8 +437,106 @@
 					  struct jffs2_inode_cache *ic,
 					  struct jffs2_raw_node_ref *raw)
 {
-	D1(printk(KERN_DEBUG "Wanted to GC REF_PRISTINE node. Not implemented yet :)\n"));
-	return -EBADFD;
+	struct jffs2_raw_inode *ri;
+	struct jffs2_raw_node_ref *nraw;
+	size_t retlen;
+	int ret;
+	uint32_t phys_ofs, alloclen;
+	uint32_t crc;
+
+	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,
+				     &phys_ofs, &alloclen);
+	if (ret)
+		return ret;
+
+	if (alloclen < raw->totlen) {
+		/* Doesn't fit untouched. We'll go the old route and split it */
+		return -EBADFD;
+	}
+
+	ri = kmalloc(raw->totlen, GFP_KERNEL);
+	if (!ri)
+               return -ENOMEM;
+
+	ret = jffs2_flash_read(c, ref_offset(raw), raw->totlen, &retlen, (char *)ri);
+	if (!ret && retlen != raw->totlen)
+		ret = -EIO;
+	if (ret)
+		goto out_ri;
+
+	crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
+	if (je32_to_cpu(ri->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);
+		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;
+	}
+
+	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);
+			goto bail;
+		}
+	}
+
+	nraw = jffs2_alloc_raw_node_ref();
+	if (!nraw) {
+		ret = -ENOMEM;
+		goto out_ri;
+	}
+	nraw->flash_offset = phys_ofs;
+	nraw->totlen = raw->totlen;
+	nraw->next_phys = NULL;
+
+	/* 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);
+	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);
+		if (retlen) {
+                        /* Doesn't belong to any inode */
+			nraw->next_in_ino = NULL;
+
+			nraw->flash_offset |= REF_OBSOLETE;
+			jffs2_add_physical_node_ref(c, nraw);
+			jffs2_mark_node_obsolete(c, nraw);
+		} else {
+			printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset);
+                        jffs2_free_raw_node_ref(raw);
+		}
+		if (!ret)
+			ret = -EIO;
+		goto out_ri;
+	}
+	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. */
+        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)));
+
+ out_ri:
+	kfree(ri);
+	return ret;
+ bail:
+	ret = -EBADFD;
+	goto out_ri;
+
 }
 
 static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 





More information about the linux-mtd-cvs mailing list