incubator-nuttx/fs/nxffs/nxffs_block.c

158 lines
4.7 KiB
C

/****************************************************************************
* fs/nxffs/nxffs_block.c
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/mtd/mtd.h>
#include "nxffs.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxffs_verifyblock
*
* Description:
* Assure that the provided (logical) block number is in the block cache
* 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.
*
* Returned Value:
* 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.
*
****************************************************************************/
int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block)
{
FAR struct nxffs_block_s *blkhdr;
int ret;
/* Make sure that the block is in the cache */
ret = nxffs_rdcache(volume, block);
if (ret < 0)
{
/* Perhaps we are at the end of the media */
ferr("ERROR: Failed to read data into cache: %d\n", ret);
return -EIO;
}
/* 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
* for deletion)
*/
blkhdr = (FAR struct nxffs_block_s *)volume->cache;
if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) == 0)
{
/* This does appear to be a block */
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;
}
}
/* Whatever is here where a block header should be is invalid */
return -EINVAL;
}
/****************************************************************************
* 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 */
for (i = *block; i < volume->nblocks; i++)
{
/* 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;
}
}
/* ENOSPC is special return value that means that there is no further,
* valid blocks left in the volume.
*/
ferr("ERROR: No valid block found\n");
return -ENOSPC;
}