drivers/mtd/smart.c Fixed SmartFS wear level error that occurs when the logical sector size is too small to save all wear level status bytes in a single sector. Logical sectors 1 and 2 were simply not being allocated and then the read_sector and write_sector routines were failing. From Ken Petit
This commit is contained in:
parent
cfc38a45fa
commit
cbe1b3a415
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/system/smart_test/smart_test.c
|
* apps/system/smart_test/smart_test.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Ken Pettit. All rights reserved.
|
* Copyright (C) 2013, 2015 Ken Pettit. All rights reserved.
|
||||||
* Author: Ken Pettit <pettitkd@gmail.com>
|
* Author: Ken Pettit <pettitkd@gmail.com>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -52,15 +52,15 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define SMART_TEST_LINE_COUNT 2000
|
|
||||||
#define SMART_TEST_SEEK_WRITE_COUNT 2000
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private data
|
* Private data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int g_linePos[SMART_TEST_LINE_COUNT];
|
static int *g_linePos;
|
||||||
static int g_lineLen[SMART_TEST_LINE_COUNT];
|
static int *g_lineLen;
|
||||||
|
static int g_lineCount = 2000;
|
||||||
|
static int g_seekCount = 2000;
|
||||||
|
static int g_writeCount = 2000;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@ -76,7 +76,7 @@ static int g_lineLen[SMART_TEST_LINE_COUNT];
|
|||||||
|
|
||||||
static int smart_create_test_file(char *filename)
|
static int smart_create_test_file(char *filename)
|
||||||
{
|
{
|
||||||
FILE* fd;
|
FILE *fd;
|
||||||
int x;
|
int x;
|
||||||
char string[80];
|
char string[80];
|
||||||
|
|
||||||
@ -97,8 +97,8 @@ static int smart_create_test_file(char *filename)
|
|||||||
* file where that file starts.
|
* file where that file starts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf("Writing test data. %d lines to write\n", SMART_TEST_LINE_COUNT);
|
printf("Writing test data. %d lines to write\n", g_lineCount);
|
||||||
for (x = 0; x < SMART_TEST_LINE_COUNT; x++)
|
for (x = 0; x < g_lineCount; x++)
|
||||||
{
|
{
|
||||||
g_linePos[x] = ftell(fd);
|
g_linePos[x] = ftell(fd);
|
||||||
|
|
||||||
@ -128,13 +128,12 @@ static int smart_create_test_file(char *filename)
|
|||||||
|
|
||||||
static int smart_seek_test(char *filename)
|
static int smart_seek_test(char *filename)
|
||||||
{
|
{
|
||||||
FILE* fd;
|
FILE *fd;
|
||||||
int x;
|
|
||||||
int index;
|
|
||||||
char readstring[80];
|
char readstring[80];
|
||||||
char cmpstring[80];
|
char cmpstring[80];
|
||||||
|
int index;
|
||||||
printf("Performing 2000 random seek tests\n");
|
int x;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
fd = fopen(filename, "r");
|
fd = fopen(filename, "r");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
@ -143,15 +142,17 @@ static int smart_seek_test(char *filename)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Performing %d random seek tests\n", g_seekCount);
|
||||||
|
|
||||||
srand(23);
|
srand(23);
|
||||||
for (x = 0; x < 2000; x++)
|
for (x = 0; x < g_seekCount; x++)
|
||||||
{
|
{
|
||||||
/* Get random line to seek to */
|
/* Get random line to seek to */
|
||||||
|
|
||||||
index = rand();
|
index = rand();
|
||||||
while (index >= SMART_TEST_LINE_COUNT)
|
while (index >= g_lineCount)
|
||||||
{
|
{
|
||||||
index -= SMART_TEST_LINE_COUNT;
|
index -= g_lineCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(fd, g_linePos[index], SEEK_SET);
|
fseek(fd, g_linePos[index], SEEK_SET);
|
||||||
@ -164,15 +165,20 @@ static int smart_seek_test(char *filename)
|
|||||||
if (strcmp(readstring, cmpstring) != 0)
|
if (strcmp(readstring, cmpstring) != 0)
|
||||||
{
|
{
|
||||||
printf("\nSeek error on line %d\n", index);
|
printf("\nSeek error on line %d\n", index);
|
||||||
|
printf ("\t Expected \"%s\"\n", cmpstring);
|
||||||
|
printf ("\t Received \"%s\"\n", readstring);
|
||||||
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\r%d", x);
|
printf("\r%d", x);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fd);
|
printf("\r%d", x);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
return OK;
|
fclose(fd);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -184,7 +190,7 @@ static int smart_seek_test(char *filename)
|
|||||||
|
|
||||||
static int smart_append_test(char *filename)
|
static int smart_append_test(char *filename)
|
||||||
{
|
{
|
||||||
FILE* fd;
|
FILE *fd;
|
||||||
int pos;
|
int pos;
|
||||||
char readstring[80];
|
char readstring[80];
|
||||||
|
|
||||||
@ -217,15 +223,14 @@ static int smart_append_test(char *filename)
|
|||||||
readstring[30] = '\0';
|
readstring[30] = '\0';
|
||||||
if (strcmp(readstring, "This is a test of the append.\n") != 0)
|
if (strcmp(readstring, "This is a test of the append.\n") != 0)
|
||||||
{
|
{
|
||||||
printf("Append test failed\n");
|
printf("\nAppend test failed\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Append test passed\n");
|
printf("\nAppend test passed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,16 +243,17 @@ static int smart_append_test(char *filename)
|
|||||||
|
|
||||||
static int smart_seek_with_write_test(char *filename)
|
static int smart_seek_with_write_test(char *filename)
|
||||||
{
|
{
|
||||||
FILE* fd;
|
FILE *fd;
|
||||||
int x;
|
|
||||||
int index;
|
|
||||||
char temp;
|
char temp;
|
||||||
char readstring[80];
|
char readstring[80];
|
||||||
char cmpstring[80];
|
char cmpstring[80];
|
||||||
int c, s1, s2, len;
|
int c;
|
||||||
|
int s1;
|
||||||
printf("Performing %d random seek with write tests\n",
|
int s2;
|
||||||
SMART_TEST_SEEK_WRITE_COUNT);
|
int len;
|
||||||
|
int x;
|
||||||
|
int index;
|
||||||
|
int pass = TRUE;
|
||||||
|
|
||||||
fd = fopen(filename, "r+");
|
fd = fopen(filename, "r+");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
@ -256,16 +262,19 @@ static int smart_seek_with_write_test(char *filename)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Performing %d random seek with write tests\n",
|
||||||
|
g_writeCount);
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
for (x = 0; x < SMART_TEST_SEEK_WRITE_COUNT; x++)
|
for (x = 0; x < g_writeCount; x++)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* Get a random value */
|
/* Get a random value */
|
||||||
|
|
||||||
index = rand();
|
index = rand();
|
||||||
while (index >= SMART_TEST_LINE_COUNT)
|
while (index >= g_lineCount)
|
||||||
{
|
{
|
||||||
index -= SMART_TEST_LINE_COUNT;
|
index -= g_lineCount;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Read the data into the buffer */
|
/* Read the data into the buffer */
|
||||||
@ -301,7 +310,13 @@ static int smart_seek_with_write_test(char *filename)
|
|||||||
|
|
||||||
if (strcmp(readstring, cmpstring) != 0)
|
if (strcmp(readstring, cmpstring) != 0)
|
||||||
{
|
{
|
||||||
printf("\nCompare failure on line %d\n", index);
|
printf("\nCompare failure on line %d, offset %d\n",
|
||||||
|
index, g_linePos[index]);
|
||||||
|
printf("\tExpected \"%s\"", cmpstring);
|
||||||
|
printf("\rReceived \"%s\"", readstring);
|
||||||
|
fseek(fd, g_linePos[index], SEEK_SET);
|
||||||
|
fread(cmpstring, 1, g_lineLen[index], fd);
|
||||||
|
pass = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,16 +325,22 @@ static int smart_seek_with_write_test(char *filename)
|
|||||||
|
|
||||||
/* On to next line */
|
/* On to next line */
|
||||||
|
|
||||||
if (++index >= SMART_TEST_LINE_COUNT)
|
if (++index >= g_lineCount)
|
||||||
{
|
{
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
if (pass)
|
||||||
|
{
|
||||||
|
printf("\nPass\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\nFail\n");
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,45 +354,87 @@ int main(int argc, FAR char *argv[])
|
|||||||
int smart_test_main(int argc, char *argv[])
|
int smart_test_main(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, opt;
|
||||||
|
int gTestCount = 10000;
|
||||||
|
|
||||||
/* Argument given? */
|
/* Argument given? */
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "l:s:w:")) != -1)
|
||||||
|
{
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
g_lineCount = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
g_seekCount = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
g_writeCount = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* '?' */
|
||||||
|
fprintf(stderr, "usage: smart_test [-l lineCount] [-s seekCount] [-w writeCount] smart_mounted_filename\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: smart_test smart_mounted_filename\n");
|
fprintf(stderr, "usage: smart_test [-l lineCount] [-s seekCount] [-w writeCount] smart_mounted_filename\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the test */
|
||||||
|
|
||||||
|
g_linePos = malloc(g_lineCount * sizeof(int));
|
||||||
|
if (g_linePos == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_lineLen = malloc(g_lineCount * sizeof(int));
|
||||||
|
if (g_lineLen == NULL)
|
||||||
|
{
|
||||||
|
free(g_linePos);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a test file */
|
/* Create a test file */
|
||||||
|
|
||||||
if ((ret = smart_create_test_file(argv[1])) < 0)
|
if ((ret = smart_create_test_file(argv[optind])) < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
goto err_out_with_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Conduct a seek test */
|
/* Conduct a seek test */
|
||||||
|
|
||||||
if ((ret = smart_seek_test(argv[1])) < 0)
|
if ((ret = smart_seek_test(argv[optind])) < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
goto err_out_with_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Conduct an append test */
|
/* Conduct an append test */
|
||||||
|
|
||||||
if ((ret = smart_append_test(argv[1])) < 0)
|
if ((ret = smart_append_test(argv[optind])) < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
goto err_out_with_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Conduct a seek with write test */
|
/* Conduct a seek with write test */
|
||||||
|
|
||||||
if ((ret = smart_seek_with_write_test(argv[1])) < 0)
|
if ((ret = smart_seek_with_write_test(argv[optind])) < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
goto err_out_with_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the file */
|
err_out_with_mem:
|
||||||
|
|
||||||
return 0;
|
/* Free the memory */
|
||||||
|
|
||||||
|
free(g_linePos);
|
||||||
|
free(g_lineLen);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user