]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/jffs2/nodemgmt.c
[PATCH] x86_64: Calgary IOMMU - move valid_dma_direction into the callers
[linux-2.6-omap-h63xx.git] / fs / jffs2 / nodemgmt.c
index 01bf2773fe4d55cfec3f9a4f1079dc1eb734fbaf..8bedfd2ff68991c19f212159d48fb6b5694e7700 100644 (file)
@@ -138,7 +138,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
        }
        spin_unlock(&c->erase_completion_lock);
        if (!ret)
-               ret = jffs2_prealloc_raw_node_refs(c, 1);
+               ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
        if (ret)
                up(&c->alloc_sem);
        return ret;
@@ -161,7 +161,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
        }
        spin_unlock(&c->erase_completion_lock);
        if (!ret)
-               ret = jffs2_prealloc_raw_node_refs(c, 1);
+               ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
 
        return ret;
 }
@@ -317,6 +317,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
                }
        } else {
                if (jeb && minsize > jeb->free_size) {
+                       uint32_t waste;
+
                        /* Skip the end of this block and file it as having some dirty space */
                        /* If there's a pending write to it, flush now */
 
@@ -329,10 +331,26 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
                                goto restart;
                        }
 
-                       c->wasted_size += jeb->free_size;
-                       c->free_size -= jeb->free_size;
-                       jeb->wasted_size += jeb->free_size;
-                       jeb->free_size = 0;
+                       spin_unlock(&c->erase_completion_lock);
+
+                       ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
+                       if (ret)
+                               return ret;
+                       /* Just lock it again and continue. Nothing much can change because
+                          we hold c->alloc_sem anyway. In fact, it's not entirely clear why
+                          we hold c->erase_completion_lock in the majority of this function...
+                          but that's a question for another (more caffeine-rich) day. */
+                       spin_lock(&c->erase_completion_lock);
+
+                       waste = jeb->free_size;
+                       jffs2_link_node_ref(c, jeb,
+                                           (jeb->offset + c->sector_size - waste) | REF_OBSOLETE,
+                                           waste, NULL);
+                       /* FIXME: that made it count as dirty. Convert to wasted */
+                       jeb->dirty_size -= waste;
+                       c->dirty_size -= waste;
+                       jeb->wasted_size += waste;
+                       c->wasted_size += waste;
 
                        jffs2_close_nextblock(c, jeb);
                        jeb = NULL;
@@ -464,7 +482,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
        size_t retlen;
        uint32_t freed_len;
 
-       if(!ref) {
+       if(unlikely(!ref)) {
                printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n");
                return;
        }
@@ -516,7 +534,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
 
        // Take care, that wasted size is taken into concern
        if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + freed_len)) && jeb != c->nextblock) {
-               D1(printk(KERN_DEBUG "Dirtying\n"));
+               D1(printk("Dirtying\n"));
                addedsize = freed_len;
                jeb->dirty_size += freed_len;
                c->dirty_size += freed_len;
@@ -538,7 +556,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
                        }
                }
        } else {
-               D1(printk(KERN_DEBUG "Wasting\n"));
+               D1(printk("Wasting\n"));
                addedsize = 0;
                jeb->wasted_size += freed_len;
                c->wasted_size += freed_len;
@@ -617,7 +635,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
        /* The erase_free_sem is locked, and has been since before we marked the node obsolete
           and potentially put its eraseblock onto the erase_pending_list. Thus, we know that
           the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet
-          by jffs2_free_all_node_refs() in erase.c. Which is nice. */
+          by jffs2_free_jeb_node_refs() in erase.c. Which is nice. */
 
        D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref)));
        ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
@@ -682,55 +700,6 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
                spin_unlock(&c->erase_completion_lock);
        }
 
-
-       /* Merge with the next node in the physical list, if there is one
-          and if it's also obsolete and if it doesn't belong to any inode */
-       if (ref->next_phys && ref_obsolete(ref->next_phys) &&
-           !ref->next_phys->next_in_ino) {
-               struct jffs2_raw_node_ref *n = ref->next_phys;
-
-               spin_lock(&c->erase_completion_lock);
-
-#ifdef TEST_TOTLEN
-               ref->__totlen += n->__totlen;
-#endif
-               ref->next_phys = n->next_phys;
-                if (jeb->last_node == n) jeb->last_node = ref;
-               if (jeb->gc_node == n) {
-                       /* gc will be happy continuing gc on this node */
-                       jeb->gc_node=ref;
-               }
-               spin_unlock(&c->erase_completion_lock);
-
-               __jffs2_free_raw_node_ref(n);
-       }
-
-       /* Also merge with the previous node in the list, if there is one
-          and that one is obsolete */
-       if (ref != jeb->first_node ) {
-               struct jffs2_raw_node_ref *p = jeb->first_node;
-
-               spin_lock(&c->erase_completion_lock);
-
-               while (p->next_phys != ref)
-                       p = p->next_phys;
-
-               if (ref_obsolete(p) && !ref->next_in_ino) {
-#ifdef TEST_TOTLEN
-                       p->__totlen += ref->__totlen;
-#endif
-                       if (jeb->last_node == ref) {
-                               jeb->last_node = p;
-                       }
-                       if (jeb->gc_node == ref) {
-                               /* gc will be happy continuing gc on this node */
-                               jeb->gc_node=p;
-                       }
-                       p->next_phys = ref->next_phys;
-                       __jffs2_free_raw_node_ref(ref);
-               }
-               spin_unlock(&c->erase_completion_lock);
-       }
  out_erase_sem:
        up(&c->erase_free_sem);
 }