fs/spiffs: Fix more problems found in testing. It is getting closer but examples/fstest is still showing problem.

This commit is contained in:
Gregory Nutt
2018-09-26 10:05:43 -06:00
parent 955527b14f
commit 6d2cce99e1
7 changed files with 140 additions and 116 deletions
+2 -1
View File
@@ -190,7 +190,8 @@ static void *ram_write(FAR void *dest, FAR const void *src, size_t len)
* Name: ram_erase * Name: ram_erase
****************************************************************************/ ****************************************************************************/
static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks)
{ {
FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev; FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
off_t offset; off_t offset;
+3 -3
View File
@@ -543,7 +543,7 @@ static int spiffs_check_luentry_validate(FAR struct spiffs_s *fs,
ret = spiffs_objlu_find_id_and_span_byphdr(fs, ret = spiffs_objlu_find_id_and_span_byphdr(fs,
pghdr->objid | SPIFFS_OBJID_NDXFLAG, pghdr->objid | SPIFFS_OBJID_NDXFLAG,
0, 0, 0); 0, 0, 0);
if (ret == OK) if (ret >= 0)
{ {
int16_t new_pgndx; int16_t new_pgndx;
@@ -1229,7 +1229,7 @@ static int spiffs_check_objidconsistency_callback(FAR struct spiffs_s *fs,
0, 0, &objhdr_pgndx); 0, 0, &objhdr_pgndx);
retc = SPIFFS_VIS_COUNTINUE_RELOAD; retc = SPIFFS_VIS_COUNTINUE_RELOAD;
if (ret == OK) if (ret >= 0)
{ {
/* Found, register as reachable */ /* Found, register as reachable */
@@ -1767,7 +1767,7 @@ int spiffs_check_pgconsistency(FAR struct spiffs_s *fs)
ret = spiffs_check_get_data_pgndx(fs, pghdr.objid, ret = spiffs_check_get_data_pgndx(fs, pghdr.objid,
pghdr.spndx, &rpgndx, pghdr.spndx, &rpgndx,
&objndx_pgndx); &objndx_pgndx);
if (ret == OK) if (ret >= 0)
{ {
if (((rpgndx == (int16_t) - 1 || if (((rpgndx == (int16_t) - 1 ||
rpgndx > SPIFFS_GEO_PAGE_COUNT(fs)) || rpgndx > SPIFFS_GEO_PAGE_COUNT(fs)) ||
+35 -35
View File
@@ -189,10 +189,10 @@ static int spiffs_page_index_check(FAR struct spiffs_s *fs,
return ret; return ret;
} }
ret = spiffs_validate_objix(&ph, fobj->objid, spndx); ret = spiffs_validate_objndx(&ph, fobj->objid, spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
#endif #endif
@@ -418,7 +418,7 @@ spiffs_objlu_find_free_objid_compact_callback(FAR struct spiffs_s *fs,
SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, blkndx, entry), SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, blkndx, entry),
sizeof(struct spiffs_pgobj_ndxheader_s), sizeof(struct spiffs_pgobj_ndxheader_s),
(FAR uint8_t *)&objhdr); (FAR uint8_t *)&objhdr);
if (ret == OK && objhdr.phdr.spndx == 0 && if (ret >= 0 && objhdr.phdr.spndx == 0 &&
((objhdr.phdr.flags & (SPIFFS_PH_FLAG_INDEX | ((objhdr.phdr.flags & (SPIFFS_PH_FLAG_INDEX |
SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_FINAL |
SPIFFS_PH_FLAG_DELET)) == SPIFFS_PH_FLAG_DELET)) ==
@@ -451,7 +451,7 @@ spiffs_objlu_find_free_objid_compact_callback(FAR struct spiffs_s *fs,
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: spiffs_validate_objix * Name: spiffs_validate_objndx
* *
* Description: * Description:
* Returns zero (OK) if everything checks out. Otherwise, a negated errno * Returns zero (OK) if everything checks out. Otherwise, a negated errno
@@ -459,8 +459,8 @@ spiffs_objlu_find_free_objid_compact_callback(FAR struct spiffs_s *fs,
* *
****************************************************************************/ ****************************************************************************/
int spiffs_validate_objix(FAR struct spiffs_page_header_s *ph, int16_t objid, int spiffs_validate_objndx(FAR struct spiffs_page_header_s *ph,
int16_t spndx) int16_t objid, int16_t spndx)
{ {
int ret = OK; int ret = OK;
@@ -584,7 +584,7 @@ int spiffs_foreach_objlu(FAR struct spiffs_s *fs, int16_t starting_block,
entry_count = SPIFFS_GEO_BLOCK_COUNT(fs) * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs); entry_count = SPIFFS_GEO_BLOCK_COUNT(fs) * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs);
cur_block = starting_block; cur_block = starting_block;
cur_block_addr = starting_block * SPIFFS_GEO_BLOCK_SIZE(fs); cur_block_addr = starting_block * SPIFFS_GEO_BLOCK_SIZE(fs);
objlu_buf = (FAR int16_t *) fs->lu_work; objlu_buf = (FAR int16_t *)fs->lu_work;
cur_entry = starting_lu_entry; cur_entry = starting_lu_entry;
entries_per_page = (SPIFFS_GEO_PAGE_SIZE(fs) / sizeof(int16_t)); entries_per_page = (SPIFFS_GEO_PAGE_SIZE(fs) / sizeof(int16_t));
ret = OK; ret = OK;
@@ -615,13 +615,13 @@ int spiffs_foreach_objlu(FAR struct spiffs_s *fs, int16_t starting_block,
/* Check each block */ /* Check each block */
while (ret == OK && entry_count > 0) while (ret >= 0 && entry_count > 0)
{ {
int obj_lookup_page = cur_entry / entries_per_page; int obj_lookup_page = cur_entry / entries_per_page;
/* Check each object lookup page */ /* Check each object lookup page */
while (ret == OK && while (ret >= 0 &&
obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs))
{ {
int entry_offset = obj_lookup_page * entries_per_page; int entry_offset = obj_lookup_page * entries_per_page;
@@ -632,7 +632,7 @@ int spiffs_foreach_objlu(FAR struct spiffs_s *fs, int16_t starting_block,
/* Check each entry */ /* Check each entry */
while (ret == OK && while (ret >= 0 &&
cur_entry - entry_offset < entries_per_page && cur_entry - entry_offset < entries_per_page &&
cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs))
{ {
@@ -900,7 +900,7 @@ int spiffs_objlu_find_free(FAR struct spiffs_s *fs, int16_t starting_block,
ret = spiffs_objlu_find_id(fs, starting_block, starting_lu_entry, ret = spiffs_objlu_find_id(fs, starting_block, starting_lu_entry,
SPIFFS_OBJID_FREE, blkndx, lu_entry); SPIFFS_OBJID_FREE, blkndx, lu_entry);
if (ret == OK) if (ret >= 0)
{ {
fs->free_blkndx = *blkndx; fs->free_blkndx = *blkndx;
fs->free_entry = (*lu_entry) + 1; fs->free_entry = (*lu_entry) + 1;
@@ -1442,10 +1442,10 @@ int spiffs_object_update_index_hdr(FAR struct spiffs_s *fs,
objhdr = (FAR struct spiffs_pgobj_ndxheader_s *) fs->work; objhdr = (FAR struct spiffs_pgobj_ndxheader_s *) fs->work;
} }
ret = spiffs_validate_objix(&objhdr->phdr, objid, 0); ret = spiffs_validate_objndx(&objhdr->phdr, objid, 0);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
@@ -1662,10 +1662,10 @@ int spiffs_object_open_bypage(FAR struct spiffs_s *fs, int16_t pgndx,
fobj->objid = objid; fobj->objid = objid;
fobj->flags = flags; fobj->flags = flags;
ret = spiffs_validate_objix(&objndx_hdr.phdr, fobj->objid, 0); ret = spiffs_validate_objndx(&objndx_hdr.phdr, fobj->objid, 0);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
@@ -1727,7 +1727,7 @@ int spiffs_object_append(FAR struct spiffs_s *fs,
/* Write all data */ /* Write all data */
while (ret == OK && written < len) while (ret >= 0 && written < len)
{ {
size_t to_write; size_t to_write;
@@ -1875,11 +1875,11 @@ int spiffs_object_append(FAR struct spiffs_s *fs,
return ret; return ret;
} }
ret = spiffs_validate_objix(&objhdr->phdr, fobj->objid, ret = spiffs_validate_objndx(&objhdr->phdr, fobj->objid,
cur_objndx_spndx); cur_objndx_spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
} }
@@ -1967,11 +1967,11 @@ int spiffs_object_append(FAR struct spiffs_s *fs,
return ret; return ret;
} }
ret = spiffs_validate_objix(&objhdr->phdr, fobj->objid, ret = spiffs_validate_objndx(&objhdr->phdr, fobj->objid,
cur_objndx_spndx); cur_objndx_spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ferr("ERROR: spiffs_validate_objndx() failed: %d\n",
ret); ret);
return ret; return ret;
} }
@@ -2261,7 +2261,7 @@ int spiffs_object_modify(FAR struct spiffs_s *fs,
/* Write all data */ /* Write all data */
while (ret == OK && written < len) while (ret >= 0 && written < len)
{ {
size_t to_write; size_t to_write;
int16_t orig_data_pgndx; int16_t orig_data_pgndx;
@@ -2358,11 +2358,11 @@ int spiffs_object_modify(FAR struct spiffs_s *fs,
return ret; return ret;
} }
ret = spiffs_validate_objix(&objhdr->phdr, fobj->objid, ret = spiffs_validate_objndx(&objhdr->phdr, fobj->objid,
cur_objndx_spndx); cur_objndx_spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
} }
@@ -2405,11 +2405,11 @@ int spiffs_object_modify(FAR struct spiffs_s *fs,
return ret; return ret;
} }
ret = spiffs_validate_objix(&objhdr->phdr, fobj->objid, ret = spiffs_validate_objndx(&objhdr->phdr, fobj->objid,
cur_objndx_spndx); cur_objndx_spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
@@ -2882,11 +2882,11 @@ int spiffs_object_truncate(FAR struct spiffs_s *fs,
return ret; return ret;
} }
ret = spiffs_validate_objix(&objhdr->phdr, fobj->objid, ret = spiffs_validate_objndx(&objhdr->phdr, fobj->objid,
cur_objndx_spndx); cur_objndx_spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
@@ -3280,11 +3280,11 @@ ssize_t spiffs_object_read(FAR struct spiffs_s *fs,
return ret; return ret;
} }
ret = spiffs_validate_objix(&objndx->phdr, fobj->objid, ret = spiffs_validate_objndx(&objndx->phdr, fobj->objid,
cur_objndx_spndx); cur_objndx_spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
+2 -2
View File
@@ -391,8 +391,8 @@ typedef int (*spiffs_callback_t)(FAR struct spiffs_s *fs, int16_t objid,
* Public Function Prototypes * Public Function Prototypes
****************************************************************************/ ****************************************************************************/
int spiffs_validate_objix(FAR struct spiffs_page_header_s *ph, int spiffs_validate_objndx(FAR struct spiffs_page_header_s *ph,
int16_t objid, int16_t spndx); int16_t objid, int16_t spndx);
int spiffs_phys_cpy(FAR struct spiffs_s *fs, int spiffs_phys_cpy(FAR struct spiffs_s *fs,
int16_t objid, uint32_t dest, uint32_t src, uint32_t len); int16_t objid, uint32_t dest, uint32_t src, uint32_t len);
int spiffs_foreach_objlu(FAR struct spiffs_s *fs, int16_t starting_block, int spiffs_foreach_objlu(FAR struct spiffs_s *fs, int16_t starting_block,
+18 -18
View File
@@ -168,7 +168,7 @@ static int spiffs_gc_epage_stats(FAR struct spiffs_s *fs, int16_t blkndx)
/* Check each object lookup page */ /* Check each object lookup page */
while (ret == OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) while (ret >= 0 && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs))
{ {
int entry_offset = obj_lookup_page * entries_per_page; int entry_offset = obj_lookup_page * entries_per_page;
ret = spiffs_cache_read(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, ret = spiffs_cache_read(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0,
@@ -178,7 +178,7 @@ static int spiffs_gc_epage_stats(FAR struct spiffs_s *fs, int16_t blkndx)
/* Check each entry */ /* Check each entry */
while (ret == OK && while (ret >= 0 &&
cur_entry - entry_offset < entries_per_page && cur_entry - entry_offset < entries_per_page &&
cur_entry < cur_entry <
(int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) (int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)))
@@ -272,7 +272,7 @@ static int spiffs_gc_find_candidate(FAR struct spiffs_s *fs,
/* Check each block */ /* Check each block */
while (ret == OK && blocks--) while (ret >= 0 && blocks--)
{ {
uint16_t deleted_pages_in_block = 0; uint16_t deleted_pages_in_block = 0;
uint16_t used_pages_in_block = 0; uint16_t used_pages_in_block = 0;
@@ -280,7 +280,7 @@ static int spiffs_gc_find_candidate(FAR struct spiffs_s *fs,
/* check each object lookup page */ /* check each object lookup page */
while (ret == OK && while (ret >= 0 &&
obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs))
{ {
int entry_offset = obj_lookup_page * entries_per_page; int entry_offset = obj_lookup_page * entries_per_page;
@@ -291,7 +291,7 @@ static int spiffs_gc_find_candidate(FAR struct spiffs_s *fs,
/* Check each entry */ /* Check each entry */
while (ret == OK && while (ret >= 0 &&
cur_entry - entry_offset < entries_per_page && cur_entry - entry_offset < entries_per_page &&
cur_entry < cur_entry <
(int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) - (int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) -
@@ -332,7 +332,7 @@ static int spiffs_gc_find_candidate(FAR struct spiffs_s *fs,
* probably not so many blocks * probably not so many blocks
*/ */
if (ret == OK /* && deleted_pages_in_block > 0 */ ) if (ret >= 0 /* && deleted_pages_in_block > 0 */ )
{ {
int32_t score; int32_t score;
int16_t erase_count; int16_t erase_count;
@@ -476,7 +476,7 @@ static int spiffs_gc_clean(FAR struct spiffs_s *fs, int16_t blkndx)
spiffs_gcinfo("Move free cursor to block=%0rx\n", fs->free_blkndx); spiffs_gcinfo("Move free cursor to block=%0rx\n", fs->free_blkndx);
} }
while (ret == OK && gc.state != FINISHED) while (ret >= 0 && gc.state != FINISHED)
{ {
int obj_lookup_page; int obj_lookup_page;
uint8_t scan; uint8_t scan;
@@ -492,7 +492,7 @@ static int spiffs_gc_clean(FAR struct spiffs_s *fs, int16_t blkndx)
/* Check each object lookup page */ /* Check each object lookup page */
while (scan && ret == OK && while (scan && ret >= 0 &&
obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs))
{ {
int entry_offset = obj_lookup_page * entries_per_page; int entry_offset = obj_lookup_page * entries_per_page;
@@ -504,7 +504,7 @@ static int spiffs_gc_clean(FAR struct spiffs_s *fs, int16_t blkndx)
/* Check each object lookup entry */ /* Check each object lookup entry */
while (scan && ret == OK && while (scan && ret >= 0 &&
cur_entry - entry_offset < entries_per_page && cur_entry - entry_offset < entries_per_page &&
cur_entry < cur_entry <
(int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) - (int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) -
@@ -845,12 +845,12 @@ static int spiffs_gc_clean(FAR struct spiffs_s *fs, int16_t blkndx)
* index, a check must run or lot of data may be lost * index, a check must run or lot of data may be lost
*/ */
ret = spiffs_validate_objix(&objndx->phdr, ret = spiffs_validate_objndx(&objndx->phdr,
gc.cur_objid | SPIFFS_OBJID_NDXFLAG, gc.cur_objid | SPIFFS_OBJID_NDXFLAG,
gc.cur_objndx_spndx); gc.cur_objndx_spndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_validate_objix() failed: %d\n", ret); ferr("ERROR: spiffs_validate_objndx() failed: %d\n", ret);
return ret; return ret;
} }
@@ -981,7 +981,7 @@ int spiffs_gc_quick(FAR struct spiffs_s *fs, uint16_t max_free_pages)
/* Find fully deleted blocks */ /* Find fully deleted blocks */
while (ret == OK && blocks--) while (ret >= 0 && blocks--)
{ {
uint16_t deleted_pages_in_block = 0; uint16_t deleted_pages_in_block = 0;
uint16_t free_pages_in_block = 0; uint16_t free_pages_in_block = 0;
@@ -989,7 +989,7 @@ int spiffs_gc_quick(FAR struct spiffs_s *fs, uint16_t max_free_pages)
/* Check each object lookup page */ /* Check each object lookup page */
while (ret == OK && while (ret >= 0 &&
obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs))
{ {
int entry_offset = obj_lookup_page * entries_per_page; int entry_offset = obj_lookup_page * entries_per_page;
@@ -1001,7 +1001,7 @@ int spiffs_gc_quick(FAR struct spiffs_s *fs, uint16_t max_free_pages)
/* Check each entry */ /* Check each entry */
while (ret == OK && while (ret >= 0 &&
cur_entry - entry_offset < entries_per_page && cur_entry - entry_offset < entries_per_page &&
cur_entry < cur_entry <
(int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) - (int)(SPIFFS_GEO_PAGES_PER_BLOCK(fs) -
@@ -1045,7 +1045,7 @@ int spiffs_gc_quick(FAR struct spiffs_s *fs, uint16_t max_free_pages)
ret = OK; ret = OK;
} }
if (ret == OK && if (ret >= 0 &&
deleted_pages_in_block + free_pages_in_block == deleted_pages_in_block + free_pages_in_block ==
SPIFFS_GEO_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) && SPIFFS_GEO_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) &&
free_pages_in_block <= max_free_pages) free_pages_in_block <= max_free_pages)
@@ -1062,7 +1062,7 @@ int spiffs_gc_quick(FAR struct spiffs_s *fs, uint16_t max_free_pages)
cur_block_addr += SPIFFS_GEO_BLOCK_SIZE(fs); cur_block_addr += SPIFFS_GEO_BLOCK_SIZE(fs);
} }
if (ret == OK) if (ret >= 0)
{ {
/* No deleted blocks */ /* No deleted blocks */
+63 -46
View File
@@ -89,7 +89,9 @@ ssize_t spiffs_mtd_write(FAR struct spiffs_s *fs, off_t offset, size_t len,
off_t blkstart; off_t blkstart;
off_t blkend; off_t blkend;
DEBUGASSERT(fs != NULL && fs->mtd != NULL && src != NULL); DEBUGASSERT(fs != NULL && fs->mtd != NULL && src != NULL && len > 0);
remaining = len;
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
/* Try to do the byte write */ /* Try to do the byte write */
@@ -105,14 +107,14 @@ ssize_t spiffs_mtd_write(FAR struct spiffs_s *fs, off_t offset, size_t len,
* blkmask - Mask that isolates fractional block bytes. * blkmask - Mask that isolates fractional block bytes.
* blkoffset - The offset of data in the first block written * blkoffset - The offset of data in the first block written
* blkstart - Start block number (aligned down) * blkstart - Start block number (aligned down)
* blkend - End block number (aligned up) * blkend - End block number (aligned down)
*/ */
blksize = fs->geo.blocksize; blksize = fs->geo.blocksize;
blkmask = blksize - 1; blkmask = blksize - 1;
blkoffset = blksize & ~blkmask; blkoffset = offset & blkmask;
blkstart = offset / blksize; blkstart = offset / blksize;
blkend = (offset + len + blkmask) / blksize; blkend = (offset + len) / blksize;
/* Check if we have to do a read-modify-write on the first block. We /* Check if we have to do a read-modify-write on the first block. We
* need to do this if the blkoffset is not zero. In that case we need * need to do this if the blkoffset is not zero. In that case we need
@@ -159,23 +161,20 @@ ssize_t spiffs_mtd_write(FAR struct spiffs_s *fs, off_t offset, size_t len,
/* Write all intervening complete blocks... all at once */ /* Write all intervening complete blocks... all at once */
nblocks = blkend - blkstart; nblocks = blkend - blkstart + 1;
if (nblocks > 0)
if ((remaining & blkmask) == 0)
{ {
nblocks++; /* Include the final block */ ret = MTD_BWRITE(fs->mtd, blkstart, nblocks, src);
} if (ret < 0)
{
ferr("ERROR: MTD_BWRITE() failed: %d\n", ret);
return (ssize_t)ret;
}
ret = MTD_BWRITE(fs->mtd, blkstart, nblocks, src); src += (remaining & ~blkmask);
if (ret < 0) remaining = (remaining & blkmask);
{
ferr("ERROR: MTD_BWRITE() failed: %d\n", ret);
return (ssize_t)ret;
} }
src += (remaining & ~blkmask);
remaining = (remaining & blkmask);
/* Check if we need to perform a read-modify-write on the final block. /* Check if we need to perform a read-modify-write on the final block.
* If the remaining bytes to write is less then a full block, then we * If the remaining bytes to write is less then a full block, then we
* need write only the data at the beginning of the block. * need write only the data at the beginning of the block.
@@ -183,6 +182,10 @@ ssize_t spiffs_mtd_write(FAR struct spiffs_s *fs, off_t offset, size_t len,
if (remaining > 0) if (remaining > 0)
{ {
/* The real end block is the next block */
blkend++;
#warning "REVISIT: is fs->work available here?" #warning "REVISIT: is fs->work available here?"
ret = MTD_BREAD(fs->mtd, blkend, 1, fs->work); ret = MTD_BREAD(fs->mtd, blkend, 1, fs->work);
if (ret < 0) if (ret < 0)
@@ -239,7 +242,9 @@ ssize_t spiffs_mtd_read(FAR struct spiffs_s *fs, off_t offset, size_t len,
off_t blkstart; off_t blkstart;
off_t blkend; off_t blkend;
DEBUGASSERT(fs != NULL && fs->mtd != NULL && dest != NULL); DEBUGASSERT(fs != NULL && fs->mtd != NULL && dest != NULL && len > 0);
remaining = len;
/* Try to do the byte read */ /* Try to do the byte read */
@@ -253,14 +258,14 @@ ssize_t spiffs_mtd_read(FAR struct spiffs_s *fs, off_t offset, size_t len,
* blkmask - Mask that isolates fractional block bytes. * blkmask - Mask that isolates fractional block bytes.
* blkoffset - The offset of data in the first block read. * blkoffset - The offset of data in the first block read.
* blkstart - Start block number (aligned down) * blkstart - Start block number (aligned down)
* blkend - End block number (aligned up) * blkend - End block number (aligned down)
*/ */
blksize = fs->geo.blocksize; blksize = fs->geo.blocksize;
blkmask = blksize - 1; blkmask = blksize - 1;
blkoffset = blksize & ~blkmask; blkoffset = offset & blkmask;
blkstart = offset / blksize; blkstart = offset / blksize;
blkend = (offset + len + blkmask) / blksize; blkend = (offset + len) / blksize;
/* Check if we have to do a partial read on the first block. We /* Check if we have to do a partial read on the first block. We
* need to do this if the blkoffset is not zero. In that case we need * need to do this if the blkoffset is not zero. In that case we need
@@ -298,23 +303,20 @@ ssize_t spiffs_mtd_read(FAR struct spiffs_s *fs, off_t offset, size_t len,
/* Read all intervening complete blocks... all at once */ /* Read all intervening complete blocks... all at once */
nblocks = blkend - blkstart; nblocks = blkend - blkstart + 1;
if (nblocks > 0)
if ((remaining & blkmask) == 0)
{ {
nblocks++; /* Include the final block */ ret = MTD_BREAD(fs->mtd, blkstart, nblocks, dest);
} if (ret < 0)
{
ferr("ERROR: MTD_BREAD() failed: %d\n", ret);
return (ssize_t)ret;
}
ret = MTD_BREAD(fs->mtd, blkstart, nblocks, dest); dest += (remaining & ~blkmask);
if (ret < 0) remaining = (remaining & blkmask);
{
ferr("ERROR: MTD_BREAD() failed: %d\n", ret);
return (ssize_t)ret;
} }
dest += (remaining & ~blkmask);
remaining = (remaining & blkmask);
/* Check if we need to perform a partial read on the final block. /* Check if we need to perform a partial read on the final block.
* If the remaining bytes to write is less then a full block, then we * If the remaining bytes to write is less then a full block, then we
* need write only the data at the beginning of the block. * need write only the data at the beginning of the block.
@@ -323,7 +325,7 @@ ssize_t spiffs_mtd_read(FAR struct spiffs_s *fs, off_t offset, size_t len,
if (remaining > 0) if (remaining > 0)
{ {
#warning "REVISIT: is fs->work available here?" #warning "REVISIT: is fs->work available here?"
ret = MTD_BREAD(fs->mtd, blkend, 1, fs->work); ret = MTD_BREAD(fs->mtd, blkend + 1, 1, fs->work);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: MTD_BREAD() failed: %d\n", ret); ferr("ERROR: MTD_BREAD() failed: %d\n", ret);
@@ -347,7 +349,7 @@ ssize_t spiffs_mtd_read(FAR struct spiffs_s *fs, off_t offset, size_t len,
* *
* Input Parameters: * Input Parameters:
* fs - A reference to the volume structure * fs - A reference to the volume structure
* offset - The physical offset to begin erasing * offset - The byte offset to begin erasing
* len - The number of bytes to erase * len - The number of bytes to erase
* *
* Returned Value: * Returned Value:
@@ -358,20 +360,35 @@ ssize_t spiffs_mtd_read(FAR struct spiffs_s *fs, off_t offset, size_t len,
ssize_t spiffs_mtd_erase(FAR struct spiffs_s *fs, off_t offset, size_t len) ssize_t spiffs_mtd_erase(FAR struct spiffs_s *fs, off_t offset, size_t len)
{ {
int16_t blksize; int16_t erasesize;
off_t blkstart; off_t eblkstart;
off_t blkend; off_t eblkend;
ssize_t nerased;
DEBUGASSERT(fs != NULL && fs->mtd != NULL); DEBUGASSERT(fs != NULL && fs->mtd != NULL);
#warning REVISIT: What are units of offset and len? /* We will have to do block read(s)
*
* erasesize - Size of one erase block.
* eblkstart - Start erase block number (aligned down)
* eblkend - End block number (aligned down)
*/
blksize = fs->geo.erasesize; erasesize = fs->geo.erasesize;
DEBUGASSERT(offset = offset % blksize); eblkstart = offset / erasesize;
DEBUGASSERT(len = len % blksize); eblkend = (offset + len) / erasesize;
blkstart = offset / blksize; /* Truncates to floor */ /* Must be even multiples of the erase block size */
blkend = (offset + len + blksize - 1) / blksize; /* Rounds up to ceil */
return MTD_ERASE(fs->mtd, blkstart, blkend - blkstart); DEBUGASSERT(offset == erasesize * eblkstart);
DEBUGASSERT(len == erasesize * eblkend - offset);
nerased = MTD_ERASE(fs->mtd, eblkstart, eblkend - eblkstart);
if (nerased < 0)
{
ferr("ERROR: MTD_ERASE() failed: %d\n");
return nerased;
}
return erasesize * nerased;
} }
+17 -11
View File
@@ -194,7 +194,7 @@ static void spiffs_lock_reentrant(FAR struct spiffs_sem_s *rsem)
* was awakened by a signal. * was awakened by a signal.
*/ */
DEBUGASSERT(ret == OK || ret == -EINTR); DEBUGASSERT(ret >= 0 || ret == -EINTR);
} }
while (ret == -EINTR); while (ret == -EINTR);
@@ -245,7 +245,7 @@ static int spiffs_consistency_check(FAR struct spiffs_s *fs)
if (status < 0) if (status < 0)
{ {
fwarn("WARNING spiffs_check_luconsistency failed: %d\n", status); fwarn("WARNING spiffs_check_luconsistency failed: %d\n", status);
if (ret == OK) if (ret >= 0)
{ {
ret = status; ret = status;
} }
@@ -255,7 +255,7 @@ static int spiffs_consistency_check(FAR struct spiffs_s *fs)
if (status < 0) if (status < 0)
{ {
fwarn("WARNING spiffs_check_objidconsistency failed: %d\n", status); fwarn("WARNING spiffs_check_objidconsistency failed: %d\n", status);
if (ret == OK) if (ret >= 0)
{ {
ret = status; ret = status;
} }
@@ -265,7 +265,7 @@ static int spiffs_consistency_check(FAR struct spiffs_s *fs)
if (status < 0) if (status < 0)
{ {
fwarn("WARNING spiffs_check_pgconsistency failed: %d\n", status); fwarn("WARNING spiffs_check_pgconsistency failed: %d\n", status);
if (ret == OK) if (ret >= 0)
{ {
ret = status; ret = status;
} }
@@ -275,7 +275,7 @@ static int spiffs_consistency_check(FAR struct spiffs_s *fs)
if (status < 0) if (status < 0)
{ {
fwarn("WARNING spiffs_objlu_scan failed: %d\n", status); fwarn("WARNING spiffs_objlu_scan failed: %d\n", status);
if (ret == OK) if (ret >= 0)
{ {
ret = status; ret = status;
} }
@@ -378,6 +378,7 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
fobj = (FAR struct spiffs_file_s *)kmm_zalloc(sizeof(struct spiffs_file_s)); fobj = (FAR struct spiffs_file_s *)kmm_zalloc(sizeof(struct spiffs_file_s));
if (fobj == NULL) if (fobj == NULL)
{ {
ferr("ERROR: Failed to allocate fail object\n");
return -ENOMEM; return -ENOMEM;
} }
@@ -389,19 +390,19 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
/* Check of the file object already exists */ /* Check of the file object already exists */
ret = spiffs_find_objhdr_pgndx(fs, ret = spiffs_find_objhdr_pgndx(fs, (FAR const uint8_t *)relpath, &pgndx);
(FAR const uint8_t *)relpath,
&pgndx);
if (ret < 0 && (oflags & O_CREAT) == 0) if (ret < 0 && (oflags & O_CREAT) == 0)
{ {
/* It does not exist and we were not asked to create it */ /* It does not exist and we were not asked to create it */
fwarn("WARNING: File does not exist a O_CREAT not set\n");
goto errout_with_fileobject; goto errout_with_fileobject;
} }
else if (ret == OK && (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) else if (ret >= 0 && (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
{ {
/* O_CREAT and O_EXCL and file exists - fail */ /* O_CREAT and O_EXCL and file exists - fail */
fwarn("WARNING: File exists and O_CREAT|O_EXCL is selected\n");
ret = -EEXIST; ret = -EEXIST;
goto errout_with_fileobject; goto errout_with_fileobject;
} }
@@ -414,6 +415,7 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
ret = spiffs_objlu_find_free_objid(fs, &objid, 0); ret = spiffs_objlu_find_free_objid(fs, &objid, 0);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_objlu_find_free_objid() failed: %d\n", ret);
goto errout_with_fileobject; goto errout_with_fileobject;
} }
@@ -421,6 +423,7 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
DTYPE_FILE, &pgndx); DTYPE_FILE, &pgndx);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_object_create() failed: %d\n", ret);
goto errout_with_fileobject; goto errout_with_fileobject;
} }
@@ -430,6 +433,7 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
} }
else if (ret < 0) else if (ret < 0)
{ {
ferr("ERROR: spiffs_find_objhdr_pgndx() failed: %d\n", ret);
goto errout_with_fileobject; goto errout_with_fileobject;
} }
@@ -438,6 +442,7 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
ret = spiffs_object_open_bypage(fs, pgndx, fobj, oflags, mode); ret = spiffs_object_open_bypage(fs, pgndx, fobj, oflags, mode);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_object_open_bypage() failed: %d\n", ret);
goto errout_with_fileobject; goto errout_with_fileobject;
} }
@@ -448,6 +453,7 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
ret = spiffs_object_truncate(fs, fobj, 0, false); ret = spiffs_object_truncate(fs, fobj, 0, false);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: spiffs_object_truncate() failed: %d\n", ret);
goto errout_with_fileobject; goto errout_with_fileobject;
} }
} }
@@ -1242,7 +1248,7 @@ static int spiffs_readdir(FAR struct inode *mountpt,
ret = spiffs_foreach_objlu(fs, dir->u.spiffs.block, dir->u.spiffs.entry, ret = spiffs_foreach_objlu(fs, dir->u.spiffs.block, dir->u.spiffs.entry,
SPIFFS_VIS_NO_WRAP, 0, spiffs_readdir_callback, SPIFFS_VIS_NO_WRAP, 0, spiffs_readdir_callback,
NULL, dir, &blkndx, &entry); NULL, dir, &blkndx, &entry);
if (ret == OK) if (ret >= 0)
{ {
dir->u.spiffs.block = blkndx; dir->u.spiffs.block = blkndx;
dir->u.spiffs.entry = entry + 1; dir->u.spiffs.entry = entry + 1;
@@ -1725,7 +1731,7 @@ static int spiffs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath,
{ {
ret = OK; ret = OK;
} }
else if (ret == OK) else if (ret >= 0)
{ {
ret = -EEXIST; ret = -EEXIST;
} }