/*
 * JFFS2 -- Journalling Flash File System, Version 2.
 *
 * Copyright © 2006  NEC Corporation
 *
 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/crc32.h>
#include <linux/jffs2.h>
#include <linux/xattr.h>
#include <linux/mtd/mtd.h>
#include "nodelist.h"
/* -------- xdatum related functions ----------------
 * xattr_datum_hashkey(xprefix, xname, xvalue, xsize)
 *   is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is
 *   the index of the xattr name/value pair cache (c->xattrindex).
 * is_xattr_datum_unchecked(c, xd)
 *   returns 1, if xdatum contains any unchecked raw nodes. if all raw nodes are not
 *   unchecked, it returns 0.
 * unload_xattr_datum(c, xd)
 *   is used to release xattr name/value pair and detach from c->xattrindex.
 * reclaim_xattr_datum(c)
 *   is used to reclaim xattr name/value pairs on the xattr name/value pair cache when
 *   memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold 
 *   is hard coded as 32KiB.
 * do_verify_xattr_datum(c, xd)
 *   is used to load the xdatum informations without name/value pair from the medium.
 *   It's necessary once, because those informations are not collected during mounting
 *   process when EBS is enabled.
 *   0 will be returned, if success. An negative return value means recoverable error, and
 *   positive return value means unrecoverable error. Thus, caller must remove this xdatum
 *   and xref when it returned positive value.
 * do_load_xattr_datum(c, xd)
 *   is used to load name/value pair from the medium.
 *   The meanings of return value is same as do_verify_xattr_datum().
 * load_xattr_datum(c, xd)
 *   is used to be as a wrapper of do_verify_xattr_datum() and do_load_xattr_datum().
 *   If xd need to call do_verify_xattr_datum() at first, it's called before calling
 *   do_load_xattr_datum(). The meanings of return value is same as do_verify_xattr_datum().
 * save_xattr_datum(c, xd)
 *   is used to write xdatum to medium. xd->version will be incremented.
 * create_xattr_datum(c, xprefix, xname, xvalue, xsize)
 *   is used to create new xdatum and write to medium.
 * unrefer_xattr_datum(c, xd)
 *   is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD
 *   is set on xd->flags and chained xattr_dead_list or release it immediately.
 *   In the first case, the garbage collector release it later.
 * -------------------------------------------------- */
static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
{
	int name_len = strlen(xname);

	return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
}

static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	struct jffs2_raw_node_ref *raw;
	int rc = 0;

	spin_lock(&c->erase_completion_lock);
	for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
		if (ref_flags(raw) == REF_UNCHECKED) {
			rc = 1;
			break;
		}
	}
	spin_unlock(&c->erase_completion_lock);
	return rc;
}

static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	D1(dbg_xattr("%s: xid=%u, version=%u\n", __func__, xd->xid, xd->version));
	if (xd->xname) {
		c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
		kfree(xd->xname);
	}

	list_del_init(&xd->xindex);
	xd->hashkey = 0;
	xd->xname = NULL;
	xd->xvalue = NULL;
}

static void reclaim_xattr_datum(struct jffs2_sb_info *c)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_xattr_datum *xd, *_xd;
	uint32_t target, before;
	static int index = 0;
	int count;

	if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
		return;

	before = c->xdatum_mem_usage;
	target = c->xdatum_mem_usage * 4 / 5; /* 20% reduction */
	for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
		list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
			if (xd->flags & JFFS2_XFLAGS_HOT) {
				xd->flags &= ~JFFS2_XFLAGS_HOT;
			} else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
				unload_xattr_datum(c, xd);
			}
			if (c->xdatum_mem_usage <= target)
				goto out;
		}
		index = (index+1) % XATTRINDEX_HASHSIZE;
	}
 out:
	JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
		     before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
}

