* 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)
+ * 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)
BUG_ON(!ref->node);
delete_xattr_ref_node(c, ref);
- list_del(&ref->ilist);
xd = ref->xd;
xd->refcnt--;
if (!xd->refcnt)
}
/* Chain to inode */
- list_add(&ref->ilist, &ic->ilist);
+ ref->next = ic->xref;
+ ic->xref = ref;
return ref; /* success */
}
return;
down_write(&c->xattr_sem);
- list_for_each_entry_safe(ref, _ref, &ic->ilist, ilist)
+ for (ref = ic->xref; ref; ref = _ref) {
+ _ref = ref->next;
delete_xattr_ref(c, ref);
+ }
+ ic->xref = NULL;
up_write(&c->xattr_sem);
}
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);
+ for (ref = ic->xref; ref; ref = _ref) {
+ _ref = ref->next;
xd = ref->xd;
xd->refcnt--;
if (!xd->refcnt) {
}
jffs2_free_xattr_ref(ref);
}
+ ic->xref = NULL;
up_write(&c->xattr_sem);
}
-static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
+static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{
- /* success of check_xattr_ref_ilist() means taht inode (ic) dose not have
+ /* 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;
+ struct jffs2_xattr_ref *ref, *cmp, **pref;
int rc = 0;
if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
down_write(&c->xattr_sem);
retry:
rc = 0;
- list_for_each_entry(ref, &ic->ilist, ilist) {
+ 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;
}
- cmp = ref;
- list_for_each_entry_continue(cmp, &ic->ilist, ilist) {
+ for (cmp=ref->next, pref=&ref->next; cmp; pref=&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)) {
+ *pref = cmp->next;
delete_xattr_ref(c, cmp);
goto retry;
} else if (unlikely(rc < 0))
}
if (ref->xd->xprefix == cmp->xd->xprefix
&& !strcmp(ref->xd->xname, cmp->xd->xname)) {
+ *pref = cmp->next;
delete_xattr_ref(c, cmp);
goto retry;
}
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);
+ c->xref_temp = NULL;
init_rwsem(&c->xattr_sem);
c->xdatum_mem_usage = 0;
struct jffs2_xattr_ref *ref, *_ref;
int i;
- list_for_each_entry_safe(ref, _ref, &c->xattr_temp, ilist)
+ for (ref=c->xref_temp; ref; ref = _ref) {
+ _ref = ref->next;
jffs2_free_xattr_ref(ref);
+ }
+ c->xref_temp = NULL;
for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
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);
+ for (ref=c->xref_temp; ref; ref=_ref) {
+ _ref = ref->next;
/* checking REF_UNCHECKED nodes */
if (ref_flags(ref->node) != REF_PRISTINE) {
if (verify_xattr_ref(c, ref)) {
ref->xd = xd;
ref->ic = ic;
xd->refcnt++;
- list_add_tail(&ref->ilist, &ic->ilist);
+ ref->next = ic->xref;
+ ic->xref = ref;
xref_count++;
}
+ c->xref_temp = NULL;
/* After this, ref->xid/ino are NEVER used. */
/* Phase.2 */
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_ref *ref, **pref;
struct jffs2_xattr_datum *xd;
struct xattr_handler *xhandle;
ssize_t len, rc;
int retry = 0;
- rc = check_xattr_ref_ilist(c, ic);
+ rc = check_xattr_ref_inode(c, ic);
if (unlikely(rc))
return rc;
down_read(&c->xattr_sem);
retry:
len = 0;
- list_for_each_entry(ref, &ic->ilist, ilist) {
+ 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) {
} 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))
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;
+ struct jffs2_xattr_ref *ref, **pref;
int rc, retry = 0;
- rc = check_xattr_ref_ilist(c, ic);
+ rc = check_xattr_ref_inode(c, ic);
if (unlikely(rc))
return rc;
down_read(&c->xattr_sem);
retry:
- list_for_each_entry(ref, &ic->ilist, ilist) {
+ for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
BUG_ON(ref->ic!=ic);
xd = ref->xd;
} 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)) {
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;
+ struct jffs2_xattr_ref *ref, *newref, **pref;
uint32_t phys_ofs, length, request;
int rc;
- rc = check_xattr_ref_ilist(c, ic);
+ rc = check_xattr_ref_inode(c, ic);
if (unlikely(rc))
return rc;
/* Find existing xattr */
down_write(&c->xattr_sem);
retry:
- list_for_each_entry(ref, &ic->ilist, ilist) {
+ 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 (!buffer) {
+ *pref = ref->next;
delete_xattr_ref(c, ref);
rc = 0;
goto out;
}
}
/* not found */
- ref = NULL;
if (flags & XATTR_REPLACE) {
rc = -ENODATA;
goto out;
return rc;
}
down_write(&c->xattr_sem);
+ if (ref)
+ *pref = ref->next;
newref = create_xattr_ref(c, ic, xd, phys_ofs);
if (IS_ERR(newref)) {
+ if (ref) {
+ ref->next = ic->xref;
+ ic->xref = ref;
+ }
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: