From aa98d7cf59b5b0764d3502662053489585faf2fe Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Sat, 13 May 2006 15:09:47 +0900 Subject: [JFFS2][XATTR] XATTR support on JFFS2 (version. 5) This attached patches provide xattr support including POSIX-ACL and SELinux support on JFFS2 (version.5). There are some significant differences from previous version posted at last December. The biggest change is addition of EBS(Erase Block Summary) support. Currently, both kernel and usermode utility (sumtool) can recognize xattr nodes which have JFFS2_NODETYPE_XATTR/_XREF nodetype. In addition, some bugs are fixed. - A potential race condition was fixed. - Unexpected fail when updating a xattr by same name/value pair was fixed. - A bug when removing xattr name/value pair was fixed. The fundamental structures (such as using two new nodetypes and exclusion mechanism by rwsem) are unchanged. But most of implementation were reviewed and updated if necessary. Espacially, we had to change several internal implementations related to load_xattr_datum() to avoid a potential race condition. [1/2] xattr_on_jffs2.kernel.version-5.patch [2/2] xattr_on_jffs2.utils.version-5.patch Signed-off-by: KaiGai Kohei Signed-off-by: David Woodhouse --- fs/jffs2/gc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'fs/jffs2/gc.c') diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 967fb2cf8e21..4ea1b7f0ae78 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c @@ -125,6 +125,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) struct jffs2_eraseblock *jeb; struct jffs2_raw_node_ref *raw; int ret = 0, inum, nlink; + int xattr = 0; if (down_interruptible(&c->alloc_sem)) return -EINTR; @@ -138,7 +139,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) the node CRCs etc. Do it now. */ /* checked_ino is protected by the alloc_sem */ - if (c->checked_ino > c->highest_ino) { + if (c->checked_ino > c->highest_ino && xattr) { printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", c->unchecked_size); jffs2_dbg_dump_block_lists_nolock(c); @@ -148,6 +149,9 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) spin_unlock(&c->erase_completion_lock); + if (!xattr) + xattr = jffs2_verify_xattr(c); + spin_lock(&c->inocache_lock); ic = jffs2_get_ino_cache(c, c->checked_ino++); @@ -262,6 +266,16 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) ic = jffs2_raw_ref_to_ic(raw); + /* 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) + goto release_sem; + /* We need to hold the inocache. Either the erase_completion_lock or the inocache_lock are sufficient; we trade down since the inocache_lock causes less contention. */ -- cgit v1.2.1 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 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'fs/jffs2/gc.c') 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 -- cgit v1.2.1