static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_eraseblock *jeb;
	struct jffs2_raw_node_ref *raw;
	struct jffs2_raw_xattr rx;
	size_t readlen;
	uint32_t crc, offset, totlen;
	int rc;

	spin_lock(&c->erase_completion_lock);
	offset = ref_offset(xd->node);
	if (ref_flags(xd->node) == REF_PRISTINE)
		goto complete;
	spin_unlock(&c->erase_completion_lock);

	rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
	if (rc || readlen != sizeof(rx)) {
		JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
			      rc, sizeof(rx), readlen, offset);
		return rc ? rc : -EIO;
	}
	crc = crc32(0, &rx, sizeof(rx) - 4);
	if (crc != je32_to_cpu(rx.node_crc)) {
		JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
			    offset, je32_to_cpu(rx.hdr_crc), crc);
		xd->flags |= JFFS2_XFLAGS_INVALID;
		return EIO;
	}
	totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
	if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
	    || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
	    || je32_to_cpu(rx.totlen) != totlen
	    || je32_to_cpu(rx.xid) != xd->xid
	    || je32_to_cpu(rx.version) != xd->version) {
		JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
			    "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
			    offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
			    je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
			    je32_to_cpu(rx.totlen), totlen,
			    je32_to_cpu(rx.xid), xd->xid,
			    je32_to_cpu(rx.version), xd->version);
		xd->flags |= JFFS2_XFLAGS_INVALID;
		return EIO;
	}
	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);

	spin_lock(&c->erase_completion_lock);
 complete:
	for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
		jeb = &c->blocks[ref_offset(raw) / c->sector_size];
		totlen = PAD(ref_totlen(c, jeb, raw));
		if (ref_flags(raw) == REF_UNCHECKED) {
			c->unchecked_size -= totlen; c->used_size += totlen;
			jeb->unchecked_size -= totlen; jeb->used_size += totlen;
		}
		raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL);
	}
	spin_unlock(&c->erase_completion_lock);

	/* unchecked xdatum is chained with c->xattr_unchecked */
	list_del_init(&xd->xindex);

	dbg_xattr("success on verfying xdatum (xid=%u, version=%u)\n",
		  xd->xid, xd->version);

	return 0;
}

static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	char *data;
	size_t readlen;
	uint32_t crc, length;
	int i, ret, retry = 0;

	BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
	BUG_ON(!list_empty(&xd->xindex));
 retry:
	length = xd->name_len + 1 + xd->value_len;
	data = kmalloc(length, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr),
			       length, &readlen, data);

	if (ret || length!=readlen) {
		JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n",
			      ret, length, readlen, ref_offset(xd->node));
		kfree(data);
		return ret ? ret : -EIO;
	}

	data[xd->name_len] = '\0';
	crc = crc32(0, data, length);
	if (crc != xd->data_crc) {
		JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XREF)"
			      " at %#08x, read: 0x%08x calculated: 0x%08x\n",
			      ref_offset(xd->node), xd->data_crc, crc);
		kfree(data);
		xd->flags |= JFFS2_XFLAGS_INVALID;
		return EIO;
	}

	xd->flags |= JFFS2_XFLAGS_HOT;
	xd->xname = data;
	xd->xvalue = data + xd->name_len+1;

	c->xdatum_mem_usage += length;

	xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len);
	i = xd->hashkey % XATTRINDEX_HASHSIZE;
	list_add(&xd->xindex, &c->xattrindex[i]);
	if (!retry) {
		retry = 1;
		reclaim_xattr_datum(c);
		if (!xd->xname)
			goto retry;
	}

	dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
		  xd->xid, xd->xprefix, xd->xname);

	return 0;
}

static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem);
	 * rc < 0 : recoverable error, try again
	 * rc = 0 : success
	 * rc > 0 : Unrecoverable error, this node should be deleted.
	 */
	int rc = 0;

	BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD);
	if (xd->xname)
		return 0;
	if (xd->flags & JFFS2_XFLAGS_INVALID)
		return EIO;
	if (unlikely(is_xattr_datum_unchecked(c, xd)))
		rc = do_verify_xattr_datum(c, xd);
	if (!rc)
		rc = do_load_xattr_datum(c, xd);
	return rc;
}

static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_raw_xattr rx;
	struct kvec vecs[2];
	size_t length;
	int rc, totlen;
	uint32_t phys_ofs = write_ofs(c);

	BUG_ON(!xd->xname);
	BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID));

	vecs[0].iov_base = &rx;
	vecs[0].iov_len = sizeof(rx);
	vecs[1].iov_base = xd->xname;
	vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
	totlen = vecs[0].iov_len + vecs[1].iov_len;

	/* Setup raw-xattr */
	memset(&rx, 0, sizeof(rx));
	rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
	rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
	rx.totlen = cpu_to_je32(PAD(totlen));
	rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));

	rx.xid = cpu_to_je32(xd->xid);
	rx.version = cpu_to_je32(++xd->version);
	rx.xprefix = xd->xprefix;
	rx.name_len = xd->name_len;
	rx.value_len = cpu_to_je16(xd->value_len);
	rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
	rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));

	rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
	if (rc || totlen != length) {
		JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
			      rc, totlen, length, phys_ofs);
		rc = rc ? rc : -EIO;
		if (length)
			jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL);

		return rc;
	}
	/* success */
	jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd);

	dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
		  xd->xid, xd->version, xd->xprefix, xd->xname);

	return 0;
}

