fs/spiffs: fs/spiffs: Fix several bugs: (1) Fix bad statfs return values. (2) Fix an error in spiffs_unlink(). Fix an in error detection logic when closing a file.

This commit is contained in:
Gregory Nutt 2018-09-27 19:29:00 -06:00
parent 2d2dd5e9e3
commit 2ca8c6682c
5 changed files with 32 additions and 30 deletions

View File

@ -142,8 +142,8 @@ struct spiffs_s
int lu_entry; /* Cursor when searching, entry index */
uint32_t total_pages; /* Total number of pages on the media */
uint32_t free_blocks; /* Current number of free blocks */
uint32_t stats_p_allocated; /* Current number of busy pages */
uint32_t stats_p_deleted; /* Current number of deleted pages */
uint32_t alloc_pages; /* Current number of busy pages */
uint32_t deleted_pages; /* Current number of deleted pages */
#ifdef CONFIG_SPIFFS_GCDBG
uint32_t stats_gc_runs;
#endif

View File

@ -223,11 +223,11 @@ static int spiffs_objlu_scan_callback(FAR struct spiffs_s *fs, int16_t objid,
}
else if (objid == SPIFFS_OBJID_DELETED)
{
fs->stats_p_deleted++;
fs->deleted_pages++;
}
else
{
fs->stats_p_allocated++;
fs->alloc_pages++;
}
return SPIFFS_VIS_COUNTINUE;
@ -851,8 +851,8 @@ int spiffs_objlu_scan(FAR struct spiffs_s *fs)
/* Count blocks */
fs->free_blocks = 0;
fs->stats_p_allocated = 0;
fs->stats_p_deleted = 0;
fs->alloc_pages = 0;
fs->deleted_pages = 0;
ret = spiffs_foreach_objlu(fs, 0, 0, 0, 0, spiffs_objlu_scan_callback,
0, 0, &blkndx, &entry);
@ -1082,7 +1082,7 @@ int spiffs_page_allocate_data(FAR struct spiffs_s *fs, int16_t objid,
return ret;
}
fs->stats_p_allocated++;
fs->alloc_pages++;
/* Write page header */
@ -1225,7 +1225,7 @@ int spiffs_page_move(FAR struct spiffs_s *fs,
return ret;
}
fs->stats_p_allocated++;
fs->alloc_pages++;
if (was_final)
{
@ -1276,8 +1276,8 @@ int spiffs_page_delete(FAR struct spiffs_s *fs, int16_t pgndx)
return ret;
}
fs->stats_p_deleted++;
fs->stats_p_allocated--;
fs->deleted_pages++;
fs->alloc_pages--;
/* Mark deleted in source page */
@ -1363,7 +1363,7 @@ int spiffs_object_create(FAR struct spiffs_s *fs,
return ret;
}
fs->stats_p_allocated++;
fs->alloc_pages++;
/* Write empty object index page */

View File

@ -205,8 +205,8 @@ static int spiffs_gc_epage_stats(FAR struct spiffs_s *fs, int16_t blkndx)
spiffs_gcinfo("Wipe pallo=%d pdele=%d\n", allo, dele);
fs->stats_p_allocated -= allo;
fs->stats_p_deleted -= dele;
fs->alloc_pages -= allo;
fs->deleted_pages -= dele;
return ret;
}
@ -1052,7 +1052,7 @@ int spiffs_gc_quick(FAR struct spiffs_s *fs, uint16_t max_free_pages)
{
/* Found a fully deleted block */
fs->stats_p_deleted -= deleted_pages_in_block;
fs->deleted_pages -= deleted_pages_in_block;
ret = spiffs_gc_erase_block(fs, cur_block);
return ret;
}
@ -1112,10 +1112,10 @@ int spiffs_gc_check(FAR struct spiffs_s *fs, off_t len)
free_pages = (SPIFFS_GEO_PAGES_PER_BLOCK(fs) -
SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (SPIFFS_GEO_BLOCK_COUNT(fs) - 2) -
fs->stats_p_allocated - fs->stats_p_deleted;
fs->alloc_pages - fs->deleted_pages;
spiffs_gcinfo("len=%ld free_blocks=%lu\n free_pages=%ld",
(long)len, (unsigned long)fs->free_blocksm,
(long)len, (unsigned long)fs->free_blocks,
(long)free_pages);
if (fs->free_blocks > 3 &&
@ -1135,16 +1135,16 @@ int spiffs_gc_check(FAR struct spiffs_s *fs, off_t len)
{
spiffs_gcinfo("Full freeblk=%d" needed=%d" free=%d dele=%d\n",
fs->free_blocks, needed_pages, free_pages,
fs->stats_p_deleted);
fs->deleted_pages);
return -ENOSPC;
}
#endif
if ((int32_t)needed_pages > (int32_t)(free_pages + fs->stats_p_deleted))
if ((int32_t)needed_pages > (int32_t)(free_pages + fs->deleted_pages))
{
spiffs_gcinfo("Full freeblk=%d needed=%d free=%d dele=%d\n",
fs->free_blocks, needed_pages, free_pages,
fs->stats_p_deleted);
fs->deleted_pages);
return -ENOSPC;
}
@ -1157,8 +1157,8 @@ int spiffs_gc_check(FAR struct spiffs_s *fs, off_t len)
spiffs_gcinfo("#%d: run gc free_blocks=%d pfree=%d pallo=%d pdele=%d [%d] len=%d of %d\n",
tries, fs->free_blocks, free_pages,
fs->stats_p_allocated, fs->stats_p_deleted,
(free_pages + fs->stats_p_allocated + fs->stats_p_deleted),
fs->alloc_pages, fs->deleted_pages,
(free_pages + fs->alloc_pages + fs->deleted_pages),
len, (uint32_t)(free_pages * SPIFFS_DATA_PAGE_SIZE(fs)));
/* If the fs is crammed, ignore block age when selecting candidate - kind
@ -1209,7 +1209,7 @@ int spiffs_gc_check(FAR struct spiffs_s *fs, off_t len)
free_pages = (SPIFFS_GEO_PAGES_PER_BLOCK(fs) -
SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (SPIFFS_GEO_BLOCK_COUNT(fs) - 2) -
fs->stats_p_allocated - fs->stats_p_deleted;
fs->alloc_pages - fs->deleted_pages;
if (prev_free_pages <= 0 && prev_free_pages == free_pages)
{
@ -1228,7 +1228,7 @@ int spiffs_gc_check(FAR struct spiffs_s *fs, off_t len)
free_pages = (SPIFFS_GEO_PAGES_PER_BLOCK(fs) -
SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (SPIFFS_GEO_BLOCK_COUNT(fs) - 2) -
fs->stats_p_allocated - fs->stats_p_deleted;
fs->alloc_pages - fs->deleted_pages;
if ((int32_t) len > free_pages * (int32_t)SPIFFS_DATA_PAGE_SIZE(fs))
{
@ -1237,7 +1237,7 @@ int spiffs_gc_check(FAR struct spiffs_s *fs, off_t len)
spiffs_gcinfo("Finished, %d dirty, blocks, %d free, %d pages free, "
"%d tries, ret=%d\n",
fs->stats_p_allocated + fs->stats_p_deleted,
fs->alloc_pages + fs->deleted_pages,
fs->free_blocks, free_pages, tries, ret);
return ret;

View File

@ -490,6 +490,7 @@ static int spiffs_open(FAR struct file *filep, FAR const char *relpath,
/* Add the new file object to the tail of the open file list */
finfo("Adding fobj for objid=%04x\n", fobj->objid);
dq_addlast((FAR dq_entry_t *)fobj, &fs->objq);
spiffs_unlock_volume(fs);
@ -1515,7 +1516,6 @@ static int spiffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
uint32_t data_pgsize;
uint32_t ndata_pages;
uint32_t nfile_objs;
uint32_t used;
finfo("mountpt=%p buf=%p\n", mountpt, buf);
DEBUGASSERT(mountpt != NULL && buf != NULL);
@ -1539,7 +1539,6 @@ static int spiffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
/* -2 for spare blocks, +1 for emergency page */
ndata_pages = (blocks - 2) * (pages_per_block - obj_lupages) + 1;
used = fs->stats_p_allocated * data_pgsize;
/* Count the number of file objects */
@ -1557,7 +1556,7 @@ static int spiffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
buf->f_namelen = CONFIG_SPIFFS_NAME_MAX - 1;
buf->f_bsize = data_pgsize;
buf->f_blocks = ndata_pages;
buf->f_bfree = ndata_pages - used;
buf->f_bfree = ndata_pages - fs->alloc_pages;
buf->f_bavail = buf->f_bfree;
buf->f_files = nfile_objs;
buf->f_ffree = buf->f_bfree; /* SWAG */
@ -1599,12 +1598,12 @@ static int spiffs_unlink(FAR struct inode *mountpt, FAR const char *relpath)
/* Find the page index to the object header associated with this path */
ret = spiffs_find_objhdr_pgndx(fs, (FAR const uint8_t *)relpath, &pgndx);
if (ret < OK)
if (ret == -ENOENT)
{
fwarn("WARNING: No objhdr found for relpath '%s': %d\n", relpath, ret);
goto errout_with_lock;
}
else if (ret != -ENOENT)
else if (ret < 0)
{
ferr("ERROR: spiffs_find_objhdr_pgndx failed: %d\n", ret);
goto errout_with_lock;

View File

@ -428,6 +428,8 @@ void spiffs_fobj_free(FAR struct spiffs_s *fs, FAR struct spiffs_file_s *fobj)
FAR struct spiffs_file_s *curr;
int ret;
finfo("Removing fobj for objid=%04x\n", fobj->objid);
/* Flush any buffered write data */
ret = spiffs_fflush_cache(fs, fobj);
@ -451,6 +453,7 @@ void spiffs_fobj_free(FAR struct spiffs_s *fs, FAR struct spiffs_file_s *fobj)
/* Yes, remove it from the list of of file objects */
dq_rem((FAR dq_entry_t *)curr, &fs->objq);
break;
}
}