/*
 * JFFS2 -- Journalling Flash File System, Version 2.
 *
 * Copyright (C) 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.
 * delete_xattr_datum(c, xd)
 *   is used to delete a xdatum. It marks xd JFFS2_XFLAGS_DEAD, and allows
 *   GC to reclaim those physical nodes.
 * -------------------------------------------------- */
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", __FUNCTION__, 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 delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	BUG_ON(atomic_read(&xd->refcnt));

	unload_xattr_datum(c, xd);
	xd->flags |= JFFS2_XFLAGS_DEAD;
	spin_lock(&c->erase_completion_lock);
	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);

	if (atomic_dec_and_test(&xd->refcnt))
		delete_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);
	}
}

#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) {
				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);
					if (atomic_dec_and_test(&xd->refcnt))
						delete_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);
		if (atomic_dec_and_test(&xd->refcnt))
			delete_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);
		if (atomic_dec_and_test(&xd->refcnt))
			delete_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);
		rc = rc ? rc : -EBADFD;
		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",
			      __FUNCTION__, 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);
}
