Commit 084702e0 authored by KaiGai Kohei's avatar KaiGai Kohei

[JFFS2][XATTR] Remove jffs2_garbage_collect_xattr(c, ic)

Remove jffs2_garbage_collect_xattr(c, ic).
jffs2_garbage_collect_xattr_datum/ref() are called from gc.c directly.

In original implementation, jffs2_garbage_collect_xattr(c, ic) returns
with holding a spinlock if 'ic' is inode_cache. But it returns after
releasing a spinlock if 'ic' is xattr_datum/ref.
It looks so confusable behavior. Thus, this patch makes caller manage
locking/unlocking.

[5/10] jffs2-xattr-v5.1-05-update_xattr_gc.patch
Signed-off-by: default avatarKaiGai Kohei <kaigai@ak.jp.nec.com>
parent 8f2b6f49
...@@ -266,15 +266,22 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) ...@@ -266,15 +266,22 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
ic = jffs2_raw_ref_to_ic(raw); ic = jffs2_raw_ref_to_ic(raw);
#ifdef CONFIG_JFFS2_FS_XATTR
/* When 'ic' refers xattr_datum/xattr_ref, this node is GCed as xattr. /* When 'ic' refers xattr_datum/xattr_ref, this node is GCed as xattr.
We can decide whether this node is inode or xattr by ic->class. * We can decide whether this node is inode or xattr by ic->class. */
ret = 0 : ic is xattr_datum/xattr_ref, and GC was SUCCESSED. if (ic->class == RAWNODE_CLASS_XATTR_DATUM
ret < 0 : ic is xattr_datum/xattr_ref, but GC was FAILED. || ic->class == RAWNODE_CLASS_XATTR_REF) {
ret > 0 : ic is NOT xattr_datum/xattr_ref. BUG_ON(raw->next_in_ino != (void *)ic);
*/ spin_unlock(&c->erase_completion_lock);
ret = jffs2_garbage_collect_xattr(c, ic);
if (ret <= 0) if (ic->class == RAWNODE_CLASS_XATTR_DATUM) {
ret = jffs2_garbage_collect_xattr_datum(c, (struct jffs2_xattr_datum *)ic);
} else {
ret = jffs2_garbage_collect_xattr_ref(c, (struct jffs2_xattr_ref *)ic);
}
goto release_sem; goto release_sem;
}
#endif
/* We need to hold the inocache. Either the erase_completion_lock or /* We need to hold the inocache. Either the erase_completion_lock or
the inocache_lock are sufficient; we trade down since the inocache_lock the inocache_lock are sufficient; we trade down since the inocache_lock
......
...@@ -1170,104 +1170,76 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -1170,104 +1170,76 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
* is used to move xdatum into new node. * is used to move xdatum into new node.
* jffs2_garbage_collect_xattr_ref(c, ref) * jffs2_garbage_collect_xattr_ref(c, ref)
* is used to move xref into new node. * 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) * jffs2_verify_xattr(c)
* is used to call do_verify_xattr_datum() before garbage collecting. * is used to call do_verify_xattr_datum() before garbage collecting.
* -------------------------------------------------- */ * -------------------------------------------------- */
static int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
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; uint32_t phys_ofs, totlen, length, old_ofs;
int rc; int rc = -EINVAL;
down_write(&c->xattr_sem);
BUG_ON(!xd->node); BUG_ON(!xd->node);
old_ofs = ref_offset(xd->node); old_ofs = ref_offset(xd->node);
totlen = ref_totlen(c, c->gcblock, xd->node); totlen = ref_totlen(c, c->gcblock, xd->node);
if (totlen < sizeof(struct jffs2_raw_xattr)) if (totlen < sizeof(struct jffs2_raw_xattr))
return -EINVAL; goto out;
if (!xd->xname) { if (!xd->xname) {
rc = load_xattr_datum(c, xd); rc = load_xattr_datum(c, xd);
if (unlikely(rc > 0)) { if (unlikely(rc > 0)) {
delete_xattr_datum_node(c, xd); delete_xattr_datum_node(c, xd);
return 0; rc = 0;
goto out;
} else if (unlikely(rc < 0)) } else if (unlikely(rc < 0))
return -EINVAL; goto out;
} }
rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE); rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE);
if (rc || length < totlen) { if (rc || length < totlen) {
JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen); JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen);
return rc ? rc : -EBADFD; rc = rc ? rc : -EBADFD;
goto out;
} }
rc = save_xattr_datum(c, xd, phys_ofs); rc = save_xattr_datum(c, xd, phys_ofs);
if (!rc) if (!rc)
dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n", dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
xd->xid, xd->version, old_ofs, ref_offset(xd->node)); xd->xid, xd->version, old_ofs, ref_offset(xd->node));
out:
up_write(&c->xattr_sem);
return rc; return rc;
} }
static int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
struct jffs2_xattr_ref *ref)
{ {
/* must be called under down(alloc_sem) */
uint32_t phys_ofs, totlen, length, old_ofs; uint32_t phys_ofs, totlen, length, old_ofs;
int rc; int rc = -EINVAL;
down_write(&c->xattr_sem);
BUG_ON(!ref->node); BUG_ON(!ref->node);
old_ofs = ref_offset(ref->node); old_ofs = ref_offset(ref->node);
totlen = ref_totlen(c, c->gcblock, ref->node); totlen = ref_totlen(c, c->gcblock, ref->node);
if (totlen != sizeof(struct jffs2_raw_xref)) if (totlen != sizeof(struct jffs2_raw_xref))
return -EINVAL; goto out;
rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE); rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE);
if (rc || length < totlen) { if (rc || length < totlen) {
JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n", JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n",
__FUNCTION__, rc, totlen); __FUNCTION__, rc, totlen);
return rc ? rc : -EBADFD; rc = rc ? rc : -EBADFD;
goto out;
} }
rc = save_xattr_ref(c, ref, phys_ofs); rc = save_xattr_ref(c, ref, phys_ofs);
if (!rc) if (!rc)
dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n", 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)); ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
out:
up_write(&c->xattr_sem);
return rc; 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) int jffs2_verify_xattr(struct jffs2_sb_info *c)
{ {
struct jffs2_xattr_datum *xd, *_xd; struct jffs2_xattr_datum *xd, *_xd;
......
...@@ -69,7 +69,8 @@ extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c ...@@ -69,7 +69,8 @@ extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c
extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
extern int jffs2_garbage_collect_xattr(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); extern int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd);
extern int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref);
extern int jffs2_verify_xattr(struct jffs2_sb_info *c); extern int jffs2_verify_xattr(struct jffs2_sb_info *c);
extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
...@@ -94,7 +95,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); ...@@ -94,7 +95,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
#define jffs2_xattr_delete_inode(c, ic) #define jffs2_xattr_delete_inode(c, ic)
#define jffs2_xattr_free_inode(c, ic) #define jffs2_xattr_free_inode(c, ic)
#define jffs2_garbage_collect_xattr(c, ic) (1)
#define jffs2_verify_xattr(c) (1) #define jffs2_verify_xattr(c) (1)
#define jffs2_xattr_handlers NULL #define jffs2_xattr_handlers NULL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment