/* -------------------------------------------------------------------------
 *  File: fs/jffs2/xattr.c
 *  XATTR support on JFFS2 FileSystem
 *
 *  Implemented by KaiGai Kohei <kaigai@ak.jp.nec.com>
 *  Copyright (C) 2006 NEC Corporation
 *
 *  For licensing information, see the file 'LICENCE' in the jffs2 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).
 * 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.
 * delete_xattr_datum_node(c, xd)
 *   is used to delete a jffs2 node is dominated by xdatum. When EBS(Erase Block Summary) is
 *   enabled, it overwrites the obsolete node by myself.
 * delete_xattr_datum(c, xd)
 *   is used to delete jffs2_xattr_datum object. It must be called with 0-value of reference
 *   counter. (It means how many jffs2_xattr_ref object refers this xdatum.)
 * 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, phys_ofs)
 *   is used to write xdatum to medium. xd->version will be incremented.
 * create_xattr_datum(c, xprefix, xname, xvalue, xsize, phys_ofs)
 *   is used to create new xdatum and write to medium.
 * -------------------------------------------------- */

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 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 void delete_xattr_datum_node(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_raw_xattr rx;
	uint32_t length;
	int rc;

	if (!xd->node) {
		JFFS2_WARNING("xdatum (xid=%u) is removed twice.\n", xd->xid);
		return;
	}
	if (jffs2_sum_active()) {
		memset(&rx, 0xff, sizeof(struct jffs2_raw_xattr));
		rc = jffs2_flash_read(c, ref_offset(xd->node),
				      sizeof(struct jffs2_unknown_node),
				      &length, (char *)&rx);
		if (rc || length != sizeof(struct jffs2_unknown_node)) {
			JFFS2_ERROR("jffs2_flash_read()=%d, req=%u, read=%u at %#08x\n",
				    rc, sizeof(struct jffs2_unknown_node),
				    length, ref_offset(xd->node));
		}
		rc = jffs2_flash_write(c, ref_offset(xd->node), sizeof(rx),
				       &length, (char *)&rx);
		if (rc || length != sizeof(struct jffs2_raw_xattr)) {
			JFFS2_ERROR("jffs2_flash_write()=%d, req=%u, wrote=%u ar %#08x\n",
				    rc, sizeof(rx), length, ref_offset(xd->node));
		}
	}
	spin_lock(&c->erase_completion_lock);
	xd->node->next_in_ino = NULL;
	spin_unlock(&c->erase_completion_lock);
	jffs2_mark_node_obsolete(c, xd->node);
	xd->node = NULL;
}

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(xd->refcnt);

	unload_xattr_datum(c, xd);
	if (xd->node) {
		delete_xattr_datum_node(c, xd);
		xd->node = NULL;
	}
	jffs2_free_xattr_datum(xd);
}

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_xattr rx;
	size_t readlen;
	uint32_t crc, totlen;
	int rc;

	BUG_ON(!xd->node);
	BUG_ON(ref_flags(xd->node) != REF_UNCHECKED);

	rc = jffs2_flash_read(c, ref_offset(xd->node), sizeof(rx), &readlen, (char *)&rx);
	if (rc || readlen != sizeof(rx)) {
		JFFS2_WARNING("jffs2_flash_read()=%d, req=%u, read=%u at %#08x\n",
			      rc, sizeof(rx), readlen, ref_offset(xd->node));
		return rc ? rc : -EIO;
	}
	crc = crc32(0, &rx, sizeof(rx) - 4);
	if (crc != je32_to_cpu(rx.node_crc)) {
		if (je32_to_cpu(rx.node_crc) != 0xffffffff)
			JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
				    ref_offset(xd->node), je32_to_cpu(rx.hdr_crc), crc);
		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",
			    ref_offset(xd->node), 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);
		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);

	/* This JFFS2_NODETYPE_XATTR node is checked */
	jeb = &c->blocks[ref_offset(xd->node) / c->sector_size];
	totlen = PAD(je32_to_cpu(rx.totlen));

	spin_lock(&c->erase_completion_lock);
	c->unchecked_size -= totlen; c->used_size += totlen;
	jeb->unchecked_size -= totlen; jeb->used_size += totlen;
	xd->node->flash_offset = ref_offset(xd->node) | REF_PRISTINE;
	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(!xd->node);
	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=%d, 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);
		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->xname);
	if (!xd->node)
		return EIO;
	if (unlikely(ref_flags(xd->node) != REF_PRISTINE)) {
		rc = do_verify_xattr_datum(c, xd);
		if (rc > 0) {
			list_del_init(&xd->xindex);
			delete_xattr_datum_node(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, uint32_t phys_ofs)
{
	/* must be called under down_write(xattr_sem) */
	struct jffs2_raw_xattr rx;
	struct jffs2_raw_node_ref *raw;
	struct kvec vecs[2];
	uint32_t length;
	int rc, totlen;

	BUG_ON(!xd->xname);

	vecs[0].iov_base = &rx;
	vecs[0].iov_len = PAD(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;

	raw = jffs2_alloc_raw_node_ref();
	if (!raw)
		return -ENOMEM;
	raw->flash_offset = phys_ofs;
	raw->__totlen = PAD(totlen);
	raw->next_phys = NULL;
	raw->next_in_ino = (void *)xd;

	/* Setup raw-xattr */
	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=%u, at %#08x\n",
			      rc, totlen, length, phys_ofs);
		rc = rc ? rc : -EIO;
		if (length) {
			raw->flash_offset |= REF_OBSOLETE;
			raw->next_in_ino = NULL;
			jffs2_add_physical_node_ref(c, raw);
			jffs2_mark_node_obsolete(c, raw);
		} else {
			jffs2_free_raw_node_ref(raw);
		}
		return rc;
	}
	BUG_ON(raw->__totlen < sizeof(struct jffs2_raw_xattr));
	/* success */
	raw->flash_offset |= REF_PRISTINE;
	jffs2_add_physical_node_ref(c, raw);
	if (xd->node)
		delete_xattr_datum_node(c, xd);
	xd->node = raw;

	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,
						    uint32_t phys_ofs)
{
	/* 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)) {
			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);

	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, phys_ofs);
	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;
}

/* -------- xdatum 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.
 * delete_xattr_ref_node(c, ref)
 *   is used to delete a jffs2 node is dominated by xref. When EBS is enabled,
 *   it overwrites the obsolete node by myself. 
 * delete_xattr_ref(c, ref)
 *   is used to delete jffs2_xattr_ref object. If the reference counter of xdatum
 *   is refered by this xref become 0, delete_xattr_datum() is called later.
 * save_xattr_ref(c, ref, phys_ofs)
 *   is used to write xref to medium.
 * create_xattr_ref(c, ic, xd, phys_ofs)
 *   is used to create a new xref and write to medium.
 * 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_ilist(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_xref rr;
	size_t readlen;
	uint32_t crc, totlen;
	int rc;

	BUG_ON(ref_flags(ref->node) != REF_UNCHECKED);

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

	/* fixup superblock/eraseblock info */
	jeb = &c->blocks[ref_offset(ref->node) / c->sector_size];
	totlen = PAD(sizeof(rr));

	spin_lock(&c->erase_completion_lock);
	c->unchecked_size -= totlen; c->used_size += totlen;
	jeb->unchecked_size -= totlen; jeb->used_size += totlen;
	ref->node->flash_offset = ref_offset(ref->node) | REF_PRISTINE;
	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 void delete_xattr_ref_node(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
{
	struct jffs2_raw_xref rr;
	uint32_t length;
	int rc;

	if (jffs2_sum_active()) {
		memset(&rr, 0xff, sizeof(rr));
		rc = jffs2_flash_read(c, ref_offset(ref->node),
				      sizeof(struct jffs2_unknown_node),
				      &length, (char *)&rr);
		if (rc || length != sizeof(struct jffs2_unknown_node)) {
			JFFS2_ERROR("jffs2_flash_read()=%d, req=%u, read=%u at %#08x\n",
				    rc, sizeof(struct jffs2_unknown_node),
				    length, ref_offset(ref->node));
		}
		rc = jffs2_flash_write(c, ref_offset(ref->node), sizeof(rr),
				       &length, (char *)&rr);
		if (rc || length != sizeof(struct jffs2_raw_xref)) {
			JFFS2_ERROR("jffs2_flash_write()=%d, req=%u, wrote=%u at %#08x\n",
				    rc, sizeof(rr), length, ref_offset(ref->node));
		}
	}
	spin_lock(&c->erase_completion_lock);
	ref->node->next_in_ino = NULL;
	spin_unlock(&c->erase_completion_lock);
	jffs2_mark_node_obsolete(c, ref->node);
	ref->node = NULL;
}

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;

	BUG_ON(!ref->node);
	delete_xattr_ref_node(c, ref);

	list_del(&ref->ilist);
	xd = ref->xd;
	xd->refcnt--;
	if (!xd->refcnt)
		delete_xattr_datum(c, xd);
	jffs2_free_xattr_ref(ref);
}

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

	raw = jffs2_alloc_raw_node_ref();
	if (!raw)
		return -ENOMEM;
	raw->flash_offset = phys_ofs;
	raw->__totlen = PAD(sizeof(rr));
	raw->next_phys = NULL;
	raw->next_in_ino = (void *)ref;

	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));

	rr.ino = cpu_to_je32(ref->ic->ino);
	rr.xid = cpu_to_je32(ref->xd->xid);
	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=%u, retlen=%u, at %#08x\n",
			      ret, sizeof(rr), length, phys_ofs);
		ret = ret ? ret : -EIO;
		if (length) {
			raw->flash_offset |= REF_OBSOLETE;
			raw->next_in_ino = NULL;
			jffs2_add_physical_node_ref(c, raw);
			jffs2_mark_node_obsolete(c, raw);
		} else {
			jffs2_free_raw_node_ref(raw);
		}
		return ret;
	}
	raw->flash_offset |= REF_PRISTINE;

	jffs2_add_physical_node_ref(c, raw);
	if (ref->node)
		delete_xattr_ref_node(c, ref);
	ref->node = raw;

	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, uint32_t phys_ofs)
{
	/* 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, phys_ofs);
	if (ret) {
		jffs2_free_xattr_ref(ref);
		return ERR_PTR(ret);
	}

	/* Chain to inode */
	list_add(&ref->ilist, &ic->ilist);

	return ref; /* success */
}

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);
	list_for_each_entry_safe(ref, _ref, &ic->ilist, ilist)
		delete_xattr_ref(c, ref);
	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);
	list_for_each_entry_safe(ref, _ref, &ic->ilist, ilist) {
		list_del(&ref->ilist);
		xd = ref->xd;
		xd->refcnt--;
		if (!xd->refcnt) {
			unload_xattr_datum(c, xd);
			jffs2_free_xattr_datum(xd);
		}
		jffs2_free_xattr_ref(ref);
	}
	up_write(&c->xattr_sem);
}

