diff options
Diffstat (limited to 'linux-2.4.x/drivers/mtd/nftlmount.c')
-rw-r--r-- | linux-2.4.x/drivers/mtd/nftlmount.c | 263 |
1 files changed, 144 insertions, 119 deletions
diff --git a/linux-2.4.x/drivers/mtd/nftlmount.c b/linux-2.4.x/drivers/mtd/nftlmount.c index 56b42a5..3b104eb 100644 --- a/linux-2.4.x/drivers/mtd/nftlmount.c +++ b/linux-2.4.x/drivers/mtd/nftlmount.c @@ -1,10 +1,10 @@ -/* +/* * NFTL mount code with extensive checks * - * Author: Fabrice Bellard (fabrice.bellard@netgem.com) + * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * - * $Id: nftlmount.c,v 1.25 2001/11/30 16:46:27 dwmw2 Exp $ + * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,25 +21,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define __NO_VERSION__ #include <linux/kernel.h> -#include <linux/module.h> #include <asm/errno.h> -#include <asm/io.h> -#include <asm/uaccess.h> -#include <linux/miscdevice.h> -#include <linux/pci.h> #include <linux/delay.h> #include <linux/slab.h> -#include <linux/sched.h> -#include <linux/init.h> #include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> #include <linux/mtd/nftl.h> -#include <linux/mtd/compatmac.h> #define SECTORSIZE 512 -char nftlmountrev[]="$Revision: 1.25 $"; +char nftlmountrev[]="$Revision: 1.41 $"; /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the * various device information of the NFTL partition and Bad Unit Table. Update @@ -49,13 +41,21 @@ char nftlmountrev[]="$Revision: 1.25 $"; static int find_boot_record(struct NFTLrecord *nftl) { struct nftl_uci1 h1; - struct nftl_oob oob; unsigned int block, boot_record_count = 0; - int retlen; + size_t retlen; u8 buf[SECTORSIZE]; struct NFTLMediaHeader *mh = &nftl->MediaHdr; unsigned int i; + /* Assume logical EraseSize == physical erasesize for starting the scan. + We'll sort it out later if we find a MediaHeader which says otherwise */ + /* Actually, we won't. The new DiskOnChip driver has already scanned + the MediaHeader and adjusted the virtual erasesize it presents in + the mtd device accordingly. We could even get rid of + nftl->EraseSize if there were any point in doing so. */ + nftl->EraseSize = nftl->mbd.mtd->erasesize; + nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize; + nftl->MediaUnit = BLOCK_NIL; nftl->SpareMediaUnit = BLOCK_NIL; @@ -65,12 +65,15 @@ static int find_boot_record(struct NFTLrecord *nftl) /* Check for ANAND header first. Then can whinge if it's found but later checks fail */ - if ((ret = MTD_READ(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) { + ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf); + /* We ignore ret in case the ECC of the MediaHeader is invalid + (which is apparently acceptable) */ + if (retlen != SECTORSIZE) { static int warncount = 5; if (warncount) { printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n", - block * nftl->EraseSize, nftl->mtd->index, ret); + block * nftl->EraseSize, nftl->mbd.mtd->index, ret); if (!--warncount) printk(KERN_WARNING "Further failures for this block will not be printed\n"); } @@ -80,17 +83,17 @@ static int find_boot_record(struct NFTLrecord *nftl) if (retlen < 6 || memcmp(buf, "ANAND", 6)) { /* ANAND\0 not found. Continue */ #if 0 - printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", - block * nftl->EraseSize, nftl->mtd->index); -#endif + printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", + block * nftl->EraseSize, nftl->mbd.mtd->index); +#endif continue; } /* To be safer with BIOS, also use erase mark as discriminant */ - if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, + if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0)) { printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n", - block * nftl->EraseSize, nftl->mtd->index, ret); + block * nftl->EraseSize, nftl->mbd.mtd->index, ret); continue; } @@ -100,29 +103,28 @@ static int find_boot_record(struct NFTLrecord *nftl) */ if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) { printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n", - block * nftl->EraseSize, nftl->mtd->index, + block * nftl->EraseSize, nftl->mbd.mtd->index, le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1)); continue; } /* Finally reread to check ECC */ - if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, - &retlen, buf, (char *)&oob) < 0)) { + if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, + &retlen, buf, (char *)&oob, NULL) < 0)) { printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n", - block * nftl->EraseSize, nftl->mtd->index, ret); + block * nftl->EraseSize, nftl->mbd.mtd->index, ret); continue; } /* Paranoia. Check the ANAND header is still there after the ECC read */ if (memcmp(buf, "ANAND", 6)) { printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n", - block * nftl->EraseSize, nftl->mtd->index); + block * nftl->EraseSize, nftl->mbd.mtd->index); printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); continue; } #endif - /* OK, we like it. */ if (boot_record_count) { @@ -132,11 +134,19 @@ static int find_boot_record(struct NFTLrecord *nftl) printk(KERN_NOTICE "NFTL Media Headers at 0x%x and 0x%x disagree.\n", nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize); /* if (debug) Print both side by side */ - return -1; + if (boot_record_count < 2) { + /* We haven't yet seen two real ones */ + return -1; + } + continue; } if (boot_record_count == 1) nftl->SpareMediaUnit = block; + /* Mark this boot record (NFTL MediaHeader) block as reserved */ + nftl->ReplUnitTable[block] = BLOCK_RESERVED; + + boot_record_count++; continue; } @@ -145,16 +155,27 @@ static int find_boot_record(struct NFTLrecord *nftl) memcpy(mh, buf, sizeof(struct NFTLMediaHeader)); /* Do some sanity checks on it */ - if (mh->UnitSizeFactor != 0xff) { - printk(KERN_NOTICE "Sorry, we don't support UnitSizeFactor " - "of != 1 yet.\n"); +#if 0 +The new DiskOnChip driver scans the MediaHeader itself, and presents a virtual +erasesize based on UnitSizeFactor. So the erasesize we read from the mtd +device is already correct. + if (mh->UnitSizeFactor == 0) { + printk(KERN_NOTICE "NFTL: UnitSizeFactor 0x00 detected. This violates the spec but we think we know what it means...\n"); + } else if (mh->UnitSizeFactor < 0xfc) { + printk(KERN_NOTICE "Sorry, we don't support UnitSizeFactor 0x%02x\n", + mh->UnitSizeFactor); return -1; + } else if (mh->UnitSizeFactor != 0xff) { + printk(KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n", + mh->UnitSizeFactor); + nftl->EraseSize = nftl->mbd.mtd->erasesize << (0xff - mh->UnitSizeFactor); + nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize; } - +#endif nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN); if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) { printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n"); - printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", + printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", nftl->nb_boot_blocks, nftl->nb_blocks); return -1; } @@ -166,35 +187,70 @@ static int find_boot_record(struct NFTLrecord *nftl) nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks); return -1; } - - nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); - + + nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); + /* If we're not using the last sectors in the device for some reason, reduce nb_blocks accordingly so we forget they're there */ nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN); + /* XXX: will be suppressed */ + nftl->lastEUN = nftl->nb_blocks - 1; + + /* memory alloc */ + nftl->EUNtable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL); + if (!nftl->EUNtable) { + printk(KERN_NOTICE "NFTL: allocation of EUNtable failed\n"); + return -ENOMEM; + } + + nftl->ReplUnitTable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL); + if (!nftl->ReplUnitTable) { + kfree(nftl->EUNtable); + printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n"); + return -ENOMEM; + } + + /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */ + for (i = 0; i < nftl->nb_boot_blocks; i++) + nftl->ReplUnitTable[i] = BLOCK_RESERVED; + /* mark all remaining blocks as potentially containing data */ + for (; i < nftl->nb_blocks; i++) { + nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED; + } + + /* Mark this boot record (NFTL MediaHeader) block as reserved */ + nftl->ReplUnitTable[block] = BLOCK_RESERVED; + /* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */ for (i = 0; i < nftl->nb_blocks; i++) { +#if 0 +The new DiskOnChip driver already scanned the bad block table. Just query it. if ((i & (SECTORSIZE - 1)) == 0) { /* read one sector for every SECTORSIZE of blocks */ - if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize + - i + SECTORSIZE, SECTORSIZE, - &retlen, buf, (char *)&oob)) < 0) { + if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize + + i + SECTORSIZE, SECTORSIZE, &retlen, buf, + (char *)&oob, NULL)) < 0) { printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n", ret); + kfree(nftl->ReplUnitTable); + kfree(nftl->EUNtable); return -1; } } /* mark the Bad Erase Unit as RESERVED in ReplUnitTable */ if (buf[i & (SECTORSIZE - 1)] != 0xff) nftl->ReplUnitTable[i] = BLOCK_RESERVED; +#endif + if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize)) + nftl->ReplUnitTable[i] = BLOCK_RESERVED; } - + nftl->MediaUnit = block; boot_record_count++; - + } /* foreach (block) */ - + return boot_record_count?0:-1; } @@ -209,25 +265,21 @@ static int memcmpb(void *a, int c, int n) } /* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */ -static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, +static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, int check_oob) { - int i, retlen; - u8 buf[SECTORSIZE]; + int i; + size_t retlen; + u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize]; for (i = 0; i < len; i += SECTORSIZE) { - /* we want to read the sector without ECC check here since a free - sector does not have ECC syndrome on it yet */ - if (MTD_READ(nftl->mtd, address, SECTORSIZE, &retlen, buf) < 0) + if (MTD_READECC(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &nftl->oobinfo) < 0) return -1; if (memcmpb(buf, 0xff, SECTORSIZE) != 0) return -1; if (check_oob) { - if (MTD_READOOB(nftl->mtd, address, nftl->mtd->oobsize, - &retlen, buf) < 0) - return -1; - if (memcmpb(buf, 0xff, nftl->mtd->oobsize) != 0) + if (memcmpb(buf + SECTORSIZE, 0xff, nftl->mbd.mtd->oobsize) != 0) return -1; } address += SECTORSIZE; @@ -241,18 +293,17 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int * * Return: 0 when succeed, -1 on error. * - * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? - * 2. UnitSizeFactor != 0xFF + * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? */ int NFTL_formatblock(struct NFTLrecord *nftl, int block) { - int retlen; + size_t retlen; unsigned int nb_erases, erase_mark; struct nftl_uci1 uci; struct erase_info *instr = &nftl->instr; /* Read the Unit Control Information #1 for Wear-Leveling */ - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&uci) < 0) goto default_uci1; @@ -267,16 +318,16 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block) memset(instr, 0, sizeof(struct erase_info)); /* XXX: use async erase interface, XXX: test return code */ + instr->mtd = nftl->mbd.mtd; instr->addr = block * nftl->EraseSize; instr->len = nftl->EraseSize; - MTD_ERASE(nftl->mtd, instr); + MTD_ERASE(nftl->mbd.mtd, instr); if (instr->state == MTD_ERASE_FAILED) { - /* could not format, FixMe: We should update the BadUnitTable - both in memory and on disk */ printk("Error while formatting block %d\n", block); - return -1; - } else { + goto fail; + } + /* increase and write Wear-Leveling info */ nb_erases = le32_to_cpu(uci.WearInfo); nb_erases++; @@ -289,14 +340,18 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block) * FixMe: is this check really necessary ? since we have check the * return code after the erase operation. */ if (check_free_sectors(nftl, instr->addr, nftl->EraseSize, 1) != 0) - return -1; + goto fail; uci.WearInfo = le32_to_cpu(nb_erases); - if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&uci) < 0) - return -1; + goto fail; return 0; - } +fail: + /* could not format, update the bad block table (caller is responsible + for setting the ReplUnitTable to BLOCK_RESERVED on failure) */ + nftl->mbd.mtd->block_markbad(nftl->mbd.mtd, instr->addr); + return -1; } /* check_sectors_in_chain: Check that each sector of a Virtual Unit Chain is correct. @@ -312,13 +367,14 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b { unsigned int block, i, status; struct nftl_bci bci; - int sectors_per_block, retlen; + int sectors_per_block; + size_t retlen; sectors_per_block = nftl->EraseSize / SECTORSIZE; block = first_block; for (;;) { for (i = 0; i < sectors_per_block; i++) { - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i * SECTORSIZE, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE, 8, &retlen, (char *)&bci) < 0) status = SECTOR_IGNORE; else @@ -329,7 +385,7 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b /* verify that the sector is really free. If not, mark as ignore */ if (memcmpb(&bci, 0xff, 8) != 0 || - check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE, + check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE, SECTORSIZE, 0) != 0) { printk("Incorrect free sector %d in block %d: " "marking it as ignored\n", @@ -338,7 +394,7 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b /* sector not free actually : mark it as SECTOR_IGNORE */ bci.Status = SECTOR_IGNORE; bci.Status1 = SECTOR_IGNORE; - MTD_WRITEOOB(nftl->mtd, + MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE, 8, &retlen, (char *)&bci); } @@ -401,8 +457,7 @@ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block) printk("Formatting block %d\n", block); if (NFTL_formatblock(nftl, block) < 0) { - /* cannot format !!!! Mark it as Bad Unit, - FixMe: update the BadUnitTable on disk */ + /* cannot format !!!! Mark it as Bad Unit */ nftl->ReplUnitTable[block] = BLOCK_RESERVED; } else { nftl->ReplUnitTable[block] = BLOCK_FREE; @@ -428,10 +483,10 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) { struct nftl_uci1 h1; unsigned int erase_mark; - int retlen; + size_t retlen; /* check erase mark. */ - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) return -1; @@ -446,7 +501,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) h1.EraseMark = cpu_to_le16(ERASE_MARK); h1.EraseMark1 = cpu_to_le16(ERASE_MARK); h1.WearInfo = cpu_to_le32(0); - if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) return -1; } else { @@ -458,7 +513,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) SECTORSIZE, 0) != 0) return -1; - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i, 16, &retlen, buf) < 0) return -1; if (i == SECTORSIZE) { @@ -486,9 +541,9 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block) { struct nftl_uci2 uci; - int retlen; + size_t retlen; - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, 8, &retlen, (char *)&uci) < 0) return 0; @@ -503,44 +558,14 @@ int NFTL_mount(struct NFTLrecord *s) int chain_length, do_format_chain; struct nftl_uci0 h0; struct nftl_uci1 h1; - int retlen; - - /* XXX: will be suppressed */ - s->lastEUN = s->nb_blocks - 1; - - /* memory alloc */ - s->EUNtable = kmalloc(s->nb_blocks * sizeof(u16), GFP_KERNEL); - s->ReplUnitTable = kmalloc(s->nb_blocks * sizeof(u16), GFP_KERNEL); - if (!s->EUNtable || !s->ReplUnitTable) { - fail: - if (s->EUNtable) - kfree(s->EUNtable); - if (s->ReplUnitTable) - kfree(s->ReplUnitTable); - return -1; - } - - /* mark all blocks as potentially containing data */ - for (i = 0; i < s->nb_blocks; i++) { - s->ReplUnitTable[i] = BLOCK_NOTEXPLORED; - } + size_t retlen; /* search for NFTL MediaHeader and Spare NFTL Media Header */ if (find_boot_record(s) < 0) { printk("Could not find valid boot record\n"); - goto fail; + return -1; } - /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */ - for (i = 0; i < s->nb_boot_blocks; i++) - s->ReplUnitTable[i] = BLOCK_RESERVED; - - /* also mark the boot records (NFTL MediaHeader) blocks as reserved */ - if (s->MediaUnit != BLOCK_NIL) - s->ReplUnitTable[s->MediaUnit] = BLOCK_RESERVED; - if (s->SpareMediaUnit != BLOCK_NIL) - s->ReplUnitTable[s->SpareMediaUnit] = BLOCK_RESERVED; - /* init the logical to physical table */ for (i = 0; i < s->nb_blocks; i++) { s->EUNtable[i] = BLOCK_NIL; @@ -557,9 +582,9 @@ int NFTL_mount(struct NFTLrecord *s) for (;;) { /* read the block header. If error, we format the chain */ - if (MTD_READOOB(s->mtd, block * s->EraseSize + 8, 8, + if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, &retlen, (char *)&h0) < 0 || - MTD_READOOB(s->mtd, block * s->EraseSize + SECTORSIZE + 8, 8, + MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) { s->ReplUnitTable[block] = BLOCK_NIL; do_format_chain = 1; @@ -614,7 +639,7 @@ int NFTL_mount(struct NFTLrecord *s) first_logical_block = logical_block; } else { if (logical_block != first_logical_block) { - printk("Block %d: incorrect logical block: %d expected: %d\n", + printk("Block %d: incorrect logical block: %d expected: %d\n", block, logical_block, first_logical_block); /* the chain is incorrect : we must format it, but we need to read it completly */ @@ -643,7 +668,7 @@ int NFTL_mount(struct NFTLrecord *s) s->ReplUnitTable[block] = BLOCK_NIL; break; } else if (rep_block >= s->nb_blocks) { - printk("Block %d: referencing invalid block %d\n", + printk("Block %d: referencing invalid block %d\n", block, rep_block); do_format_chain = 1; s->ReplUnitTable[block] = BLOCK_NIL; @@ -663,7 +688,7 @@ int NFTL_mount(struct NFTLrecord *s) s->ReplUnitTable[block] = rep_block; s->EUNtable[first_logical_block] = BLOCK_NIL; } else { - printk("Block %d: referencing block %d already in another chain\n", + printk("Block %d: referencing block %d already in another chain\n", block, rep_block); /* XXX: should handle correctly fold in progress chains */ do_format_chain = 1; @@ -685,7 +710,7 @@ int NFTL_mount(struct NFTLrecord *s) } else { unsigned int first_block1, chain_to_format, chain_length1; int fold_mark; - + /* valid chain : get foldmark */ fold_mark = get_fold_mark(s, first_block); if (fold_mark == 0) { @@ -704,9 +729,9 @@ int NFTL_mount(struct NFTLrecord *s) if (first_block1 != BLOCK_NIL) { /* XXX: what to do if same length ? */ chain_length1 = calc_chain_length(s, first_block1); - printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n", + printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n", first_block1, chain_length1, first_block, chain_length); - + if (chain_length >= chain_length1) { chain_to_format = first_block1; s->EUNtable[first_logical_block] = first_block; @@ -725,7 +750,7 @@ int NFTL_mount(struct NFTLrecord *s) /* second pass to format unreferenced blocks and init free block count */ s->numfreeEUNs = 0; - s->LastFreeEUN = BLOCK_NIL; + s->LastFreeEUN = le16_to_cpu(s->MediaHdr.FirstPhysicalEUN); for (block = 0; block < s->nb_blocks; block++) { if (s->ReplUnitTable[block] == BLOCK_NOTEXPLORED) { |