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