--- zzzz-none-000/linux-2.4.17/fs/jffs/jffs_fm.c 2001-10-04 22:13:18.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/fs/jffs/jffs_fm.c 2004-11-24 13:22:16.000000000 +0000 @@ -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.27 2001/09/20 12:29:47 dwmw2 Exp $ + * $Id: jffs_fm.c,v 1.1.1.1 2003/06/23 22:18:37 jharrell Exp $ * * Ported to Linux 2.3.x and MTD: * Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB @@ -89,8 +89,8 @@ /* When the flash memory scan has completed, this function should be called before use of the control structure. */ -void -jffs_build_end(struct jffs_fmcontrol *fmc) +int +jffs_build_end(struct jffs_fmcontrol *fmc, __u32 head_offset) { D3(printk("jffs_build_end()\n")); @@ -99,13 +99,100 @@ fmc->tail = fmc->tail_extra; } else if (fmc->head_extra) { - fmc->tail_extra->next = fmc->head; - fmc->head->prev = fmc->tail_extra; - fmc->head = fmc->head_extra; + struct jffs_fm *fm, *cur; + + if (head_offset == fmc->head->offset){ + fmc->tail->next = fmc->head_extra; + fmc->head_extra->prev = fmc->tail; + fmc->tail = fmc->tail_extra; + } + else { + fmc->tail_extra->next = fmc->head; + fmc->head->prev = fmc->tail_extra; + fmc->head = fmc->head_extra; + while (fmc->head->offset != head_offset){ + fmc->tail->next = fmc->head; + fmc->head = fmc->head->next; + fmc->head->prev = 0; + fmc->tail->next->prev = fmc->tail; + fmc->tail = fmc->tail->next; + fmc->tail->next = 0; + } + } + /* Make sure the only free space we have is between tail and head. + */ + for (cur = fmc->head; cur && cur != fmc->tail;) { + if (cur->offset + cur->size < cur->next->offset) { + if (!(fm = kmalloc(sizeof(struct jffs_fm), GFP_KERNEL))) { + D(printk("jffs_buid_end(): kmalloc failed!\n")); + return -ENOMEM; + } + DJM(no_jffs_fm++); + fm->size = cur->next->offset - cur->offset - cur->size; + fm->offset = cur->offset + cur->size; + fm->nodes = 0; + fm->next = cur->next; + fm->prev = cur; + cur->next->prev = fm; + cur->next = fm; + cur = fm->next; + fmc->free_size -= fm->size; + fmc->dirty_size += fm->size; + } + else if (cur->offset > cur->next->offset) { + if (cur->offset + cur->size < fmc->flash_size){ + if (!(fm = kmalloc(sizeof(struct jffs_fm), GFP_KERNEL))){ + + D(printk("jffs_buid_end(): kmalloc failed!\n")); + return -ENOMEM; + } + DJM(no_jffs_fm++); + fm->size = fmc->flash_size - + cur->offset - cur->size; + fm->nodes = 0; + fm->offset = cur->offset + cur->size; + fm->next = cur->next; + fm->prev = cur; + cur->next->prev = fm; + cur->next = fm; + cur = fm->next; + fmc->free_size -= fm->size; + fmc->dirty_size += fm->size; + } + else { + cur = cur->next; + } + if (cur->offset > 0) { + + if (!(fm = kmalloc(sizeof(struct jffs_fm), GFP_KERNEL))) { + D(printk("jffs_buid_end(): kmalloc failed!\n")); + return -ENOMEM; + } + DJM(no_jffs_fm++); + fm->size = cur->offset; + fm->nodes = 0; + fm->offset = 0; + fm->next = cur; + fm->prev = cur->prev; + cur->prev->next = fm; + cur->prev = fm; + fmc->free_size -= fm->size; + fmc->dirty_size += fm->size; + } + } + else if (cur->offset + cur->size != cur->next->offset) { + printk("jffs_build_end(): Internal error.\n"); + return -EINVAL; + } + else { + cur = cur->next; + } + } } fmc->head_extra = 0; /* These two instructions should be omitted. */ fmc->tail_extra = 0; D3(jffs_print_fmcontrol(fmc)); + return 0; }