// SPDX-License-Identifier: GPL-2.0-or-later /* * NFTL mount code with extensive checks * * Author: Fabrice Bellard ([email protected]) * Copyright © 2000 Netgem S.A. * Copyright © 1999-2010 David Woodhouse <[email protected]> */ #include <linux/kernel.h> #include <asm/errno.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/mtd/nftl.h> #define SECTORSIZE … /* 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 * the ReplUnitTable[] table according to the Bad Unit Table. ReplUnitTable[] * is used for management of Erase Unit in other routines in nftl.c and nftlmount.c */ static int find_boot_record(struct NFTLrecord *nftl) { … } 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, int check_oob) { … } /* NFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase Unit and * Update NFTL metadata. Each erase operation is checked with check_free_sectors * * Return: 0 when succeed, -1 on error. * * ToDo: 1. Is it necessary to check_free_sector after erasing ?? */ int NFTL_formatblock(struct NFTLrecord *nftl, int block) { … } /* check_sectors_in_chain: Check that each sector of a Virtual Unit Chain is correct. * Mark as 'IGNORE' each incorrect sector. This check is only done if the chain * was being folded when NFTL was interrupted. * * The check_free_sectors in this function is necessary. There is a possible * situation that after writing the Data area, the Block Control Information is * not updated according (due to power failure or something) which leaves the block * in an inconsistent state. So we have to check if a block is really FREE in this * case. */ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block) { … } /* calc_chain_length: Walk through a Virtual Unit Chain and estimate chain length */ static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block) { … } /* format_chain: Format an invalid Virtual Unit chain. It frees all the Erase Units in a * Virtual Unit Chain, i.e. all the units are disconnected. * * It is not strictly correct to begin from the first block of the chain because * if we stop the code, we may see again a valid chain if there was a first_block * flag in a block inside it. But is it really a problem ? * * FixMe: Figure out what the last statement means. What if power failure when we are * in the for (;;) loop formatting blocks ?? */ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block) { … } /* check_and_mark_free_block: Verify that a block is free in the NFTL sense (valid erase mark) or * totally free (only 0xff). * * Definition: Free Erase Unit -- A properly erased/formatted Free Erase Unit should have meet the * following criteria: * 1. */ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) { … } /* get_fold_mark: Read fold mark from Unit Control Information #2, we use FOLD_MARK_IN_PROGRESS * to indicate that we are in the progression of a Virtual Unit Chain folding. If the UCI #2 * is FOLD_MARK_IN_PROGRESS when mounting the NFTL, the (previous) folding process is interrupted * for some reason. A clean up/check of the VUC is necessary in this case. * * WARNING: return 0 if read error */ static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block) { … } int NFTL_mount(struct NFTLrecord *s) { … }