patch-2.4.11-dontuse linux/fs/jffs/jffs_fm.c
Next file: linux/fs/jffs/jffs_fm.h
Previous file: linux/fs/jffs/intrep.h
Back to the patch index
Back to the overall index
- Lines: 300
- Date:
Thu Oct 4 15:13:18 2001
- Orig file:
v2.4.10/linux/fs/jffs/jffs_fm.c
- Orig date:
Sun Sep 23 11:41:00 2001
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/jffs_fm.c linux/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.18 2000/08/21 10:41:45 dwmw2 Exp $
+ * $Id: jffs_fm.c,v 1.27 2001/09/20 12:29:47 dwmw2 Exp $
*
* Ported to Linux 2.3.x and MTD:
* Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -26,6 +26,8 @@
static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset);
#endif
+extern kmem_cache_t *fm_cache;
+extern kmem_cache_t *node_cache;
/* This function creates a new shiny flash memory control structure. */
struct jffs_fmcontrol *
@@ -46,16 +48,14 @@
mtd = get_mtd_device(NULL, MINOR(dev));
- if (!mtd)
- {
+ if (!mtd) {
kfree(fmc);
+ DJM(no_jffs_fmcontrol--);
return NULL;
}
/* Retrieve the size of the flash memory. */
- fmc->flash_start = 0;
fmc->flash_size = mtd->size;
- D3(printk(" fmc->flash_start = 0x%08x\n", fmc->flash_start));
D3(printk(" fmc->flash_size = %d bytes\n", fmc->flash_size));
fmc->used_size = 0;
@@ -71,8 +71,11 @@
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.
+ + another 2 sectors because people keep getting GC stuck and
+ we don't know why. This scares me - I want formal proof
+ of correctness of whatever number we put here. dwmw2.
*/
- fmc->min_free_size = fmc->sector_size << 1;
+ fmc->min_free_size = fmc->sector_size << 2;
fmc->mtd = mtd;
fmc->c = c;
fmc->head = 0;
@@ -117,8 +120,7 @@
while ((cur = next)) {
next = next->next;
- kfree(cur);
- DJM(no_jffs_fm--);
+ jffs_free_fm(cur);
}
put_mtd_device(fmc->mtd);
kfree(fmc);
@@ -135,7 +137,7 @@
{
__u32 head;
__u32 tail;
- __u32 end = fmc->flash_start + fmc->flash_size;
+ __u32 end = fmc->flash_size;
if (!fmc->head) {
/* There is nothing on the flash. */
@@ -146,11 +148,11 @@
head = fmc->head->offset;
tail = fmc->tail->offset + fmc->tail->size;
if (tail == end) {
- tail = fmc->flash_start;
+ tail = 0;
}
ASSERT(else if (tail > end) {
printk(KERN_WARNING "jffs_free_size1(): tail > end\n");
- tail = fmc->flash_start;
+ tail = 0;
});
if (head <= tail) {
@@ -178,12 +180,12 @@
if (fmc->head) {
__u32 head = fmc->head->offset;
__u32 tail = fmc->tail->offset + fmc->tail->size;
- if (tail == fmc->flash_start + fmc->flash_size) {
- tail = fmc->flash_start;
+ if (tail == fmc->flash_size) {
+ tail = 0;
}
if (tail >= head) {
- return head - fmc->flash_start;
+ return head;
}
}
return 0;
@@ -206,12 +208,10 @@
*result = 0;
- if (!(fm = (struct jffs_fm*)kmalloc(sizeof(struct jffs_fm),
- GFP_KERNEL))) {
+ if (!(fm = jffs_alloc_fm())) {
D(printk("jffs_fmalloc(): kmalloc() failed! (fm)\n"));
return -ENOMEM;
}
- DJM(no_jffs_fm++);
free_chunk_size1 = jffs_free_size1(fmc);
free_chunk_size2 = jffs_free_size2(fmc);
@@ -230,8 +230,7 @@
GFP_KERNEL))) {
D(printk("jffs_fmalloc(): kmalloc() failed! "
"(node_ref)\n"));
- kfree(fm);
- DJM(no_jffs_fm--);
+ jffs_free_fm(fm);
return -ENOMEM;
}
DJM(no_jffs_node_ref++);
@@ -239,22 +238,19 @@
fm->nodes->next = 0;
if (fmc->tail) {
fm->offset = fmc->tail->offset + fmc->tail->size;
- if (fm->offset
- == fmc->flash_start + fmc->flash_size) {
- fm->offset = fmc->flash_start;
+ if (fm->offset == fmc->flash_size) {
+ fm->offset = 0;
}
- ASSERT(else if (fm->offset
- > fmc->flash_start
- + fmc->flash_size) {
+ ASSERT(else if (fm->offset > fmc->flash_size) {
printk(KERN_WARNING "jffs_fmalloc(): "
"offset > flash_end\n");
- fm->offset = fmc->flash_start;
+ fm->offset = 0;
});
}
else {
/* There don't have to be files in the file
system yet. */
- fm->offset = fmc->flash_start;
+ fm->offset = 0;
}
fm->size = size;
fmc->free_size -= size;
@@ -263,8 +259,7 @@
else if (size > free_chunk_size2) {
printk(KERN_WARNING "JFFS: Tried to allocate a too "
"large flash memory chunk. (size = %u)\n", size);
- kfree(fm);
- DJM(no_jffs_fm--);
+ jffs_free_fm(fm);
return -ENOSPC;
}
else {
@@ -350,7 +345,6 @@
return -1;
}
#endif
- fmc->c->sb->s_dirt = 1;
}
ASSERT(if (!del) {
@@ -372,13 +366,11 @@
D3(printk("jffs_fmalloced()\n"));
- if (!(fm = (struct jffs_fm *)kmalloc(sizeof(struct jffs_fm),
- GFP_KERNEL))) {
+ if (!(fm = jffs_alloc_fm())) {
D(printk("jffs_fmalloced(0x%p, %u, %u, 0x%p): failed!\n",
fmc, offset, size, node));
return 0;
}
- DJM(no_jffs_fm++);
fm->offset = offset;
fm->size = size;
fm->prev = 0;
@@ -391,8 +383,7 @@
kmalloc(sizeof(struct jffs_node_ref),
GFP_KERNEL))) {
D(printk("jffs_fmalloced(): !fm->nodes\n"));
- kfree(fm);
- DJM(no_jffs_fm--);
+ jffs_free_fm(fm);
return 0;
}
DJM(no_jffs_node_ref++);
@@ -469,6 +460,7 @@
fmc->used_size -= fm->size;
if (fm == fmc->tail) {
fm->size -= size;
+ fmc->free_size += size;
}
fmc->dirty_size += fm->size;
}
@@ -535,8 +527,7 @@
fm = fm->next;
fm->prev = 0;
fmc->head = fm;
- kfree(del);
- DJM(no_jffs_fm--);
+ jffs_free_fm(del);
}
else {
fm->size -= erased_size;
@@ -664,7 +655,7 @@
/* Calculate how much space that is dirty. */
for (fm = fmc->head; fm && !fm->nodes; fm = fm->next) {
- if (size && fm->offset == fmc->flash_start) {
+ if (size && fm->offset == 0) {
/* We have reached the beginning of the flash. */
break;
}
@@ -674,14 +665,13 @@
/* Someone's signature contained this:
There's a fine line between fishing and just standing on
the shore like an idiot... */
- ret = jffs_flash_erasable_size(fmc->mtd,
- fmc->head->offset - fmc->flash_start, size);
+ ret = jffs_flash_erasable_size(fmc->mtd, fmc->head->offset, size);
ASSERT(if (ret < 0) {
printk("jffs_erasable_size: flash_erasable_size() "
"returned something less than zero (%ld).\n", ret);
printk("jffs_erasable_size: offset = 0x%08x\n",
- fmc->head->offset - fmc->flash_start);
+ fmc->head->offset);
});
/* If there is dirt on the flash (which is the reason to why
@@ -705,21 +695,58 @@
if (del->next) {
del->next->prev = head;
}
- kfree(del);
- DJM(no_jffs_fm--);
+ jffs_free_fm(del);
}
}
return (ret >= 0 ? ret : 0);
}
+struct jffs_fm *jffs_alloc_fm(void)
+{
+ struct jffs_fm *fm;
+
+ fm = kmem_cache_alloc(fm_cache,GFP_KERNEL);
+ DJM(if (fm) no_jffs_fm++;);
+
+ return fm;
+}
+
+void jffs_free_fm(struct jffs_fm *n)
+{
+ kmem_cache_free(fm_cache,n);
+ DJM(no_jffs_fm--);
+}
+
+
+
+struct jffs_node *jffs_alloc_node(void)
+{
+ struct jffs_node *n;
+
+ n = (struct jffs_node *)kmem_cache_alloc(node_cache,GFP_KERNEL);
+ if(n != NULL)
+ no_jffs_node++;
+ return n;
+}
+
+void jffs_free_node(struct jffs_node *n)
+{
+ kmem_cache_free(node_cache,n);
+ no_jffs_node--;
+}
+
+
+int jffs_get_node_inuse(void)
+{
+ return no_jffs_node;
+}
void
jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
{
D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
D(printk("{\n"));
- D(printk(" 0x%08x, /* flash_start */\n", fmc->flash_start));
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));
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)