static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{
	/* success of check_xattr_ref_ilist() 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;
	int rc = 0;

	if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
		return 0;
	down_write(&c->xattr_sem);
 retry:
	rc = 0;
	list_for_each_entry(ref, &ic->ilist, ilist) {
		if (!ref->xd->xname) {
			rc = load_xattr_datum(c, ref->xd);
			if (unlikely(rc > 0)) {
				delete_xattr_ref(c, ref);
				goto retry;
			} else if (unlikely(rc < 0))
				goto out;
		}
		cmp = ref;
		list_for_each_entry_continue(cmp, &ic->ilist, ilist) {
			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)) {
					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)) {
				delete_xattr_ref(c, cmp);
				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_temp);
	INIT_LIST_HEAD(&c->xattr_unchecked);

	init_rwsem(&c->xattr_sem);
	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;

	list_for_each_entry_safe(ref, _ref, &c->xattr_temp, ilist)
		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);
		}
	}
}

void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
{
	struct jffs2_xattr_ref *ref, *_ref;
	struct jffs2_xattr_datum *xd, *_xd;
	struct jffs2_inode_cache *ic;
	int i, xdatum_count =0, xdatum_unchecked_count = 0, xref_count = 0;

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

	/* Phase.1 */
	list_for_each_entry_safe(ref, _ref, &c->xattr_temp, ilist) {
		list_del_init(&ref->ilist);
		/* checking REF_UNCHECKED nodes */
		if (ref_flags(ref->node) != REF_PRISTINE) {
			if (verify_xattr_ref(c, ref)) {
				delete_xattr_ref_node(c, ref);
				jffs2_free_xattr_ref(ref);
				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) {
			if (ref_flags(ref->node) != REF_UNCHECKED)
				JFFS2_WARNING("xref(ino=%u, xid=%u) is orphan. \n",
					      ref->ino, ref->xid);
			delete_xattr_ref_node(c, ref);
			jffs2_free_xattr_ref(ref);
			continue;
		}
		ref->xd = xd;
		ref->ic = ic;
		xd->refcnt++;
		list_add_tail(&ref->ilist, &ic->ilist);
		xref_count++;
	}
	/* After this, ref->xid/ino are NEVER used. */

	/* Phase.2 */
	for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
		list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
			list_del_init(&xd->xindex);
			if (!xd->refcnt) {
				if (ref_flags(xd->node) != REF_UNCHECKED)
					JFFS2_WARNING("orphan xdatum(xid=%u, version=%u) at %#08x\n",
						      xd->xid, xd->version, ref_offset(xd->node));
				delete_xattr_datum(c, xd);
				continue;
			}
			if (ref_flags(xd->node) != REF_PRISTINE) {
				dbg_xattr("unchecked xdatum(xid=%u) at %#08x\n",
					  xd->xid, ref_offset(xd->node));
				list_add(&xd->xindex, &c->xattr_unchecked);
				xdatum_unchecked_count++;
			}
			xdatum_count++;
		}
	}
	/* build complete */
	JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum (%u unchecked) and "
		     "%u of xref found.\n", xdatum_count, xdatum_unchecked_count, xref_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;

	_xd = jffs2_find_xattr_datum(c, xid);
	if (_xd) {
		dbg_xattr("duplicate xdatum (xid=%u, version=%u/%u) at %#08x\n",
			  xid, version, _xd->version, ref_offset(_xd->node));
		if (version < _xd->version)
			return ERR_PTR(-EEXIST);
	}
	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]);

	if (_xd) {
		list_del_init(&_xd->xindex);
		delete_xattr_datum_node(c, _xd);
		jffs2_free_xattr_datum(_xd);
	}
	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;
	struct jffs2_xattr_datum *xd;
	struct xattr_handler *xhandle;
	ssize_t len, rc;
	int retry = 0;

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

	down_read(&c->xattr_sem);
 retry:
	len = 0;
	list_for_each_entry(ref, &ic->ilist, ilist) {
		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)) {
					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;
	int rc, retry = 0;

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

	down_read(&c->xattr_sem);
 retry:
	list_for_each_entry(ref, &ic->ilist, ilist) {
		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)) {
					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;
	uint32_t phys_ofs, length, request;
	int rc;

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

	request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
	rc = jffs2_reserve_space(c, request, &phys_ofs, &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:
	list_for_each_entry(ref, &ic->ilist, ilist) {
		xd = ref->xd;
		if (xd->xprefix != xprefix)
			continue;
		if (!xd->xname) {
			rc = load_xattr_datum(c, xd);
			if (unlikely(rc > 0)) {
				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) {
				delete_xattr_ref(c, ref);
				rc = 0;
				goto out;
			}
			goto found;
		}
	}
	/* not found */
	ref = NULL;
	if (flags & XATTR_REPLACE) {
		rc = -ENODATA;
		goto out;
	}
	if (!buffer) {
		rc = -EINVAL;
		goto out;
	}
 found:
	xd = create_xattr_datum(c, xprefix, xname, buffer, size, phys_ofs);
	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, &phys_ofs, &length,
				 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
	if (rc) {
		JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
		down_write(&c->xattr_sem);
		xd->refcnt--;
		if (!xd->refcnt)
			delete_xattr_datum(c, xd);
		up_write(&c->xattr_sem);
		return rc;
	}
	down_write(&c->xattr_sem);
	newref = create_xattr_ref(c, ic, xd, phys_ofs);
	if (IS_ERR(newref)) {
		rc = PTR_ERR(newref);
		xd->refcnt--;
		if (!xd->refcnt)
			delete_xattr_datum(c, xd);
	} else if (ref) {
		/* If replaced xattr_ref exists */
		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)
 *   is used to move xdatum into new node.
 * jffs2_garbage_collect_xattr_ref(c, ref)
 *   is used to move xref into new node.
 * jffs2_garbage_collect_xattr(c, ic)
 *   is used to call appropriate garbage collector function, if argument
 *   pointer (ic) is the reference of xdatum/xref.
 * jffs2_verify_xattr(c)
 *   is used to call do_verify_xattr_datum() before garbage collecting.
 * -------------------------------------------------- */
static int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c,
					     struct jffs2_xattr_datum *xd)
{
	/* must be called under down_write(xattr_sem), and called from GC thread */
	uint32_t phys_ofs, totlen, length, old_ofs;
	int rc;

	BUG_ON(!xd->node);

	old_ofs = ref_offset(xd->node);
	totlen = ref_totlen(c, c->gcblock, xd->node);
	if (totlen < sizeof(struct jffs2_raw_xattr))
		return -EINVAL;

	if (!xd->xname) {
		rc = load_xattr_datum(c, xd);
		if (unlikely(rc > 0)) {
			delete_xattr_datum_node(c, xd);
			return 0;
		} else if (unlikely(rc < 0))
			return -EINVAL;
	}
	rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE);
	if (rc || length < totlen) {
		JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen);
		return rc ? rc : -EBADFD;
	}
	rc = save_xattr_datum(c, xd, phys_ofs);
	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));
	return rc;
}


