More NXFFS bugfixes
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3561 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
51740b3bfa
commit
fc3bd5c968
|
@ -46,9 +46,11 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <crc32.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mtd.h>
|
||||
#include <nuttx/nxffs.h>
|
||||
|
@ -100,6 +102,22 @@
|
|||
# define CONFIG_EXAMPLES_NXFFS_MOUNTPT "/mnt/nxffs"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_NXFFS_NLOOPS
|
||||
# define CONFIG_EXAMPLES_NXFFS_NLOOPS 2
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_NXFFS_VERBOSE
|
||||
# define CONFIG_EXAMPLES_NXFFS_VERBOSE 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||
# define message lib_rawprintf
|
||||
# define msgflush()
|
||||
#else
|
||||
# define message printf
|
||||
# define msgflush() fflush(stdout);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
@ -173,7 +191,8 @@ static inline void nxffs_randname(FAR struct nxffs_filedesc_s *file)
|
|||
file->name = (FAR char*)malloc(alloclen + 1);
|
||||
if (!file->name)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to allocate name, length=%d\n", namelen);
|
||||
message("ERROR: Failed to allocate name, length=%d\n", namelen);
|
||||
msgflush();
|
||||
exit(5);
|
||||
}
|
||||
|
||||
|
@ -232,9 +251,9 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file)
|
|||
fd = open(file->name, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to open file for writing: %d\n", errno);
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
message("ERROR: Failed to open file for writing: %d\n", errno);
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
nxffs_freefile(file);
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -255,11 +274,11 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file)
|
|||
nbyteswritten = write(fd, &g_fileimage[offset], nbytestowrite);
|
||||
if (nbyteswritten < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to write file: %d\n", errno);
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
fprintf(stderr, " Write offset: %d\n", offset);
|
||||
fprintf(stderr, " Write size: %d\n", nbytestowrite);
|
||||
message("ERROR: Failed to write file: %d\n", errno);
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
message(" Write offset: %d\n", offset);
|
||||
message(" Write size: %d\n", nbytestowrite);
|
||||
close(fd);
|
||||
|
||||
/* Remove any garbage file that might have been left behind */
|
||||
|
@ -267,11 +286,11 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file)
|
|||
ret = unlink(file->name);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, " Failed to remove corrupted file\n");
|
||||
message(" Failed to remove corrupted file\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, " Successfully removed corrupted file\n");
|
||||
message(" Successfully removed corrupted file\n");
|
||||
}
|
||||
|
||||
nxffs_freefile(file);
|
||||
|
@ -279,12 +298,12 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file)
|
|||
}
|
||||
else if (nbyteswritten != nbytestowrite)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Partial write:\n");
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
fprintf(stderr, " Write offset: %d\n", offset);
|
||||
fprintf(stderr, " Write size: %d\n", nbytestowrite);
|
||||
fprintf(stderr, " Written: %d\n", nbyteswritten);
|
||||
message("ERROR: Partial write:\n");
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
message(" Write offset: %d\n", offset);
|
||||
message(" Write size: %d\n", nbytestowrite);
|
||||
message(" Written: %d\n", nbyteswritten);
|
||||
}
|
||||
offset += nbyteswritten;
|
||||
}
|
||||
|
@ -313,7 +332,7 @@ static int nxffs_fillfs(void)
|
|||
ret = nxffs_wrfile(file);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to write a file. g_nfiles=%d\n", g_nfiles);
|
||||
message("ERROR: Failed to write file %d\n", i);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
@ -342,32 +361,32 @@ static ssize_t nxffs_rdblock(int fd, FAR struct nxffs_filedesc_s *file,
|
|||
nbytesread = read(fd, &g_fileimage[offset], len);
|
||||
if (nbytesread < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to read file: %d\n", errno);
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
fprintf(stderr, " Read offset: %d\n", offset);
|
||||
fprintf(stderr, " Read size: %d\n", len);
|
||||
message("ERROR: Failed to read file: %d\n", errno);
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
message(" Read offset: %d\n", offset);
|
||||
message(" Read size: %d\n", len);
|
||||
return ERROR;
|
||||
}
|
||||
else if (nbytesread == 0)
|
||||
{
|
||||
#if 0 /* No... we do this on purpose sometimes */
|
||||
fprintf(stderr, "ERROR: Unexpected end-of-file:\n");
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
fprintf(stderr, " Read offset: %d\n", offset);
|
||||
fprintf(stderr, " Read size: %d\n", len);
|
||||
message("ERROR: Unexpected end-of-file:\n");
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
message(" Read offset: %d\n", offset);
|
||||
message(" Read size: %d\n", len);
|
||||
#endif
|
||||
return ERROR;
|
||||
}
|
||||
else if (nbytesread != len)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Partial read:\n");
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
fprintf(stderr, " Read offset: %d\n", offset);
|
||||
fprintf(stderr, " Read size: %d\n", len);
|
||||
fprintf(stderr, " Bytes read: %d\n", nbytesread);
|
||||
message("ERROR: Partial read:\n");
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
message(" Read offset: %d\n", offset);
|
||||
message(" Read size: %d\n", len);
|
||||
message(" Bytes read: %d\n", nbytesread);
|
||||
}
|
||||
return nbytesread;
|
||||
}
|
||||
|
@ -390,9 +409,9 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file)
|
|||
{
|
||||
if (!file->deleted)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to open file for reading: %d\n", errno);
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
message("ERROR: Failed to open file for reading: %d\n", errno);
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -416,9 +435,9 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file)
|
|||
crc = crc32(g_fileimage, file->len);
|
||||
if (crc != file->crc)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Bad CRC: %d vs %d\n", crc, file->crc);
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
message("ERROR: Bad CRC: %d vs %d\n", crc, file->crc);
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
close(fd);
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -428,10 +447,10 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file)
|
|||
nbytesread = nxffs_rdblock(fd, file, ntotalread, 1024) ;
|
||||
if (nbytesread > 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Read past the end of file\n");
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
fprintf(stderr, " Bytes read: %d\n", nbytesread);
|
||||
message("ERROR: Read past the end of file\n");
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
message(" Bytes read: %d\n", nbytesread);
|
||||
close(fd);
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -462,16 +481,18 @@ static int nxffs_verifyfs(void)
|
|||
{
|
||||
if (file->deleted)
|
||||
{
|
||||
fprintf(stderr, "Deleted file %d OK\n", i);
|
||||
#if CONFIG_EXAMPLES_NXFFS_VERBOSE != 0
|
||||
message("Deleted file %d OK\n", i);
|
||||
#endif
|
||||
nxffs_freefile(file);
|
||||
g_ndeleted--;
|
||||
g_nfiles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to read a file: %d\n", i);
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
message("ERROR: Failed to read a file: %d\n", i);
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -479,9 +500,11 @@ static int nxffs_verifyfs(void)
|
|||
{
|
||||
if (file->deleted)
|
||||
{
|
||||
fprintf(stderr, "Succesffully read a deleted file\n");
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
#if CONFIG_EXAMPLES_NXFFS_VERBOSE != 0
|
||||
message("Succesffully read a deleted file\n");
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
#endif
|
||||
nxffs_freefile(file);
|
||||
g_ndeleted--;
|
||||
g_nfiles--;
|
||||
|
@ -489,7 +512,9 @@ static int nxffs_verifyfs(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "File %d: OK\n", i);
|
||||
#if CONFIG_EXAMPLES_NXFFS_VERBOSE != 0
|
||||
message("File %d: OK\n", i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -532,10 +557,10 @@ static int nxffs_delfiles(void)
|
|||
ret = unlink(file->name);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unlink %d failed: %d\n", i+1, errno);
|
||||
fprintf(stderr, " File name: %s\n", file->name);
|
||||
fprintf(stderr, " File size: %d\n", file->len);
|
||||
fprintf(stderr, " File index: %d\n", j);
|
||||
message("ERROR: Unlink %d failed: %d\n", i+1, errno);
|
||||
message(" File name: %s\n", file->name);
|
||||
message(" File size: %d\n", file->len);
|
||||
message(" File index: %d\n", j);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -558,6 +583,51 @@ static int nxffs_delfiles(void)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxffs_directory
|
||||
****************************************************************************/
|
||||
|
||||
static int nxffs_directory(void)
|
||||
{
|
||||
DIR *dirp;
|
||||
FAR struct dirent *entryp;
|
||||
int number;
|
||||
|
||||
/* Open the directory */
|
||||
|
||||
dirp = opendir(CONFIG_EXAMPLES_NXFFS_MOUNTPT);
|
||||
|
||||
if (!dirp)
|
||||
{
|
||||
/* Failed to open the directory */
|
||||
|
||||
message("ERROR: Failed to open directory '%s': %d\n",
|
||||
CONFIG_EXAMPLES_NXFFS_MOUNTPT, errno);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Read each directory entry */
|
||||
|
||||
message("Directory:\n");
|
||||
number = 1;
|
||||
do
|
||||
{
|
||||
entryp = readdir(dirp);
|
||||
if (entryp)
|
||||
{
|
||||
message("%2d. Type[%d]: %s Name: %s\n",
|
||||
number, entryp->d_type,
|
||||
entryp->d_type == DTYPE_FILE ? "File " : "Error",
|
||||
entryp->d_name);
|
||||
}
|
||||
number++;
|
||||
}
|
||||
while (entryp != NULL);
|
||||
|
||||
closedir(dirp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -581,7 +651,8 @@ int user_start(int argc, char *argv[])
|
|||
mtd = rammtd_initialize(g_simflash, CONFIG_EXAMPLES_NXFFS_BUFSIZE);
|
||||
if (!mtd)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to create RAM MTD instance\n");
|
||||
message("ERROR: Failed to create RAM MTD instance\n");
|
||||
msgflush();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -590,7 +661,8 @@ int user_start(int argc, char *argv[])
|
|||
ret = nxffs_initialize(mtd);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: NXFFS initialization failed: %d\n", -ret);
|
||||
message("ERROR: NXFFS initialization failed: %d\n", -ret);
|
||||
msgflush();
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
@ -599,7 +671,8 @@ int user_start(int argc, char *argv[])
|
|||
ret = mount(NULL, CONFIG_EXAMPLES_NXFFS_MOUNTPT, "nxffs", 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to mount the NXFFS volume: %d\n", errno);
|
||||
message("ERROR: Failed to mount the NXFFS volume: %d\n", errno);
|
||||
msgflush();
|
||||
exit(3);
|
||||
}
|
||||
|
||||
|
@ -608,64 +681,89 @@ int user_start(int argc, char *argv[])
|
|||
* delete, etc. This beats the FLASH very hard!
|
||||
*/
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
#if CONFIG_EXAMPLES_NXFFS_NLOOPS == 0
|
||||
for (;;)
|
||||
#else
|
||||
for (i = 1; i <= CONFIG_EXAMPLES_NXFFS_NLOOPS; i++)
|
||||
#endif
|
||||
{
|
||||
/* Write a files to the NXFFS file system until either (1) all of the
|
||||
* open file structures are utilized or until (2) NXFFS reports an error
|
||||
* (hopefully that the file system is full)
|
||||
*/
|
||||
|
||||
message("=== FILLING %d =============================\n", i);
|
||||
ret = nxffs_fillfs();
|
||||
fprintf(stderr, "Filled file system\n");
|
||||
fprintf(stderr, " Number of files: %d\n", g_nfiles);
|
||||
fprintf(stderr, " Number deleted: %d\n", g_ndeleted);
|
||||
nxffs_dump(mtd);
|
||||
message("Filled file system\n");
|
||||
message(" Number of files: %d\n", g_nfiles);
|
||||
message(" Number deleted: %d\n", g_ndeleted);
|
||||
nxffs_dump(mtd, CONFIG_EXAMPLES_NXFFS_VERBOSE);
|
||||
|
||||
/* Directory listing */
|
||||
|
||||
nxffs_directory();
|
||||
|
||||
/* Verify all files written to FLASH */
|
||||
|
||||
ret = nxffs_verifyfs();
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to verify files\n");
|
||||
message("ERROR: Failed to verify files\n");
|
||||
message(" Number of files: %d\n", g_nfiles);
|
||||
message(" Number deleted: %d\n", g_ndeleted);
|
||||
nxffs_dump(mtd, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Verified!\n");
|
||||
#if CONFIG_EXAMPLES_NXFFS_VERBOSE != 0
|
||||
message("Verified!\n");
|
||||
message(" Number of files: %d\n", g_nfiles);
|
||||
message(" Number deleted: %d\n", g_ndeleted);
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf(stderr, " Number of files: %d\n", g_nfiles);
|
||||
fprintf(stderr, " Number deleted: %d\n", g_ndeleted);
|
||||
|
||||
/* Delete some files */
|
||||
|
||||
message("=== DELETING %d ============================\n", i);
|
||||
ret = nxffs_delfiles();
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to delete files\n");
|
||||
message("ERROR: Failed to delete files\n");
|
||||
message(" Number of files: %d\n", g_nfiles);
|
||||
message(" Number deleted: %d\n", g_ndeleted);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Deleted some files\n");
|
||||
message("Deleted some files\n");
|
||||
message(" Number of files: %d\n", g_nfiles);
|
||||
message(" Number deleted: %d\n", g_ndeleted);
|
||||
}
|
||||
nxffs_dump(mtd, CONFIG_EXAMPLES_NXFFS_VERBOSE);
|
||||
|
||||
fprintf(stderr, " Number of files: %d\n", g_nfiles);
|
||||
fprintf(stderr, " Number deleted: %d\n", g_ndeleted);
|
||||
nxffs_dump(mtd);
|
||||
/* Directory listing */
|
||||
|
||||
nxffs_directory();
|
||||
|
||||
/* Verify all files written to FLASH */
|
||||
|
||||
ret = nxffs_verifyfs();
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to verify files\n");
|
||||
message("ERROR: Failed to verify files\n");
|
||||
message(" Number of files: %d\n", g_nfiles);
|
||||
message(" Number deleted: %d\n", g_ndeleted);
|
||||
nxffs_dump(mtd, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Verified!\n");
|
||||
#if CONFIG_EXAMPLES_NXFFS_VERBOSE != 0
|
||||
message("Verified!\n");
|
||||
message(" Number of files: %d\n", g_nfiles);
|
||||
message(" Number deleted: %d\n", g_ndeleted);
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf(stderr, " Number of files: %d\n", g_nfiles);
|
||||
fprintf(stderr, " Number deleted: %d\n", g_ndeleted);
|
||||
msgflush();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -555,6 +555,8 @@ extern off_t nxffs_iotell(FAR struct nxffs_volume_s *volume);
|
|||
* Input Parameters:
|
||||
* volume - Describes the NXFFS volume. The paramters ioblock and iooffset
|
||||
* in the volume structure determine the behavior of nxffs_getc().
|
||||
* reserve - If less than this much space is available at the end of the
|
||||
* block, then skip to the next block.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno indicating the
|
||||
|
@ -564,7 +566,7 @@ extern off_t nxffs_iotell(FAR struct nxffs_volume_s *volume);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
extern int nxffs_getc(FAR struct nxffs_volume_s *volume);
|
||||
extern int nxffs_getc(FAR struct nxffs_volume_s *volume, uint16_t reserve);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxffs_freeentry
|
||||
|
|
|
@ -99,7 +99,9 @@ int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block)
|
|||
ret = nxffs_rdcache(volume, block);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("Failed to read data into cache: %d\n", ret);
|
||||
/* Perhaps we are at the end of the media */
|
||||
|
||||
fvdbg("Failed to read data into cache: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -109,15 +111,29 @@ int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block)
|
|||
*/
|
||||
|
||||
blkhdr = (FAR struct nxffs_block_s *)volume->cache;
|
||||
if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) == 0 &&
|
||||
blkhdr->state == BLOCK_STATE_GOOD)
|
||||
if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) == 0)
|
||||
{
|
||||
/* The block is valid */
|
||||
/* This does appear to be a block */
|
||||
|
||||
return OK;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
/* Whatever is here where a block header should be is invalid */
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -196,6 +196,8 @@ off_t nxffs_iotell(FAR struct nxffs_volume_s *volume)
|
|||
* Input Parameters:
|
||||
* volume - Describes the NXFFS volume. The paramters ioblock and iooffset
|
||||
* in the volume structure determine the behavior of nxffs_getc().
|
||||
* reserve - If less than this much space is available at the end of the
|
||||
* block, then skip to the next block.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno indicating the
|
||||
|
@ -203,24 +205,26 @@ off_t nxffs_iotell(FAR struct nxffs_volume_s *volume)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxffs_getc(FAR struct nxffs_volume_s *volume)
|
||||
int nxffs_getc(FAR struct nxffs_volume_s *volume, uint16_t reserve)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(reserve > 0);
|
||||
|
||||
/* Loop to skip over bad blocks */
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
/* Check if we have read past the current block */
|
||||
/* Check if we have the reserve amount at the end of the current block */
|
||||
|
||||
if (volume->iooffset >= volume->geo.blocksize)
|
||||
if (volume->iooffset + reserve > volume->geo.blocksize)
|
||||
{
|
||||
/* Check for attempt to read past the end of FLASH */
|
||||
|
||||
off_t nextblock = volume->ioblock + 1;
|
||||
if (nextblock >= volume->nblocks)
|
||||
{
|
||||
fdbg("End of FLASH encountered\n");
|
||||
fvdbg("End of FLASH encountered\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
@ -241,7 +245,7 @@ int nxffs_getc(FAR struct nxffs_volume_s *volume)
|
|||
ret = nxffs_verifyblock(volume, volume->ioblock);
|
||||
if (ret < 0 && ret != -ENOENT)
|
||||
{
|
||||
fdbg("Failed to read valid data into cache: %d\n", ret);
|
||||
fvdbg("Failed to read valid data into cache: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ struct nxffs_blkinfo_s
|
|||
off_t nblocks;
|
||||
off_t block;
|
||||
off_t offset;
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -170,7 +171,10 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
|
|||
{
|
||||
/* Not than we cannot verify the inode header */
|
||||
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "UNVERFD", datlen);
|
||||
if (blkinfo->verbose)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "UNVERFD", datlen);
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
@ -202,11 +206,17 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo,
|
|||
|
||||
if (state == INODE_STATE_FILE)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "OK ", datlen);
|
||||
if (blkinfo->verbose)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "OK ", datlen);
|
||||
}
|
||||
}
|
||||
else if (state == INODE_STATE_DELETED)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "DELETED", datlen);
|
||||
if (blkinfo->verbose)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, offset, "INODE", "DELETED", datlen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -266,7 +276,10 @@ static inline ssize_t nxffs_analyzedata(FAR struct nxffs_blkinfo_s *blkinfo,
|
|||
|
||||
/* If must be a good header */
|
||||
|
||||
fdbg(g_format, blkinfo->block, offset, "DATA ", "OK ", datlen);
|
||||
if (blkinfo->verbose)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, offset, "DATA ", "OK ", datlen);
|
||||
}
|
||||
return SIZEOF_NXFFS_DATA_HDR + datlen;
|
||||
}
|
||||
#endif
|
||||
|
@ -303,8 +316,11 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo)
|
|||
size_t nerased = nxffs_erased(blkinfo->buffer + SIZEOF_NXFFS_BLOCK_HDR, datsize);
|
||||
if (nerased == datsize)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, 0, "BLOCK", "ERASED ",
|
||||
blkinfo->geo.blocksize);
|
||||
if (blkinfo->verbose)
|
||||
{
|
||||
fdbg(g_format, blkinfo->block, 0, "BLOCK", "ERASED ",
|
||||
blkinfo->geo.blocksize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#if 0 /* Too much output, to little information */
|
||||
|
@ -384,7 +400,9 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo)
|
|||
* and CONFIG_DEBUG_FS must be enabled for this function to do anything.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mtd - The MTD device that provides the interface to NXFFS-formatted media.
|
||||
* mtd - The MTD device that provides the interface to NXFFS-formatted
|
||||
* media.
|
||||
* verbose - FALSE: only show errors
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
|
@ -392,7 +410,7 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxffs_dump(FAR struct mtd_dev_s *mtd)
|
||||
int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose)
|
||||
{
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||
struct nxffs_blkinfo_s blkinfo;
|
||||
|
@ -407,16 +425,20 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd)
|
|||
ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&blkinfo.geo));
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret);
|
||||
fdbg("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Save the verbose output indication */
|
||||
|
||||
blkinfo.verbose = verbose;
|
||||
|
||||
/* Allocate a buffer to hold one block */
|
||||
|
||||
blkinfo.buffer = (FAR uint8_t *)kmalloc(blkinfo.geo.blocksize);
|
||||
if (!blkinfo.buffer)
|
||||
{
|
||||
fdbg("Failed to allocate block cache\n");
|
||||
fdbg("ERROR: Failed to allocate block cache\n");
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
@ -436,7 +458,7 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd)
|
|||
ret = MTD_BREAD(mtd, blkinfo.block, 1, blkinfo.buffer);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("Failed to read block %d\n", blkinfo.block);
|
||||
fdbg("ERROR: Failed to read block %d\n", blkinfo.block);
|
||||
goto errout_with_block;
|
||||
}
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ int nxffs_limits(FAR struct nxffs_volume_s *volume)
|
|||
nerased = 0;
|
||||
for (;;)
|
||||
{
|
||||
int ch = nxffs_getc(volume);
|
||||
int ch = nxffs_getc(volume, 1);
|
||||
if (ch < 0)
|
||||
{
|
||||
/* Failed to read the next byte... this could mean that the FLASH
|
||||
|
|
|
@ -282,7 +282,7 @@ int nxffs_nextentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
|||
{
|
||||
/* Read the next character */
|
||||
|
||||
ch = nxffs_getc(volume);
|
||||
ch = nxffs_getc(volume, SIZEOF_NXFFS_INODE_HDR - nmagic);
|
||||
if (ch < 0)
|
||||
{
|
||||
fvdbg("nxffs_getc failed: %d\n", -ch);
|
||||
|
|
|
@ -745,7 +745,7 @@ static inline int nxffs_rdopen(FAR struct nxffs_volume_s *volume,
|
|||
ret = nxffs_findinode(volume, name, &ofile->entry);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("Inode '%s' not found: %d\n", name, -ret);
|
||||
fvdbg("Inode '%s' not found: %d\n", name, -ret);
|
||||
goto errout_with_ofile;
|
||||
}
|
||||
|
||||
|
|
|
@ -550,6 +550,7 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume,
|
|||
pack->dest.blkpos = 0;
|
||||
}
|
||||
|
||||
volume->froffset = nxffs_packtell(volume, pack);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -791,8 +792,9 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume,
|
|||
pack->dest.fpos += xfrlen; /* Destination data offsets */
|
||||
pack->dest.blkpos += xfrlen;
|
||||
pack->dest.blklen += xfrlen; /* Destination data block size */
|
||||
volume->iooffset += xfrlen; /* Source I/O block offset */
|
||||
pack->iooffset += xfrlen; /* Destination I/O block offset */
|
||||
volume->iooffset += xfrlen; /* Source I/O block offset */
|
||||
volume->froffset += xfrlen; /* Free FLASH offset */
|
||||
|
||||
/* Now, either the (1) src block has been fully transferred, (2) all
|
||||
* of the source data has been transferred, or (3) the the destination
|
||||
|
@ -896,7 +898,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume,
|
|||
|
||||
/* Yes.. find the next data block in the source input stream. */
|
||||
|
||||
offset = pack->src.blkoffset + SIZEOF_NXFFS_BLOCK_HDR + pack->src.blklen;
|
||||
offset = pack->src.blkoffset + SIZEOF_NXFFS_DATA_HDR + pack->src.blklen;
|
||||
ret = nxffs_nextblock(volume, offset, &blkentry);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -1000,7 +1002,8 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume)
|
|||
* nxffs_startpos() that the inode header will fit at hoffset.
|
||||
*/
|
||||
|
||||
pack.iooffset += SIZEOF_NXFFS_INODE_HDR;
|
||||
pack.iooffset += SIZEOF_NXFFS_INODE_HDR;
|
||||
volume->froffset = nxffs_packtell(volume, &pack);
|
||||
|
||||
/* Then pack all erase blocks starting with the erase block that contains
|
||||
* the ioblock and through the final erase block on the FLASH.
|
||||
|
|
|
@ -292,7 +292,7 @@ int nxffs_nextblock(FAR struct nxffs_volume_s *volume, off_t offset,
|
|||
{
|
||||
/* Read the next character */
|
||||
|
||||
ch = nxffs_getc(volume);
|
||||
ch = nxffs_getc(volume, SIZEOF_NXFFS_DATA_HDR - nmagic);
|
||||
if (ch < 0)
|
||||
{
|
||||
fvdbg("nxffs_getc failed: %d\n", -ch);
|
||||
|
|
|
@ -112,7 +112,9 @@ EXTERN int nxffs_initialize(FAR struct mtd_dev_s *mtd);
|
|||
* and CONFIG_DEBUG_FS must be enabled for this function to do anything.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mtd - The MTD device that provides the interface to NXFFS-formatted media.
|
||||
* mtd - The MTD device that provides the interface to NXFFS-formatted
|
||||
* media.
|
||||
* verbose - FALSE: only show errors
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
|
@ -120,7 +122,7 @@ EXTERN int nxffs_initialize(FAR struct mtd_dev_s *mtd);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int nxffs_dump(FAR struct mtd_dev_s *mtd);
|
||||
EXTERN int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue