[JFFS2] Fix ACL vs. mode handling.
[safe/jmp/linux-2.6] / fs / jffs2 / nodemgmt.c
index ac0c350..5b49bff 100644 (file)
@@ -1,14 +1,12 @@
 /*
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
- * Copyright (C) 2001-2003 Red Hat, Inc.
+ * Copyright © 2001-2007 Red Hat, Inc.
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodemgmt.c,v 1.127 2005/09/20 15:49:12 dedekind Exp $
- *
  */
 
 #include <linux/kernel.h>
@@ -156,7 +154,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
        while(ret == -EAGAIN) {
                ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
                if (ret) {
-                       D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
+                       D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
                }
        }
        spin_unlock(&c->erase_completion_lock);
@@ -172,6 +170,11 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
 static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
 {
 
+       if (c->nextblock == NULL) {
+               D1(printk(KERN_DEBUG "jffs2_close_nextblock: Erase block at 0x%08x has already been placed in a list\n",
+                 jeb->offset));
+               return;
+       }
        /* Check, if we have a dirty block now, or if it was dirty already */
        if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
                c->dirty_size += jeb->wasted_size;
@@ -420,7 +423,12 @@ struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
           even after refiling c->nextblock */
        if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE))
            && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) {
-               printk(KERN_WARNING "argh. node added in wrong place\n");
+               printk(KERN_WARNING "argh. node added in wrong place at 0x%08x(%d)\n", ofs & ~3, ofs & 3);
+               if (c->nextblock)
+                       printk(KERN_WARNING "nextblock 0x%08x", c->nextblock->offset);
+               else
+                       printk(KERN_WARNING "No nextblock");
+               printk(", expected at %08x\n", jeb->offset + (c->sector_size - jeb->free_size));
                return ERR_PTR(-EINVAL);
        }
 #endif
@@ -683,19 +691,26 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
                spin_lock(&c->erase_completion_lock);
 
                ic = jffs2_raw_ref_to_ic(ref);
-               /* It seems we should never call jffs2_mark_node_obsolete() for
-                  XATTR nodes.... yet. Make sure we notice if/when we change
-                  that :) */
-               BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE);
                for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino))
                        ;
 
                *p = ref->next_in_ino;
                ref->next_in_ino = NULL;
 
-               if (ic->nodes == (void *)ic && ic->nlink == 0)
-                       jffs2_del_ino_cache(c, ic);
-
+               switch (ic->class) {
+#ifdef CONFIG_JFFS2_FS_XATTR
+                       case RAWNODE_CLASS_XATTR_DATUM:
+                               jffs2_release_xattr_datum(c, (struct jffs2_xattr_datum *)ic);
+                               break;
+                       case RAWNODE_CLASS_XATTR_REF:
+                               jffs2_release_xattr_ref(c, (struct jffs2_xattr_ref *)ic);
+                               break;
+#endif
+                       default:
+                               if (ic->nodes == (void *)ic && ic->nlink == 0)
+                                       jffs2_del_ino_cache(c, ic);
+                               break;
+               }
                spin_unlock(&c->erase_completion_lock);
        }