static int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c,
					   struct jffs2_xattr_ref *ref)
{
	/* must be called under down(alloc_sem) */
	uint32_t phys_ofs, totlen, length, old_ofs;
	int rc;

	BUG_ON(!ref->node);

	old_ofs = ref_offset(ref->node);
	totlen = ref_totlen(c, c->gcblock, ref->node);
	if (totlen != sizeof(struct jffs2_raw_xref))
		return -EINVAL;
	rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE);
	if (rc || length < totlen) {
		JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n",
			      __FUNCTION__, rc, totlen);
		return rc ? rc : -EBADFD;
	}
	rc = save_xattr_ref(c, ref, phys_ofs);
	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));
	return rc;
}

int jffs2_garbage_collect_xattr(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{
	struct jffs2_xattr_datum *xd;
	struct jffs2_xattr_ref *ref;
	int ret;

	switch (ic->class) {
	case RAWNODE_CLASS_XATTR_DATUM:
		spin_unlock(&c->erase_completion_lock);

		down_write(&c->xattr_sem);
		xd = (struct jffs2_xattr_datum *)ic;
		ret = xd ? jffs2_garbage_collect_xattr_datum(c, xd) : 0;
		up_write(&c->xattr_sem);
		break;
	case RAWNODE_CLASS_XATTR_REF:
		spin_unlock(&c->erase_completion_lock);

		down_write(&c->xattr_sem);
		ref = (struct jffs2_xattr_ref *)ic;
		ret = ref ? jffs2_garbage_collect_xattr_ref(c, ref) : 0;
		up_write(&c->xattr_sem);
		break;
	default:
		/* This node is not xattr_datum/xattr_ref */
		ret = 1;
		break;
	}
	return ret;
}

int jffs2_verify_xattr(struct jffs2_sb_info *c)
{
	struct jffs2_xattr_datum *xd, *_xd;
	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) {
			list_del_init(&xd->xindex);
			break;
		} else if (rc > 0) {
			list_del_init(&xd->xindex);
			delete_xattr_datum_node(c, xd);
		}
	}
	up_write(&c->xattr_sem);

	return list_empty(&c->xattr_unchecked) ? 1 : 0;
}