static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
						    int xprefix, const char *xname,
						    const char *xvalue, int xsize)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_xattr_datum *xd;
	uint32_t hashkey, name_len;
	char *data;
	int i, rc;

	/* Search xattr_datum has same xname/xvalue by index */
	hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
	i = hashkey % XATTRINDEX_HASHSIZE;
	list_for_each_entry(xd, &c->xattrindex[i], xindex) {
		if (xd->hashkey==hashkey
		    && xd->xprefix==xprefix
		    && xd->value_len==xsize
		    && !strcmp(xd->xname, xname)
		    && !memcmp(xd->xvalue, xvalue, xsize)) {
			atomic_inc(&xd->refcnt);
			return xd;
		}
	}

	/* Not found, Create NEW XATTR-Cache */
	name_len = strlen(xname);

	xd = jffs2_alloc_xattr_datum();
	if (!xd)
		return ERR_PTR(-ENOMEM);

	data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
	if (!data) {
		jffs2_free_xattr_datum(xd);
		return ERR_PTR(-ENOMEM);
	}
	strcpy(data, xname);
	memcpy(data + name_len + 1, xvalue, xsize);

	atomic_set(&xd->refcnt, 1);
	xd->xid = ++c->highest_xid;
	xd->flags |= JFFS2_XFLAGS_HOT;
	xd->xprefix = xprefix;

	xd->hashkey = hashkey;
	xd->xname = data;
	xd->xvalue = data + name_len + 1;
	xd->name_len = name_len;
	xd->value_len = xsize;
	xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);

	rc = save_xattr_datum(c, xd);
	if (rc) {
		kfree(xd->xname);
		jffs2_free_xattr_datum(xd);
		return ERR_PTR(rc);
	}

	/* Insert Hash Index */
	i = hashkey % XATTRINDEX_HASHSIZE;
	list_add(&xd->xindex, &c->xattrindex[i]);

	c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
	reclaim_xattr_datum(c);

	return xd;
}

static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
		unload_xattr_datum(c, xd);
		xd->flags |= JFFS2_XFLAGS_DEAD;
		if (xd->node == (void *)xd) {
			BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
			jffs2_free_xattr_datum(xd);
		} else {
			list_add(&xd->xindex, &c->xattr_dead_list);
		}
		spin_unlock(&c->erase_completion_lock);

		dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n",
			  xd->xid, xd->version);
	}
}

/* -------- xref related functions ------------------
 * verify_xattr_ref(c, ref)
 *   is used to load xref information from medium. Because summary data does not
 *   contain xid/ino, it's necessary to verify once while mounting process.
 * save_xattr_ref(c, ref)
 *   is used to write xref to medium. If delete marker is marked, it write
 *   a delete marker of xref into medium.
 * create_xattr_ref(c, ic, xd)
 *   is used to create a new xref and write to medium.
 * delete_xattr_ref(c, ref)
 *   is used to delete jffs2_xattr_ref. It marks xref XREF_DELETE_MARKER,
 *   and allows GC to reclaim those physical nodes.
 * jffs2_xattr_delete_inode(c, ic)
 *   is called to remove xrefs related to obsolete inode when inode is unlinked.
 * jffs2_xattr_free_inode(c, ic)
 *   is called to release xattr related objects when unmounting. 
 * check_xattr_ref_inode(c, ic)
 *   is used to confirm inode does not have duplicate xattr name/value pair.
 * -------------------------------------------------- */
static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
{
	struct jffs2_eraseblock *jeb;
	struct jffs2_raw_node_ref *raw;
	struct jffs2_raw_xref rr;
	size_t readlen;
	uint32_t crc, offset, totlen;
	int rc;

	spin_lock(&c->erase_completion_lock);
	if (ref_flags(ref->node) != REF_UNCHECKED)
		goto complete;
	offset = ref_offset(ref->node);
	spin_unlock(&c->erase_completion_lock);

	rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr);
	if (rc || sizeof(rr) != readlen) {
		JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
			      rc, sizeof(rr), readlen, offset);
		return rc ? rc : -EIO;
	}
	/* obsolete node */
	crc = crc32(0, &rr, sizeof(rr) - 4);
	if (crc != je32_to_cpu(rr.node_crc)) {
		JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
			    offset, je32_to_cpu(rr.node_crc), crc);
		return EIO;
	}
	if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
	    || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
	    || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
		JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
			    "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
			    offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
			    je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
			    je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
		return EIO;
	}
	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);

	spin_lock(&c->erase_completion_lock);
 complete:
	for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) {
		jeb = &c->blocks[ref_offset(raw) / c->sector_size];
		totlen = PAD(ref_totlen(c, jeb, raw));
		if (ref_flags(raw) == REF_UNCHECKED) {
			c->unchecked_size -= totlen; c->used_size += totlen;
			jeb->unchecked_size -= totlen; jeb->used_size += totlen;
		}
		raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL);
	}
	spin_unlock(&c->erase_completion_lock);

	dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
		  ref->ino, ref->xid, ref_offset(ref->node));
	return 0;
}

