[JFFS2] Deletion dirents should be REF_NORMAL, not REF_PRISTINE.
authorDavid Woodhouse <dwmw2@infradead.org>
Fri, 29 Jun 2007 12:39:57 +0000 (13:39 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Thu, 2 Aug 2007 20:39:50 +0000 (21:39 +0100)
Otherwise they'll never actually get garbage-collected.
Noted by Jonathan Larmour.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
fs/jffs2/nodelist.h
fs/jffs2/readinode.c
fs/jffs2/scan.c
fs/jffs2/write.c

index 25126a062cae6c3927e3e2e9f2df76f21217bdb7..bc5509fe577b878f542ccf3334a412c1a375d258 100644 (file)
@@ -139,6 +139,11 @@ static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_nod
 #define ref_obsolete(ref)      (((ref)->flash_offset & 3) == REF_OBSOLETE)
 #define mark_ref_normal(ref)    do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0)
 
+/* Dirent nodes should be REF_PRISTINE only if they are not a deletion
+   dirent. Deletion dirents should be REF_NORMAL so that GC gets to
+   throw them away when appropriate */
+#define dirent_node_state(rd)  ( (je32_to_cpu((rd)->ino)?REF_PRISTINE:REF_NORMAL) )
+
 /* NB: REF_PRISTINE for an inode-less node (ref->next_in_ino == NULL) indicates
    it is an unknown node of type JFFS2_NODETYPE_RWCOMPAT_COPY, so it'll get
    copied. If you need to do anything different to GC inode-less nodes, then
index 7b363786c2d2f745c30dcd53b0005e18b056df11..170da20b97c781eb3af86d8232575b5a9398e981 100644 (file)
@@ -613,7 +613,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
                jeb->unchecked_size -= len;
                c->used_size += len;
                c->unchecked_size -= len;
-               ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
+               ref->flash_offset = ref_offset(ref) | dirent_node_state(rd);
                spin_unlock(&c->erase_completion_lock);
        }
 
index 2a1c976c7924c8674cda40985a5848cfe9ff02ef..6c75cd4333424347c0f37b410d7ef9e621ddb8c4 100644 (file)
@@ -1049,7 +1049,8 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
                return -ENOMEM;
        }
 
-       fd->raw = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rd->totlen)), ic);
+       fd->raw = jffs2_link_node_ref(c, jeb, ofs | dirent_node_state(rd),
+                                     PAD(je32_to_cpu(rd->totlen)), ic);
 
        fd->next = NULL;
        fd->version = je32_to_cpu(rd->version);
index 1406f2ce20a72058ed5ea8c8ff3de727b612a40c..bc6185933664b68e76694de35ed1df68c6408699 100644 (file)
@@ -296,7 +296,8 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
                return ERR_PTR(ret?ret:-EIO);
        }
        /* Mark the space used */
-       fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | REF_PRISTINE, PAD(sizeof(*rd)+namelen), f->inocache);
+       fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | dirent_node_state(rd),
+                                             PAD(sizeof(*rd)+namelen), f->inocache);
        if (IS_ERR(fd->raw)) {
                void *hold_err = fd->raw;
                /* Release the full_dirent which is now useless, and return */