summaryrefslogtreecommitdiffstats
path: root/fs/jffs/jffs_fm.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-10-05 01:18:40 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-10-05 01:18:40 +0000
commit012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch)
tree87efc733f9b164e8c85c0336f92c8fb7eff6d183 /fs/jffs/jffs_fm.c
parent625a1589d3d6464b5d90b8a0918789e3afffd220 (diff)
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found that this kernel will only boot SMP on Origin; the UP kernel freeze soon after bootup with SCSI timeout messages. I commit this anyway since I found that the last CVS versions had the same problem.
Diffstat (limited to 'fs/jffs/jffs_fm.c')
-rw-r--r--fs/jffs/jffs_fm.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
index 3140b8a53..b9bbeb4a9 100644
--- a/fs/jffs/jffs_fm.c
+++ b/fs/jffs/jffs_fm.c
@@ -10,7 +10,7 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: jffs_fm.c,v 1.14 2000/08/09 14:26:35 dwmw2 Exp $
+ * $Id: jffs_fm.c,v 1.18 2000/08/21 10:41:45 dwmw2 Exp $
*
* Ported to Linux 2.3.x and MTD:
* Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -57,17 +57,26 @@ jffs_build_begin(struct jffs_control *c, kdev_t dev)
fmc->used_size = 0;
fmc->dirty_size = 0;
+ fmc->free_size = mtd->size;
fmc->sector_size = mtd->erasesize;
fmc->max_chunk_size = fmc->sector_size >> 1;
- fmc->min_free_size = (fmc->sector_size << 1) - fmc->max_chunk_size;
+ /* min_free_size:
+ 1 sector, obviously.
+ + 1 x max_chunk_size, for when a nodes overlaps the end of a sector
+ + 1 x max_chunk_size again, which ought to be enough to handle
+ the case where a rename causes a name to grow, and GC has
+ to write out larger nodes than the ones it's obsoleting.
+ We should fix it so it doesn't have to write the name
+ _every_ time. Later.
+ */
+ fmc->min_free_size = fmc->sector_size << 1;
fmc->mtd = mtd;
- init_MUTEX(&fmc->gclock);
fmc->c = c;
fmc->head = 0;
fmc->tail = 0;
fmc->head_extra = 0;
fmc->tail_extra = 0;
- init_MUTEX(&fmc->wlock);
+ init_MUTEX(&fmc->biglock);
return fmc;
}
@@ -203,6 +212,11 @@ jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
free_chunk_size1 = jffs_free_size1(fmc);
free_chunk_size2 = jffs_free_size2(fmc);
+ if (free_chunk_size1 + free_chunk_size2 != fmc->free_size) {
+ printk(KERN_WARNING "Free size accounting screwed\n");
+ printk(KERN_WARNING "free_chunk_size1 == 0x%x, free_chunk_size2 == 0x%x, fmc->free_size == 0x%x\n", free_chunk_size1, free_chunk_size2, fmc->free_size);
+ }
+
D3(printk("jffs_fmalloc(): free_chunk_size1 = %u, "
"free_chunk_size2 = %u\n",
free_chunk_size1, free_chunk_size2));
@@ -240,6 +254,7 @@ jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
fm->offset = fmc->flash_start;
}
fm->size = size;
+ fmc->free_size -= size;
fmc->used_size += size;
}
else if (size > free_chunk_size2) {
@@ -253,6 +268,7 @@ jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
fm->offset = fmc->tail->offset + fmc->tail->size;
fm->size = free_chunk_size1;
fm->nodes = 0;
+ fmc->free_size -= fm->size;
fmc->dirty_size += fm->size; /* Changed by simonk. This seemingly fixes a
bug that caused infinite garbage collection.
It previously set fmc->dirty_size to size (which is the
@@ -380,10 +396,12 @@ jffs_fmalloced(struct jffs_fmcontrol *fmc, __u32 offset, __u32 size,
fm->nodes->node = node;
fm->nodes->next = 0;
fmc->used_size += size;
+ fmc->free_size -= size;
}
else {
/* If there is no node, then this is just a chunk of dirt. */
fmc->dirty_size += size;
+ fmc->free_size -= size;
}
if (fmc->head_extra) {
@@ -505,6 +523,7 @@ jffs_sync_erase(struct jffs_fmcontrol *fmc, int erased_size)
});
fmc->dirty_size -= erased_size;
+ fmc->free_size += erased_size;
for (fm = fmc->head; fm && (erased_size > 0);) {
if (erased_size >= fm->size) {
@@ -701,6 +720,7 @@ jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
D(printk(" %u, /* flash_size */\n", fmc->flash_size));
D(printk(" %u, /* used_size */\n", fmc->used_size));
D(printk(" %u, /* dirty_size */\n", fmc->dirty_size));
+ D(printk(" %u, /* free_size */\n", fmc->free_size));
D(printk(" %u, /* sector_size */\n", fmc->sector_size));
D(printk(" %u, /* min_free_size */\n", fmc->min_free_size));
D(printk(" %u, /* max_chunk_size */\n", fmc->max_chunk_size));