--- cleanup-scan.c 2005-09-25 03:48:35.000000000 -0400 +++ cleanup-scan.xattr.c 2005-09-25 03:53:16.000000000 -0400 @@ -337,6 +337,139 @@ static int jffs2_scan_dirent_node(struct return 0; } +#ifdef CONFIG_JFFS2_XATTR +static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, + struct jffs2_raw_xattr *rx, uint32_t ofs) +{ + struct jffs2_xattr_datum *xd; + struct jffs2_raw_node_ref *raw; + uint32_t crc; + + crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr)-8); + if (crc != je32_to_cpu(rx->node_crc)) { + printk(KERN_NOTICE "%s node CRC failed on node at 0x%08x: " + "Read 0x%08x, calculated 0x%08x\n", + __FUNCTION__, ofs, je32_to_cpu(rx->node_crc), crc); + dirty_space(c, jeb, je32_to_cpu(rx->totlen)); + return 0; + } + + xd = jffs2_find_xattr_datum(c, je32_to_cpu(rx->xid)); + if (xd) { + printk(KERN_NOTICE "%s() duplicate xid=%u found. " + "on node at 0x%08x, later one is ignored.\n", + __FUNCTION__, je32_to_cpu(rx->xid), ofs); + dirty_space(c, jeb, je32_to_cpu(rx->totlen)); + return 0; + } + + crc = crc32(0, rx->data, rx->name_len + 1 + je16_to_cpu(rx->value_len)); + if (crc != je32_to_cpu(rx->data_crc)) { + printk(KERN_NOTICE "%s data CRC failed on node at 0x%08x: " + "Read 0x%08x, calculated 0x%08x\n", + __FUNCTION__, ofs, je32_to_cpu(rx->node_crc), crc); + dirty_space(c, jeb, je32_to_cpu(rx->totlen)); + return 0; + } + + xd = jffs2_alloc_xattr_datum(); + if (!xd) + return -ENOMEM; + init_xattr_datum(xd); + + raw = jffs2_alloc_raw_node_ref(); + if (!raw) { + jffs2_free_xattr_datum(xd); + return -ENOMEM; + } + + xd->xid = je32_to_cpu(rx->xid); + if (xd->xid > c->highest_xseqno) + c->highest_xseqno = xd->xid; + xd->xprefix = rx->xprefix; /* 8bit width */ + xd->name_len = rx->name_len; /* 8bit width */ + xd->value_len = je16_to_cpu(rx->value_len); + xd->data_crc = je32_to_cpu(rx->data_crc); + xd->node = raw; + + raw->__totlen = PAD(je32_to_cpu(rx->totlen)); + raw->flash_offset = ofs | REF_PRISTINE; + raw->next_phys = NULL; + raw->next_in_ino = (void *)xd; + if (!jeb->first_node) + jeb->first_node = raw; + if (jeb->last_node) + jeb->last_node->next_phys = raw; + jeb->last_node = raw; + + used_space(c, jeb, je32_to_cpu(rx->totlen)); + + jffs2_attach_xattr_datum(c, xd); + + return 0; +} + +static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, + struct jffs2_raw_xref *rr, uint32_t ofs) +{ + struct jffs2_xattr_ref *ref; + struct jffs2_raw_node_ref *raw; + uint32_t crc; + + crc = crc32(0, rr, sizeof(*rr)-4); + if (crc != je32_to_cpu(rr->node_crc)) { + printk(KERN_NOTICE "%s node CRC failed on node at 0x%08x: " + "Read 0x%08x, calculated 0x%08x\n", + __FUNCTION__, ofs, je32_to_cpu(rr->node_crc), crc); + dirty_space(c, jeb, je32_to_cpu(rr->totlen)); + return 0; + } + + ref = jffs2_alloc_xattr_ref(); + if (!ref) + return -ENOMEM; + init_xattr_ref(ref); + + raw = jffs2_alloc_raw_node_ref(); + if (!raw) { + jffs2_free_xattr_ref(ref); + return -ENOMEM; + } + + /* BEFORE jffs2_build_xattr_subsystem() called, + * ref->xid is used to store 32bit xid, xd is not used + * ref->ino is used to store 32bit inode-number, ic is not used + * Thoes variables are declared as union, thus using those + * are exclusive. In a similar way, ref->ilist is temporarily + * used to chain all xattr_ref object. It's re-chained to + * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. + */ + + ref->seqno = je32_to_cpu(rr->seqno); + if (ref->seqno > c->highest_xseqno) + c->highest_xseqno = ref->seqno; + ref->ino = je32_to_cpu(rr->ino); + ref->xid = je32_to_cpu(rr->xid); + ref->node = raw; + + raw->__totlen = PAD(je32_to_cpu(rr->totlen)); + raw->flash_offset = ofs | REF_PRISTINE; + raw->next_phys = NULL; + raw->next_in_ino = (void *)ref; + if (!jeb->first_node) + jeb->first_node = raw; + if (jeb->last_node) + jeb->last_node->next_phys = raw; + jeb->last_node = raw; + + used_space(c, jeb, je32_to_cpu(rr->totlen)); + + list_add_tail(&ref->ilist, &c->xattr_temp); + + return 0; +} +#endif /* CONFIG_JFFS2_XATTR */ + static int cleanmarkerfound; static int jffs2_nand_initial_scan(struct jffs2_sb *c, @@ -510,6 +643,20 @@ static int jffs2_scan_eraseblock(struct return ret; ofs += PAD(je32_to_cpu(node->totlen)); break; +#ifdef CONFIG_JFFS2_XATTR + case JFFS2_NODETYPE_XATTR: + ret = jffs2_scan_xattr_node(c, jeb, (void *)node, ofs); + if (ret) + return ret; + ofs += PAD(je32_to_cpu(node->totlen)); + break; + case JFFS2_NODETYPE_XREF: + ret = jffs2_scan_xref_node(c, jeb, (void *)node, ofs); + if (ret) + return ret; + ofs += PAD(je32_to_cpu(node->totlen)); + break; +#endif /* CONFIG_JFFS2_XATR */ case JFFS2_NODETYPE_PADDING: ofs += dirty_space(c, jeb, je32_to_cpu(node->totlen)); break;