static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_raw_xref rr;
	size_t length;
	uint32_t xseqno, phys_ofs = write_ofs(c);
	int ret;

	rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
	rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
	rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
	rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));

	xseqno = (c->highest_xseqno += 2);
	if (is_xattr_ref_dead(ref)) {
		xseqno |= XREF_DELETE_MARKER;
		rr.ino = cpu_to_je32(ref->ino);
		rr.xid = cpu_to_je32(ref->xid);
	} else {
		rr.ino = cpu_to_je32(ref->ic->ino);
		rr.xid = cpu_to_je32(ref->xd->xid);
	}
	rr.xseqno = cpu_to_je32(xseqno);
	rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));

	ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
	if (ret || sizeof(rr) != length) {
		JFFS2_WARNING("jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n",
			      ret, sizeof(rr), length, phys_ofs);
		ret = ret ? ret : -EIO;
		if (length)
			jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL);

		return ret;
	}
	/* success */
	ref->xseqno = xseqno;
	jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref);

	dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);

	return 0;
}

static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
						struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_xattr_ref *ref;
	int ret;

	ref = jffs2_alloc_xattr_ref();
	if (!ref)
		return ERR_PTR(-ENOMEM);
	ref->ic = ic;
	ref->xd = xd;

	ret = save_xattr_ref(c, ref);
	if (ret) {
		jffs2_free_xattr_ref(ref);
		return ERR_PTR(ret);
	}

	/* Chain to inode */
	ref->next = ic->xref;
	ic->xref = ref;

	return ref; /* success */
}

static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_xattr_datum *xd;

	xd = ref->xd;
	ref->xseqno |= XREF_DELETE_MARKER;
	ref->ino = ref->ic->ino;
	ref->xid = ref->xd->xid;
	spin_lock(&c->erase_completion_lock);
	ref->next = c->xref_dead_list;
	c->xref_dead_list = ref;
	spin_unlock(&c->erase_completion_lock);

	dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
		  ref->ino, ref->xid, ref->xseqno);

	unrefer_xattr_datum(c, xd);
}

void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{
	/* It's called from jffs2_clear_inode() on inode removing.
	   When an inode with XATTR is removed, those XATTRs must be removed. */
	struct jffs2_xattr_ref *ref, *_ref;

	if (!ic || ic->nlink > 0)
		return;

	down_write(&c->xattr_sem);
	for (ref = ic->xref; ref; ref = _ref) {
		_ref = ref->next;
		delete_xattr_ref(c, ref);
	}
	ic->xref = NULL;
	up_write(&c->xattr_sem);
}

void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{
	/* It's called from jffs2_free_ino_caches() until unmounting FS. */
	struct jffs2_xattr_datum *xd;
	struct jffs2_xattr_ref *ref, *_ref;

	down_write(&c->xattr_sem);
	for (ref = ic->xref; ref; ref = _ref) {
		_ref = ref->next;
		xd = ref->xd;
		if (atomic_dec_and_test(&xd->refcnt)) {
			unload_xattr_datum(c, xd);
			jffs2_free_xattr_datum(xd);
		}
		jffs2_free_xattr_ref(ref);
	}
	ic->xref = NULL;
	up_write(&c->xattr_sem);
}

static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{
	/* success of check_xattr_ref_inode() means taht inode (ic) dose not have
	 * duplicate name/value pairs. If duplicate name/value pair would be found,
	 * one will be removed.
	 */
	struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp;
	int rc = 0;

	if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
		return 0;
	down_write(&c->xattr_sem);
 retry:
	rc = 0;
	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
		if (!ref->xd->xname) {
			rc = load_xattr_datum(c, ref->xd);
			if (unlikely(rc > 0)) {
				*pref = ref->next;
				delete_xattr_ref(c, ref);
				goto retry;
			} else if (unlikely(rc < 0))
				goto out;
		}
		for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) {
			if (!cmp->xd->xname) {
				ref->xd->flags |= JFFS2_XFLAGS_BIND;
				rc = load_xattr_datum(c, cmp->xd);
				ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
				if (unlikely(rc > 0)) {
					*pcmp = cmp->next;
					delete_xattr_ref(c, cmp);
					goto retry;
				} else if (unlikely(rc < 0))
					goto out;
			}
			if (ref->xd->xprefix == cmp->xd->xprefix
			    && !strcmp(ref->xd->xname, cmp->xd->xname)) {
				if (ref->xseqno > cmp->xseqno) {
					*pcmp = cmp->next;
					delete_xattr_ref(c, cmp);
				} else {
					*pref = ref->next;
					delete_xattr_ref(c, ref);
				}
				goto retry;
			}
		}
	}
	ic->flags |= INO_FLAGS_XATTR_CHECKED;
 out:
	up_write(&c->xattr_sem);

	return rc;
}

