From 084702e00111eb9ffb6d8a5c1938b8e5423e40a8 Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Sat, 13 May 2006 15:16:13 +0900 Subject: [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: KaiGai Kohei --- fs/jffs2/gc.c | 21 +++++++++++------ fs/jffs2/xattr.c | 68 +++++++++++++++++--------------------------------------- fs/jffs2/xattr.h | 4 ++-- 3 files changed, 36 insertions(+), 57 deletions(-) (limited to 'fs/jffs2') diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 4ea1b7f0ae78..a5ef9814f165 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c @@ -266,15 +266,22 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) 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. - 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. - ret < 0 : ic is xattr_datum/xattr_ref, but GC was FAILED. - ret > 0 : ic is NOT xattr_datum/xattr_ref. - */ - ret = jffs2_garbage_collect_xattr(c, ic); - if (ret <= 0) + * We can decide whether this node is inode or xattr by ic->class. */ + if (ic->class == RAWNODE_CLASS_XATTR_DATUM + || ic->class == RAWNODE_CLASS_XATTR_REF) { + BUG_ON(raw->next_in_ino != (void *)ic); + spin_unlock(&c->erase_completion_lock); + + 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; + } +#endif /* We need to hold the inocache. Either the erase_completion_lock or the inocache_lock are sufficient; we trade down since the inocache_lock diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index b16bc71c9cd2..9c1f401d12d7 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -1170,104 +1170,76 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, * 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) +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; + int rc = -EINVAL; + down_write(&c->xattr_sem); 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; + goto out; if (!xd->xname) { rc = load_xattr_datum(c, xd); if (unlikely(rc > 0)) { delete_xattr_datum_node(c, xd); - return 0; + rc = 0; + goto out; } else if (unlikely(rc < 0)) - return -EINVAL; + goto out; } 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 = rc ? rc : -EBADFD; + goto out; } 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)); + out: + up_write(&c->xattr_sem); return rc; } -static int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, - struct jffs2_xattr_ref *ref) +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; + int rc = -EINVAL; + down_write(&c->xattr_sem); 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; + goto out; + 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 = rc ? rc : -EBADFD; + goto out; } 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)); + out: + up_write(&c->xattr_sem); 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; diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index 0360097e5933..762814b7107b 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h @@ -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_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 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); #define jffs2_xattr_delete_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_xattr_handlers NULL -- cgit v1.2.3