Example #1
0
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_summary *s)
{
	struct jffs2_xattr_datum *xd;
	uint32_t xid, version, totlen, crc;
	int err;

	crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4);
	if (crc != je32_to_cpu(rx->node_crc)) {
		JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
			      ofs, je32_to_cpu(rx->node_crc), crc);
		if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen))))
			return err;
		return 0;
	}

	xid = je32_to_cpu(rx->xid);
	version = je32_to_cpu(rx->version);

	totlen = PAD(sizeof(struct jffs2_raw_xattr)
			+ rx->name_len + 1 + je16_to_cpu(rx->value_len));
	if (totlen != je32_to_cpu(rx->totlen)) {
		JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n",
			      ofs, je32_to_cpu(rx->totlen), totlen);
		if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen))))
			return err;
		return 0;
	}

	xd = jffs2_setup_xattr_datum(c, xid, version);
	if (IS_ERR(xd))
		return PTR_ERR(xd);

	if (xd->version > version) {
		struct jffs2_raw_node_ref *raw
			= jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL);
		raw->next_in_ino = xd->node->next_in_ino;
		xd->node->next_in_ino = raw;
	} else {
		xd->version = version;
		xd->xprefix = rx->xprefix;
		xd->name_len = rx->name_len;
		xd->value_len = je16_to_cpu(rx->value_len);
		xd->data_crc = je32_to_cpu(rx->data_crc);

		jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, (void *)xd);
	}

	if (jffs2_sum_active())
		jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset);
	dbg_xattr("scaning xdatum at %#08x (xid=%u, version=%u)\n",
		  ofs, xd->xid, xd->version);
	return 0;
}
Example #2
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_summary *s)
{
	struct jffs2_xattr_ref *ref;
	uint32_t crc;
	int err;

	crc = crc32(0, rr, sizeof(*rr) - 4);
	if (crc != je32_to_cpu(rr->node_crc)) {
		JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
			      ofs, je32_to_cpu(rr->node_crc), crc);
		if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen)))))
			return err;
		return 0;
	}

	if (PAD(sizeof(struct jffs2_raw_xref)) != je32_to_cpu(rr->totlen)) {
		JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%zd\n",
			      ofs, je32_to_cpu(rr->totlen),
			      PAD(sizeof(struct jffs2_raw_xref)));
		if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rr->totlen))))
			return err;
		return 0;
	}

	ref = jffs2_alloc_xattr_ref();
	if (!ref)
		return -ENOMEM;

	/* BEFORE jffs2_build_xattr_subsystem() called, 
	 * and AFTER xattr_ref is marked as a dead xref,
	 * 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->next is temporarily
	 * used to chain all xattr_ref object. It's re-chained to
	 * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly.
	 */
	ref->ino = je32_to_cpu(rr->ino);
	ref->xid = je32_to_cpu(rr->xid);
	ref->xseqno = je32_to_cpu(rr->xseqno);
	if (ref->xseqno > c->highest_xseqno)
		c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
	ref->next = c->xref_temp;
	c->xref_temp = ref;

	jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), (void *)ref);

	if (jffs2_sum_active())
		jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset);
	dbg_xattr("scan xref at %#08x (xid=%u, ino=%u)\n",
		  ofs, ref->xid, ref->ino);
	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_summary *s)
{
	struct jffs2_xattr_ref *ref;
	uint32_t crc;
	int err;

	crc = crc32(0, rr, sizeof(*rr) - 4);
	if (crc != je32_to_cpu(rr->node_crc)) {
		JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
			      ofs, je32_to_cpu(rr->node_crc), crc);
		if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen)))))
			return err;
		return 0;
	}

	if (PAD(sizeof(struct jffs2_raw_xref)) != je32_to_cpu(rr->totlen)) {
		JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%zd\n",
			      ofs, je32_to_cpu(rr->totlen),
			      PAD(sizeof(struct jffs2_raw_xref)));
		if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rr->totlen))))
			return err;
		return 0;
	}

	ref = jffs2_alloc_xattr_ref();
	if (!ref)
		return -ENOMEM;

	ref->ino = je32_to_cpu(rr->ino);
	ref->xid = je32_to_cpu(rr->xid);
	ref->xseqno = je32_to_cpu(rr->xseqno);
	if (ref->xseqno > c->highest_xseqno)
		c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
	ref->next = c->xref_temp;
	c->xref_temp = ref;

	jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), (void *)ref);

	if (jffs2_sum_active())
		jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset);
	dbg_xattr("scan xref at %#08x (xid=%u, ino=%u)\n",
		  ofs, ref->xid, ref->ino);
	return 0;
}