/* -------- xattr subsystem functions ---------------
 * jffs2_init_xattr_subsystem(c)
 *   is used to initialize semaphore and list_head, and some variables.
 * jffs2_find_xattr_datum(c, xid)
 *   is used to lookup xdatum while scanning process.
 * jffs2_clear_xattr_subsystem(c)
 *   is used to release any xattr related objects.
 * jffs2_build_xattr_subsystem(c)
 *   is used to associate xdatum and xref while super block building process.
 * jffs2_setup_xattr_datum(c, xid, version)
 *   is used to insert xdatum while scanning process.
 * -------------------------------------------------- */
void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
{
	int i;

	for (i=0; i < XATTRINDEX_HASHSIZE; i++)
		INIT_LIST_HEAD(&c->xattrindex[i]);
	INIT_LIST_HEAD(&c->xattr_unchecked);
	INIT_LIST_HEAD(&c->xattr_dead_list);
	c->xref_dead_list = NULL;
	c->xref_temp = NULL;

	init_rwsem(&c->xattr_sem);
	c->highest_xid = 0;
	c->highest_xseqno = 0;
	c->xdatum_mem_usage = 0;
	c->xdatum_mem_threshold = 32 * 1024;	/* Default 32KB */
}

static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
{
	struct jffs2_xattr_datum *xd;
	int i = xid % XATTRINDEX_HASHSIZE;

	/* It's only used in scanning/building process. */
	BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));

	list_for_each_entry(xd, &c->xattrindex[i], xindex) {
		if (xd->xid==xid)
			return xd;
	}
	return NULL;
}

void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
{
	struct jffs2_xattr_datum *xd, *_xd;
	struct jffs2_xattr_ref *ref, *_ref;
	int i;

	for (ref=c->xref_temp; ref; ref = _ref) {
		_ref = ref->next;
		jffs2_free_xattr_ref(ref);
	}

	for (ref=c->xref_dead_list; ref; ref = _ref) {
		_ref = ref->next;
		jffs2_free_xattr_ref(ref);
	}

	for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
		list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
			list_del(&xd->xindex);
			if (xd->xname)
				kfree(xd->xname);
			jffs2_free_xattr_datum(xd);
		}
	}

	list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) {
		list_del(&xd->xindex);
		jffs2_free_xattr_datum(xd);
	}
	list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
		list_del(&xd->xindex);
		jffs2_free_xattr_datum(xd);
	}
}

#define XREF_TMPHASH_SIZE	(128)
void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
{
	struct jffs2_xattr_ref *ref, *_ref;
	struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
	struct jffs2_xattr_datum *xd, *_xd;
	struct jffs2_inode_cache *ic;
	struct jffs2_raw_node_ref *raw;
	int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0;
	int xdatum_orphan_count = 0, xref_orphan_count = 0, xref_dead_count = 0;

	BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));

	/* Phase.1 : Merge same xref */
	for (i=0; i < XREF_TMPHASH_SIZE; i++)
		xref_tmphash[i] = NULL;
	for (ref=c->xref_temp; ref; ref=_ref) {
		struct jffs2_xattr_ref *tmp;

		_ref = ref->next;
		if (ref_flags(ref->node) != REF_PRISTINE) {
			if (verify_xattr_ref(c, ref)) {
				BUG_ON(ref->node->next_in_ino != (void *)ref);
				ref->node->next_in_ino = NULL;
				jffs2_mark_node_obsolete(c, ref->node);
				jffs2_free_xattr_ref(ref);
				continue;
			}
		}

		i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE;
		for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) {
			if (tmp->ino == ref->ino && tmp->xid == ref->xid)
				break;
		}
		if (tmp) {
			raw = ref->node;
			if (ref->xseqno > tmp->xseqno) {
				tmp->xseqno = ref->xseqno;
				raw->next_in_ino = tmp->node;
				tmp->node = raw;
			} else {
				raw->next_in_ino = tmp->node->next_in_ino;
				tmp->node->next_in_ino = raw;
			}
			jffs2_free_xattr_ref(ref);
			continue;
		} else {
			ref->next = xref_tmphash[i];
			xref_tmphash[i] = ref;
		}
	}
	c->xref_temp = NULL;

	/* Phase.2 : Bind xref with inode_cache and xattr_datum */
	for (i=0; i < XREF_TMPHASH_SIZE; i++) {
		for (ref=xref_tmphash[i]; ref; ref=_ref) {
			xref_count++;
			_ref = ref->next;
			if (is_xattr_ref_dead(ref)) {
				ref->next = c->xref_dead_list;
				c->xref_dead_list = ref;
				xref_dead_count++;
				continue;
			}
			/* At this point, ref->xid and ref->ino contain XID and inode number.
			   ref->xd and ref->ic are not valid yet. */
			xd = jffs2_find_xattr_datum(c, ref->xid);
			ic = jffs2_get_ino_cache(c, ref->ino);
			if (!xd || !ic || !ic->nlink) {
				dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
					  ref->ino, ref->xid, ref->xseqno);
				ref->xseqno |= XREF_DELETE_MARKER;
				ref->next = c->xref_dead_list;
				c->xref_dead_list = ref;
				xref_orphan_count++;
				continue;
			}
			ref->xd = xd;
			ref->ic = ic;
			atomic_inc(&xd->refcnt);
			ref->next = ic->xref;
			ic->xref = ref;
		}
	}

	/* Phase.3 : Link unchecked xdatum to xattr_unchecked list */
	for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
		list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
			xdatum_count++;
			list_del_init(&xd->xindex);
			if (!atomic_read(&xd->refcnt)) {
				dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n",
					  xd->xid, xd->version);
				xd->flags |= JFFS2_XFLAGS_DEAD;
				list_add(&xd->xindex, &c->xattr_unchecked);
				xdatum_orphan_count++;
				continue;
			}
			if (is_xattr_datum_unchecked(c, xd)) {
				dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n",
					  xd->xid, xd->version);
				list_add(&xd->xindex, &c->xattr_unchecked);
				xdatum_unchecked_count++;
			}
		}
	}
	/* build complete */
	JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum"
		     " (%u unchecked, %u orphan) and "
		     "%u of xref (%u dead, %u orphan) found.\n",
		     xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
		     xref_count, xref_dead_count, xref_orphan_count);
}

struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
						  uint32_t xid, uint32_t version)
{
	struct jffs2_xattr_datum *xd;

	xd = jffs2_find_xattr_datum(c, xid);
	if (!xd) {
		xd = jffs2_alloc_xattr_datum();
		if (!xd)
			return ERR_PTR(-ENOMEM);
		xd->xid = xid;
		xd->version = version;
		if (xd->xid > c->highest_xid)
			c->highest_xid = xd->xid;
		list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
	}
	return xd;
}

/* -------- xattr subsystem functions ---------------
 * xprefix_to_handler(xprefix)
 *   is used to translate xprefix into xattr_handler.
 * jffs2_listxattr(dentry, buffer, size)
 *   is an implementation of listxattr handler on jffs2.
 * do_jffs2_getxattr(inode, xprefix, xname, buffer, size)
 *   is an implementation of getxattr handler on jffs2.
 * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags)
 *   is an implementation of setxattr handler on jffs2.
 * -------------------------------------------------- */
struct xattr_handler *jffs2_xattr_handlers[] = {
	&jffs2_user_xattr_handler,
#ifdef CONFIG_JFFS2_FS_SECURITY
	&jffs2_security_xattr_handler,
#endif
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
	&jffs2_acl_access_xattr_handler,
	&jffs2_acl_default_xattr_handler,
#endif
	&jffs2_trusted_xattr_handler,
	NULL
};

static struct xattr_handler *xprefix_to_handler(int xprefix) {
	struct xattr_handler *ret;

	switch (xprefix) {
	case JFFS2_XPREFIX_USER:
		ret = &jffs2_user_xattr_handler;
		break;
#ifdef CONFIG_JFFS2_FS_SECURITY
	case JFFS2_XPREFIX_SECURITY:
		ret = &jffs2_security_xattr_handler;
		break;
#endif
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
	case JFFS2_XPREFIX_ACL_ACCESS:
		ret = &jffs2_acl_access_xattr_handler;
		break;
	case JFFS2_XPREFIX_ACL_DEFAULT:
		ret = &jffs2_acl_default_xattr_handler;
		break;
#endif
	case JFFS2_XPREFIX_TRUSTED:
		ret = &jffs2_trusted_xattr_handler;
		break;
	default:
		ret = NULL;
		break;
	}
	return ret;
}

ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
	struct inode *inode = dentry->d_inode;
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
	struct jffs2_inode_cache *ic = f->inocache;
	struct jffs2_xattr_ref *ref, **pref;
	struct jffs2_xattr_datum *xd;
	struct xattr_handler *xhandle;
	ssize_t len, rc;
	int retry = 0;

	rc = check_xattr_ref_inode(c, ic);
	if (unlikely(rc))
		return rc;

	down_read(&c->xattr_sem);
 retry:
	len = 0;
	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
		BUG_ON(ref->ic != ic);
		xd = ref->xd;
		if (!xd->xname) {
			/* xdatum is unchached */
			if (!retry) {
				retry = 1;
				up_read(&c->xattr_sem);
				down_write(&c->xattr_sem);
				goto retry;
			} else {
				rc = load_xattr_datum(c, xd);
				if (unlikely(rc > 0)) {
					*pref = ref->next;
					delete_xattr_ref(c, ref);
					goto retry;
				} else if (unlikely(rc < 0))
					goto out;
			}
		}
		xhandle = xprefix_to_handler(xd->xprefix);
		if (!xhandle)
			continue;
		if (buffer) {
			rc = xhandle->list(inode, buffer+len, size-len, xd->xname, xd->name_len);
		} else {
			rc = xhandle->list(inode, NULL, 0, xd->xname, xd->name_len);
		}
		if (rc < 0)
			goto out;
		len += rc;
	}
	rc = len;
 out:
	if (!retry) {
		up_read(&c->xattr_sem);
	} else {
		up_write(&c->xattr_sem);
	}
	return rc;
}

