]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/jffs2/gc.c
[JFFS2][XATTR] Remove 'struct list_head ilist' from jffs2_inode_cache.
[linux-2.6-omap-h63xx.git] / fs / jffs2 / gc.c
index f9ffece453a38e65542db843701749f943a71283..4ea1b7f0ae783d6ba390f43c5d856d1c863c1399 100644 (file)
@@ -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++);
@@ -181,6 +185,10 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
                           and trigger the BUG() above while we haven't yet
                           finished checking all its nodes */
                        D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
+                       /* We need to come back again for the _same_ inode. We've
+                        made no progress in this case, but that should be OK */
+                       c->checked_ino--;
+
                        up(&c->alloc_sem);
                        sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
                        return 0;
@@ -258,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. */