2011-04-28 21:26:46 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* fs/nxffs/nxffs_block.c
|
|
|
|
*
|
2021-02-03 14:47:23 +01:00
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
|
|
* this work for additional information regarding copyright ownership. The
|
|
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
2011-04-28 21:26:46 +02:00
|
|
|
*
|
2021-02-03 14:47:23 +01:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2011-04-28 21:26:46 +02:00
|
|
|
*
|
2021-02-03 14:47:23 +01:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
2011-04-28 21:26:46 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <debug.h>
|
|
|
|
|
2013-11-15 18:22:23 +01:00
|
|
|
#include <nuttx/mtd/mtd.h>
|
2011-04-28 21:26:46 +02:00
|
|
|
|
|
|
|
#include "nxffs.h"
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Public Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: nxffs_verifyblock
|
|
|
|
*
|
|
|
|
* Description:
|
2013-08-27 17:40:19 +02:00
|
|
|
* Assure that the provided (logical) block number is in the block cache
|
2011-04-28 21:26:46 +02:00
|
|
|
* and that it has a valid block header (i.e., proper magic and
|
|
|
|
* marked good)
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* volume - Describes the NXFFS volume
|
|
|
|
* block - The (logical) block number to load and verify.
|
|
|
|
*
|
2018-02-01 17:00:02 +01:00
|
|
|
* Returned Value:
|
2013-12-03 00:19:22 +01:00
|
|
|
* OK (zero( is returned on success. Otherwise, a negated errno value is
|
|
|
|
* returned indicating the nature of the failure:
|
|
|
|
*
|
|
|
|
* -EIO is returned if we failed to read the block. If we are using
|
|
|
|
* NAND memory, then this probably means that the block has
|
|
|
|
* uncorrectable bit errors.
|
|
|
|
* -ENOENT is returned if the block is a bad block.
|
2011-04-28 21:26:46 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block)
|
|
|
|
{
|
|
|
|
FAR struct nxffs_block_s *blkhdr;
|
|
|
|
int ret;
|
|
|
|
|
2013-08-27 17:40:19 +02:00
|
|
|
/* Make sure that the block is in the cache */
|
2011-04-28 21:26:46 +02:00
|
|
|
|
2011-05-03 15:46:14 +02:00
|
|
|
ret = nxffs_rdcache(volume, block);
|
2011-04-28 21:26:46 +02:00
|
|
|
if (ret < 0)
|
|
|
|
{
|
2011-05-04 23:59:23 +02:00
|
|
|
/* Perhaps we are at the end of the media */
|
|
|
|
|
2016-06-11 23:50:49 +02:00
|
|
|
ferr("ERROR: Failed to read data into cache: %d\n", ret);
|
2013-12-03 00:19:22 +01:00
|
|
|
return -EIO;
|
2011-04-28 21:26:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the block has a magic number (meaning that it is not
|
|
|
|
* erased) and that it is valid (meaning that it is not marked
|
2011-04-30 19:29:40 +02:00
|
|
|
* for deletion)
|
2011-04-28 21:26:46 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
blkhdr = (FAR struct nxffs_block_s *)volume->cache;
|
2011-05-04 23:59:23 +02:00
|
|
|
if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) == 0)
|
2011-04-28 21:26:46 +02:00
|
|
|
{
|
2019-10-27 18:48:14 +01:00
|
|
|
/* This does appear to be a block */
|
2011-05-04 23:59:23 +02:00
|
|
|
|
|
|
|
if (blkhdr->state == BLOCK_STATE_GOOD)
|
|
|
|
{
|
|
|
|
/* The block is valid */
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
else if (blkhdr->state == BLOCK_STATE_BAD)
|
|
|
|
{
|
|
|
|
/* -ENOENT is a special indication that this is a properly marked
|
|
|
|
* bad block
|
|
|
|
*/
|
|
|
|
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
2011-04-28 21:26:46 +02:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:59:23 +02:00
|
|
|
/* Whatever is here where a block header should be is invalid */
|
|
|
|
|
|
|
|
return -EINVAL;
|
2011-04-28 21:26:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: nxffs_validblock
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Find the next valid (logical) block in the volume.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* volume - Describes the NXFFS volume
|
|
|
|
* block - On entry, this provides the starting block number. If the
|
|
|
|
* function is succesfful, then this memory location will hold the
|
|
|
|
* block number of the next valid block on return.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Zero on success otherwise a negated errno value indicating the nature
|
|
|
|
* of the failure.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
int nxffs_validblock(struct nxffs_volume_s *volume, off_t *block)
|
|
|
|
{
|
|
|
|
off_t i;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
DEBUGASSERT(volume && block);
|
|
|
|
|
|
|
|
/* Loop for each possible block or until a valid block is found */
|
|
|
|
|
2011-04-30 19:29:40 +02:00
|
|
|
for (i = *block; i < volume->nblocks; i++)
|
2011-04-28 21:26:46 +02:00
|
|
|
{
|
|
|
|
/* Loop until we find a valid block */
|
|
|
|
|
|
|
|
ret = nxffs_verifyblock(volume, i);
|
|
|
|
if (ret == OK)
|
|
|
|
{
|
|
|
|
/* We found it, return the block number */
|
|
|
|
|
|
|
|
*block = i;
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-30 19:29:40 +02:00
|
|
|
/* ENOSPC is special return value that means that there is no further,
|
|
|
|
* valid blocks left in the volume.
|
|
|
|
*/
|
|
|
|
|
2016-06-11 23:50:49 +02:00
|
|
|
ferr("ERROR: No valid block found\n");
|
2011-04-30 19:29:40 +02:00
|
|
|
return -ENOSPC;
|
2011-04-28 21:26:46 +02:00
|
|
|
}
|