int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
		      char *buffer, size_t size)
{
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
	struct jffs2_inode_cache *ic = f->inocache;
	struct jffs2_xattr_datum *xd;
	struct jffs2_xattr_ref *ref, **pref;
	int rc, retry = 0;

	rc = check_xattr_ref_inode(c, ic);
	if (unlikely(rc))
		return rc;

	down_read(&c->xattr_sem);
 retry:
	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
		BUG_ON(ref->ic!=ic);

		xd = ref->xd;
		if (xd->xprefix != xprefix)
			continue;
		if (!xd->xname) {
			/* xdatum is unchached */
			if (!retry) {
				retry = 1;
				up_read(&c->xattr_sem);
				down_write(&c->xattr_sem);
				goto retry;
			} else {
				rc = load_xattr_datum(c, xd);
				if (unlikely(rc > 0)) {
					*pref = ref->next;
					delete_xattr_ref(c, ref);
					goto retry;
				} else if (unlikely(rc < 0)) {
					goto out;
				}
			}
		}
		if (!strcmp(xname, xd->xname)) {
			rc = xd->value_len;
			if (buffer) {
				if (size < rc) {
					rc = -ERANGE;
				} else {
					memcpy(buffer, xd->xvalue, rc);
				}
			}
			goto out;
		}
	}
	rc = -ENODATA;
 out:
	if (!retry) {
		up_read(&c->xattr_sem);
	} else {
		up_write(&c->xattr_sem);
	}
	return rc;
}

int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
		      const char *buffer, size_t size, int flags)
{
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
	struct jffs2_inode_cache *ic = f->inocache;
	struct jffs2_xattr_datum *xd;
	struct jffs2_xattr_ref *ref, *newref, **pref;
	uint32_t length, request;
	int rc;

	rc = check_xattr_ref_inode(c, ic);
	if (unlikely(rc))
		return rc;

	request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
	rc = jffs2_reserve_space(c, request, &length,
				 ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
	if (rc) {
		JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
		return rc;
	}

	/* Find existing xattr */
	down_write(&c->xattr_sem);
 retry:
	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
		xd = ref->xd;
		if (xd->xprefix != xprefix)
			continue;
		if (!xd->xname) {
			rc = load_xattr_datum(c, xd);
			if (unlikely(rc > 0)) {
				*pref = ref->next;
				delete_xattr_ref(c, ref);
				goto retry;
			} else if (unlikely(rc < 0))
				goto out;
		}
		if (!strcmp(xd->xname, xname)) {
			if (flags & XATTR_CREATE) {
				rc = -EEXIST;
				goto out;
			}
			if (!buffer) {
				ref->ino = ic->ino;
				ref->xid = xd->xid;
				ref->xseqno |= XREF_DELETE_MARKER;
				rc = save_xattr_ref(c, ref);
				if (!rc) {
					*pref = ref->next;
					spin_lock(&c->erase_completion_lock);
					ref->next = c->xref_dead_list;
					c->xref_dead_list = ref;
					spin_unlock(&c->erase_completion_lock);
					unrefer_xattr_datum(c, xd);
				} else {
					ref->ic = ic;
					ref->xd = xd;
					ref->xseqno &= ~XREF_DELETE_MARKER;
				}
				goto out;
			}
			goto found;
		}
	}
	/* not found */
	if (flags & XATTR_REPLACE) {
		rc = -ENODATA;
		goto out;
	}
	if (!buffer) {
		rc = -ENODATA;
		goto out;
	}
 found:
	xd = create_xattr_datum(c, xprefix, xname, buffer, size);
	if (IS_ERR(xd)) {
		rc = PTR_ERR(xd);
		goto out;
	}
	up_write(&c->xattr_sem);
	jffs2_complete_reservation(c);

	/* create xattr_ref */
	request = PAD(sizeof(struct jffs2_raw_xref));
	rc = jffs2_reserve_space(c, request, &length,
				 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
	down_write(&c->xattr_sem);
	if (rc) {
		JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
		unrefer_xattr_datum(c, xd);
		up_write(&c->xattr_sem);
		return rc;
	}
	if (ref)
		*pref = ref->next;
	newref = create_xattr_ref(c, ic, xd);
	if (IS_ERR(newref)) {
		if (ref) {
			ref->next = ic->xref;
			ic->xref = ref;
		}
		rc = PTR_ERR(newref);
		unrefer_xattr_datum(c, xd);
	} else if (ref) {
		delete_xattr_ref(c, ref);
	}
 out:
	up_write(&c->xattr_sem);
	jffs2_complete_reservation(c);
	return rc;
}

/* -------- garbage collector functions -------------
 * jffs2_garbage_collect_xattr_datum(c, xd, raw)
 *   is used to move xdatum into new node.
 * jffs2_garbage_collect_xattr_ref(c, ref, raw)
 *   is used to move xref into new node.
 * jffs2_verify_xattr(c)
 *   is used to call do_verify_xattr_datum() before garbage collecting.
 * jffs2_release_xattr_datum(c, xd)
 *   is used to release an in-memory object of xdatum.
 * jffs2_release_xattr_ref(c, ref)
 *   is used to release an in-memory object of xref.
 * -------------------------------------------------- */
int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
				      struct jffs2_raw_node_ref *raw)
{
	uint32_t totlen, length, old_ofs;
	int rc = 0;

	down_write(&c->xattr_sem);
	if (xd->node != raw)
		goto out;
	if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID))
		goto out;

	rc = load_xattr_datum(c, xd);
	if (unlikely(rc)) {
		rc = (rc > 0) ? 0 : rc;
		goto out;
	}
	old_ofs = ref_offset(xd->node);
	totlen = PAD(sizeof(struct jffs2_raw_xattr)
			+ xd->name_len + 1 + xd->value_len);
	rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
	if (rc) {
		JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
		goto out;
	}
	rc = save_xattr_datum(c, xd);
	if (!rc)
		dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
			  xd->xid, xd->version, old_ofs, ref_offset(xd->node));
 out:
	if (!rc)
		jffs2_mark_node_obsolete(c, raw);
	up_write(&c->xattr_sem);
	return rc;
}

int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
				    struct jffs2_raw_node_ref *raw)
{
	uint32_t totlen, length, old_ofs;
	int rc = 0;

	down_write(&c->xattr_sem);
	BUG_ON(!ref->node);

	if (ref->node != raw)
		goto out;
	if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref))
		goto out;

	old_ofs = ref_offset(ref->node);
	totlen = ref_totlen(c, c->gcblock, ref->node);

	rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
	if (rc) {
		JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n",
			      __func__, rc, totlen);
		rc = rc ? rc : -EBADFD;
		goto out;
	}
	rc = save_xattr_ref(c, ref);
	if (!rc)
		dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
			  ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
 out:
	if (!rc)
		jffs2_mark_node_obsolete(c, raw);
	up_write(&c->xattr_sem);
	return rc;
}

int jffs2_verify_xattr(struct jffs2_sb_info *c)
{
	struct jffs2_xattr_datum *xd, *_xd;
	struct jffs2_eraseblock *jeb;
	struct jffs2_raw_node_ref *raw;
	uint32_t totlen;
	int rc;

	down_write(&c->xattr_sem);
	list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
		rc = do_verify_xattr_datum(c, xd);
		if (rc < 0)
			continue;
		list_del_init(&xd->xindex);
		spin_lock(&c->erase_completion_lock);
		for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
			if (ref_flags(raw) != REF_UNCHECKED)
				continue;
			jeb = &c->blocks[ref_offset(raw) / c->sector_size];
			totlen = PAD(ref_totlen(c, jeb, raw));
			c->unchecked_size -= totlen; c->used_size += totlen;
			jeb->unchecked_size -= totlen; jeb->used_size += totlen;
			raw->flash_offset = ref_offset(raw)
				| ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL);
		}
		if (xd->flags & JFFS2_XFLAGS_DEAD)
			list_add(&xd->xindex, &c->xattr_dead_list);
		spin_unlock(&c->erase_completion_lock);
	}
	up_write(&c->xattr_sem);
	return list_empty(&c->xattr_unchecked) ? 1 : 0;
}

void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under spin_lock(&c->erase_completion_lock) */
	if (atomic_read(&xd->refcnt) || xd->node != (void *)xd)
		return;

	list_del(&xd->xindex);
	jffs2_free_xattr_datum(xd);
}

void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
{
	/* must be called under spin_lock(&c->erase_completion_lock) */
	struct jffs2_xattr_ref *tmp, **ptmp;

	if (ref->node != (void *)ref)
		return;

	for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) {
		if (ref == tmp) {
			*ptmp = tmp->next;
			break;
		}
	}
	jffs2_free_xattr_ref(ref);
}
