Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
4f1b33d5
Commit
4f1b33d5
authored
Sep 21, 2016
by
Johny Mattsson
Browse files
Grabbed latest spiffs + vfs layer from dev branch.
Also included the recent LVM fix. Platform flash layer not yet functional.
parent
fe602d2d
Changes
24
Show whitespace changes
Inline
Side-by-side
components/spiffs/spiffs_gc.c
View file @
4f1b33d5
#include "spiffs.h"
#include "spiffs_nucleus.h"
#include <string.h>
#if !SPIFFS_READ_ONLY
// Erases a logical block and updates the erase counter.
// If cache is enabled, all pages that might be cached in this block
...
...
@@ -36,7 +39,7 @@ s32_t spiffs_gc_quick(
int
cur_entry
=
0
;
spiffs_obj_id
*
obj_lu_buf
=
(
spiffs_obj_id
*
)
fs
->
lu_work
;
SPIFFS_GC_DBG
(
"gc_quick: running
\n
"
,
cur_block
);
SPIFFS_GC_DBG
(
"gc_quick: running
\n
"
);
#if SPIFFS_GC_STATS
fs
->
stats_gc_runs
++
;
#endif
...
...
@@ -249,14 +252,12 @@ s32_t spiffs_gc_find_candidate(
memset
(
fs
->
work
,
0xff
,
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
));
// divide up work area into block indices and scores
// todo alignment?
// YES DO PROPER ALIGNMENT !^@#%!@%!
if
(
max_candidates
&
1
)
++
max_candidates
;
// HACK WORKAROUND ICK for sizeof(spiffs_block_idx)==2
spiffs_block_ix
*
cand_blocks
=
(
spiffs_block_ix
*
)
fs
->
work
;
s32_t
*
cand_scores
=
(
s32_t
*
)(
fs
->
work
+
max_candidates
*
sizeof
(
spiffs_block_ix
));
// align cand_scores on s32_t boundary
cand_scores
=
(
s32_t
*
)(((
ptrdiff_t
)
cand_scores
+
sizeof
(
ptrdiff_t
)
-
1
)
&
~
(
sizeof
(
ptrdiff_t
)
-
1
));
*
block_candidates
=
cand_blocks
;
int
entries_per_page
=
(
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
)
/
sizeof
(
spiffs_obj_id
));
...
...
@@ -570,3 +571,4 @@ s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) {
return
res
;
}
#endif // !SPIFFS_READ_ONLY
components/spiffs/spiffs_hydrogen.c
View file @
4f1b33d5
...
...
@@ -7,8 +7,19 @@
#include "spiffs.h"
#include "spiffs_nucleus.h"
#include <string.h>
#if SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0)
#define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0)
#else
#define SPIFFS_FH_OFFS(fs, fh) (fh)
#define SPIFFS_FH_UNOFFS(fs, fh) (fh)
#endif
#if SPIFFS_CACHE == 1
static
s32_t
spiffs_fflush_cache
(
spiffs
*
fs
,
spiffs_file
fh
);
#endif
#if SPIFFS_BUFFER_HELP
u32_t
SPIFFS_buffer_bytes_for_filedescs
(
spiffs
*
fs
,
u32_t
num_descs
)
{
...
...
@@ -26,6 +37,10 @@ u8_t SPIFFS_mounted(spiffs *fs) {
}
s32_t
SPIFFS_format
(
spiffs
*
fs
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
SPIFFS_API_CHECK_CFG
(
fs
);
if
(
SPIFFS_CHECK_MOUNT
(
fs
))
{
fs
->
err_code
=
SPIFFS_ERR_MOUNTED
;
...
...
@@ -49,25 +64,35 @@ s32_t SPIFFS_format(spiffs *fs) {
SPIFFS_UNLOCK
(
fs
);
return
0
;
#endif // SPIFFS_READ_ONLY
}
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
s32_t
SPIFFS_probe_fs
(
spiffs_config
*
config
)
{
s32_t
res
=
spiffs_probe
(
config
);
return
res
;
}
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
s32_t
SPIFFS_mount
(
spiffs
*
fs
,
spiffs_config
*
config
,
u8_t
*
work
,
u8_t
*
fd_space
,
u32_t
fd_space_size
,
void
*
cache
,
u32_t
cache_size
,
spiffs_check_callback
check_cb_f
)
{
void
*
user_data
;
SPIFFS_LOCK
(
fs
);
user_data
=
fs
->
user_data
;
memset
(
fs
,
0
,
sizeof
(
spiffs
));
memcpy
(
&
fs
->
cfg
,
config
,
sizeof
(
spiffs_config
));
fs
->
user_data
=
user_data
;
fs
->
block_count
=
SPIFFS_CFG_PHYS_SZ
(
fs
)
/
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
fs
->
work
=
&
work
[
0
];
fs
->
lu_work
=
&
work
[
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
)];
memset
(
fd_space
,
0
,
fd_space_size
);
// align fd_space pointer to pointer size byte boundary
, below is safe
// align fd_space pointer to pointer size byte boundary
u8_t
ptr_size
=
sizeof
(
void
*
);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
u8_t
addr_lsb
=
((
u8_t
)
fd_space
)
&
(
ptr_size
-
1
);
#pragma GCC diagnostic pop
u8_t
addr_lsb
=
((
u8_t
)(
intptr_t
)
fd_space
)
&
(
ptr_size
-
1
);
if
(
addr_lsb
)
{
fd_space
+=
(
ptr_size
-
addr_lsb
);
fd_space_size
-=
(
ptr_size
-
addr_lsb
);
...
...
@@ -75,11 +100,8 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
fs
->
fd_space
=
fd_space
;
fs
->
fd_count
=
(
fd_space_size
/
sizeof
(
spiffs_fd
));
// align cache pointer to 4 byte boundary, below is safe
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
addr_lsb
=
((
u8_t
)
cache
)
&
(
ptr_size
-
1
);
#pragma GCC diagnostic pop
// align cache pointer to 4 byte boundary
addr_lsb
=
((
u8_t
)(
intptr_t
)
cache
)
&
(
ptr_size
-
1
);
if
(
addr_lsb
)
{
u8_t
*
cache_8
=
(
u8_t
*
)
cache
;
cache_8
+=
(
ptr_size
-
addr_lsb
);
...
...
@@ -89,9 +111,10 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
if
(
cache_size
&
(
ptr_size
-
1
))
{
cache_size
-=
(
cache_size
&
(
ptr_size
-
1
));
}
#if SPIFFS_CACHE
fs
->
cache
=
cache
;
fs
->
cache_size
=
(
cache_size
>
(
config
->
log_page_size
*
32
))
?
config
->
log_page_size
*
32
:
cache_size
;
fs
->
cache_size
=
(
cache_size
>
(
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
)
*
32
))
?
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
)
*
32
:
cache_size
;
spiffs_cache_init
(
fs
);
#endif
...
...
@@ -152,43 +175,68 @@ void SPIFFS_clearerr(spiffs *fs) {
fs
->
err_code
=
SPIFFS_OK
;
}
s32_t
SPIFFS_creat
(
spiffs
*
fs
,
char
*
path
,
spiffs_mode
mode
)
{
s32_t
SPIFFS_creat
(
spiffs
*
fs
,
const
char
*
path
,
spiffs_mode
mode
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
(
void
)
path
;
(
void
)
mode
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
(
void
)
mode
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
if
(
strlen
(
path
)
>
SPIFFS_OBJ_NAME_LEN
-
1
)
{
SPIFFS_API_CHECK_RES
(
fs
,
SPIFFS_ERR_NAME_TOO_LONG
);
}
SPIFFS_LOCK
(
fs
);
spiffs_obj_id
obj_id
;
s32_t
res
;
res
=
spiffs_obj_lu_find_free_obj_id
(
fs
,
&
obj_id
,
(
u8_t
*
)
path
);
res
=
spiffs_obj_lu_find_free_obj_id
(
fs
,
&
obj_id
,
(
const
u8_t
*
)
path
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
res
=
spiffs_object_create
(
fs
,
obj_id
,
(
u8_t
*
)
path
,
SPIFFS_TYPE_FILE
,
0
);
res
=
spiffs_object_create
(
fs
,
obj_id
,
(
const
u8_t
*
)
path
,
SPIFFS_TYPE_FILE
,
0
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
return
0
;
#endif // SPIFFS_READ_ONLY
}
spiffs_file
SPIFFS_open
(
spiffs
*
fs
,
char
*
path
,
spiffs_flags
flags
,
spiffs_mode
mode
)
{
spiffs_file
SPIFFS_open
(
spiffs
*
fs
,
const
char
*
path
,
spiffs_flags
flags
,
spiffs_mode
mode
)
{
(
void
)
mode
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
if
(
strlen
(
path
)
>
SPIFFS_OBJ_NAME_LEN
-
1
)
{
SPIFFS_API_CHECK_RES
(
fs
,
SPIFFS_ERR_NAME_TOO_LONG
);
}
SPIFFS_LOCK
(
fs
);
spiffs_fd
*
fd
;
spiffs_page_ix
pix
;
#if SPIFFS_READ_ONLY
// not valid flags in read only mode
flags
&=
~
SPIFFS_WRONLY
|
SPIFFS_CREAT
|
SPIFFS_TRUNC
;
#endif // SPIFFS_READ_ONLY
s32_t
res
=
spiffs_fd_find_new
(
fs
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
u8_t
*
)
path
,
&
pix
);
if
((
flags
&
SPIFFS_CREAT
)
==
0
)
{
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
const
u8_t
*
)
path
,
&
pix
);
if
((
flags
&
SPIFFS_
O_
CREAT
)
==
0
)
{
if
(
res
<
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
if
((
flags
&
SPIFFS_CREAT
)
&&
res
==
SPIFFS_ERR_NOT_FOUND
)
{
if
(
res
==
SPIFFS_OK
&&
(
flags
&
(
SPIFFS_O_CREAT
|
SPIFFS_O_EXCL
))
==
(
SPIFFS_O_CREAT
|
SPIFFS_O_EXCL
))
{
// creat and excl and file exists - fail
res
=
SPIFFS_ERR_FILE_EXISTS
;
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
if
((
flags
&
SPIFFS_O_CREAT
)
&&
res
==
SPIFFS_ERR_NOT_FOUND
)
{
#if !SPIFFS_READ_ONLY
spiffs_obj_id
obj_id
;
// no need to enter conflicting name here, already looked for it above
res
=
spiffs_obj_lu_find_free_obj_id
(
fs
,
&
obj_id
,
0
);
...
...
@@ -196,12 +244,13 @@ spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
res
=
spiffs_object_create
(
fs
,
obj_id
,
(
u8_t
*
)
path
,
SPIFFS_TYPE_FILE
,
&
pix
);
res
=
spiffs_object_create
(
fs
,
obj_id
,
(
const
u8_t
*
)
path
,
SPIFFS_TYPE_FILE
,
&
pix
);
if
(
res
<
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
flags
&=
~
SPIFFS_TRUNC
;
flags
&=
~
SPIFFS_O_TRUNC
;
#endif // !SPIFFS_READ_ONLY
}
else
{
if
(
res
<
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
...
...
@@ -213,19 +262,21 @@ spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
if
(
flags
&
SPIFFS_TRUNC
)
{
#if !SPIFFS_READ_ONLY
if
(
flags
&
SPIFFS_O_TRUNC
)
{
res
=
spiffs_object_truncate
(
fd
,
0
,
0
);
if
(
res
<
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
#endif // !SPIFFS_READ_ONLY
fd
->
fdoffset
=
0
;
SPIFFS_UNLOCK
(
fs
);
return
fd
->
file_nbr
;
return
SPIFFS_FH_OFFS
(
fs
,
fd
->
file_nbr
)
;
}
spiffs_file
SPIFFS_open_by_dirent
(
spiffs
*
fs
,
struct
spiffs_dirent
*
e
,
spiffs_flags
flags
,
spiffs_mode
mode
)
{
...
...
@@ -243,19 +294,67 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
if
(
flags
&
SPIFFS_TRUNC
)
{
#if !SPIFFS_READ_ONLY
if
(
flags
&
SPIFFS_O_TRUNC
)
{
res
=
spiffs_object_truncate
(
fd
,
0
,
0
);
if
(
res
<
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
#endif // !SPIFFS_READ_ONLY
fd
->
fdoffset
=
0
;
SPIFFS_UNLOCK
(
fs
);
return
fd
->
file_nbr
;
return
SPIFFS_FH_OFFS
(
fs
,
fd
->
file_nbr
);
}
spiffs_file
SPIFFS_open_by_page
(
spiffs
*
fs
,
spiffs_page_ix
page_ix
,
spiffs_flags
flags
,
spiffs_mode
mode
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
spiffs_fd
*
fd
;
s32_t
res
=
spiffs_fd_find_new
(
fs
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
if
(
SPIFFS_IS_LOOKUP_PAGE
(
fs
,
page_ix
))
{
res
=
SPIFFS_ERR_NOT_A_FILE
;
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
res
=
spiffs_object_open_by_page
(
fs
,
page_ix
,
fd
,
flags
,
mode
);
if
(
res
==
SPIFFS_ERR_IS_FREE
||
res
==
SPIFFS_ERR_DELETED
||
res
==
SPIFFS_ERR_NOT_FINALIZED
||
res
==
SPIFFS_ERR_NOT_INDEX
||
res
==
SPIFFS_ERR_INDEX_SPAN_MISMATCH
)
{
res
=
SPIFFS_ERR_NOT_A_FILE
;
}
if
(
res
<
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
#if !SPIFFS_READ_ONLY
if
(
flags
&
SPIFFS_O_TRUNC
)
{
res
=
spiffs_object_truncate
(
fd
,
0
,
0
);
if
(
res
<
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
#endif // !SPIFFS_READ_ONLY
fd
->
fdoffset
=
0
;
SPIFFS_UNLOCK
(
fs
);
return
SPIFFS_FH_OFFS
(
fs
,
fd
->
file_nbr
);
}
s32_t
SPIFFS_read
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
s32_t
len
)
{
...
...
@@ -266,14 +365,21 @@ s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
spiffs_fd
*
fd
;
s32_t
res
;
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
if
((
fd
->
flags
&
SPIFFS_RDONLY
)
==
0
)
{
if
((
fd
->
flags
&
SPIFFS_
O_
RDONLY
)
==
0
)
{
res
=
SPIFFS_ERR_NOT_READABLE
;
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
if
(
fd
->
size
==
SPIFFS_UNDEFINED_LEN
&&
len
>
0
)
{
// special case for zero sized files
res
=
SPIFFS_ERR_END_OF_OBJECT
;
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
#if SPIFFS_CACHE_WR
spiffs_fflush_cache
(
fs
,
fh
);
#endif
...
...
@@ -305,6 +411,7 @@ s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
return
len
;
}
#if !SPIFFS_READ_ONLY
static
s32_t
spiffs_hydro_write
(
spiffs
*
fs
,
spiffs_fd
*
fd
,
void
*
buf
,
u32_t
offset
,
s32_t
len
)
{
(
void
)
fs
;
s32_t
res
=
SPIFFS_OK
;
...
...
@@ -326,8 +433,13 @@ static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offs
return
len
;
}
#endif // !SPIFFS_READ_ONLY
s32_t
SPIFFS_write
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
s32_t
len
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
(
void
)
fh
;
(
void
)
buf
;
(
void
)
len
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -336,14 +448,19 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
s32_t
res
;
u32_t
offset
;
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
if
((
fd
->
flags
&
SPIFFS_WRONLY
)
==
0
)
{
if
((
fd
->
flags
&
SPIFFS_
O_
WRONLY
)
==
0
)
{
res
=
SPIFFS_ERR_NOT_WRITABLE
;
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
if
((
fd
->
flags
&
SPIFFS_O_APPEND
))
{
fd
->
fdoffset
=
fd
->
size
==
SPIFFS_UNDEFINED_LEN
?
0
:
fd
->
size
;
}
offset
=
fd
->
fdoffset
;
#if SPIFFS_CACHE_WR
...
...
@@ -352,7 +469,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
fd
->
cache_page
=
spiffs_cache_page_get_by_fd
(
fs
,
fd
);
}
#endif
if
(
fd
->
flags
&
SPIFFS_APPEND
)
{
if
(
fd
->
flags
&
SPIFFS_
O_
APPEND
)
{
if
(
fd
->
size
==
SPIFFS_UNDEFINED_LEN
)
{
offset
=
0
;
}
else
{
...
...
@@ -366,7 +483,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
}
#if SPIFFS_CACHE_WR
if
((
fd
->
flags
&
SPIFFS_DIRECT
)
==
0
)
{
if
((
fd
->
flags
&
SPIFFS_
O_
DIRECT
)
==
0
)
{
if
(
len
<
(
s32_t
)
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
))
{
// small write, try to cache it
u8_t
alloc_cpage
=
1
;
...
...
@@ -383,7 +500,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
spiffs_get_cache_page
(
fs
,
spiffs_get_cache
(
fs
),
fd
->
cache_page
->
ix
),
fd
->
cache_page
->
offset
,
fd
->
cache_page
->
size
);
spiffs_cache_fd_release
(
fs
,
fd
->
cache_page
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
SPIFFS_API_CHECK_RES
_UNLOCK
(
fs
,
res
);
}
else
{
// writing within cache
alloc_cpage
=
0
;
...
...
@@ -414,7 +531,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
return
len
;
}
else
{
res
=
spiffs_hydro_write
(
fs
,
fd
,
buf
,
offset
,
len
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
SPIFFS_API_CHECK_RES
_UNLOCK
(
fs
,
res
);
fd
->
fdoffset
+=
len
;
SPIFFS_UNLOCK
(
fs
);
return
res
;
...
...
@@ -429,21 +546,22 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
spiffs_get_cache_page
(
fs
,
spiffs_get_cache
(
fs
),
fd
->
cache_page
->
ix
),
fd
->
cache_page
->
offset
,
fd
->
cache_page
->
size
);
spiffs_cache_fd_release
(
fs
,
fd
->
cache_page
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
SPIFFS_API_CHECK_RES
_UNLOCK
(
fs
,
res
);
res
=
spiffs_hydro_write
(
fs
,
fd
,
buf
,
offset
,
len
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
SPIFFS_API_CHECK_RES
_UNLOCK
(
fs
,
res
);
}
}
}
#endif
res
=
spiffs_hydro_write
(
fs
,
fd
,
buf
,
offset
,
len
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
SPIFFS_API_CHECK_RES
_UNLOCK
(
fs
,
res
);
fd
->
fdoffset
+=
len
;
SPIFFS_UNLOCK
(
fs
);
return
res
;
#endif // SPIFFS_READ_ONLY
}
s32_t
SPIFFS_lseek
(
spiffs
*
fs
,
spiffs_file
fh
,
s32_t
offs
,
int
whence
)
{
...
...
@@ -453,8 +571,9 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
spiffs_fd
*
fd
;
s32_t
res
;
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
SPIFFS_API_CHECK_RES
_UNLOCK
(
fs
,
res
);
#if SPIFFS_CACHE_WR
spiffs_fflush_cache
(
fs
,
fh
);
...
...
@@ -469,7 +588,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
break
;
}
if
(
offs
>
(
s32_t
)
fd
->
size
)
{
if
(
(
offs
>
(
s32_t
)
fd
->
size
)
&&
(
SPIFFS_UNDEFINED_LEN
!=
fd
->
size
))
{
res
=
SPIFFS_ERR_END_OF_OBJECT
;
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
...
...
@@ -491,9 +610,16 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
return
offs
;
}
s32_t
SPIFFS_remove
(
spiffs
*
fs
,
char
*
path
)
{
s32_t
SPIFFS_remove
(
spiffs
*
fs
,
const
char
*
path
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
(
void
)
path
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
if
(
strlen
(
path
)
>
SPIFFS_OBJ_NAME_LEN
-
1
)
{
SPIFFS_API_CHECK_RES
(
fs
,
SPIFFS_ERR_NAME_TOO_LONG
);
}
SPIFFS_LOCK
(
fs
);
spiffs_fd
*
fd
;
...
...
@@ -503,7 +629,7 @@ s32_t SPIFFS_remove(spiffs *fs, char *path) {
res
=
spiffs_fd_find_new
(
fs
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
u8_t
*
)
path
,
&
pix
);
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
const
u8_t
*
)
path
,
&
pix
);
if
(
res
!=
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
...
...
@@ -523,19 +649,25 @@ s32_t SPIFFS_remove(spiffs *fs, char *path) {
SPIFFS_UNLOCK
(
fs
);
return
0
;
#endif // SPIFFS_READ_ONLY
}
s32_t
SPIFFS_fremove
(
spiffs
*
fs
,
spiffs_file
fh
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
(
void
)
fh
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
spiffs_fd
*
fd
;
s32_t
res
;
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
if
((
fd
->
flags
&
SPIFFS_WRONLY
)
==
0
)
{
if
((
fd
->
flags
&
SPIFFS_
O_
WRONLY
)
==
0
)
{
res
=
SPIFFS_ERR_NOT_WRITABLE
;
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
}
...
...
@@ -551,9 +683,11 @@ s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) {
SPIFFS_UNLOCK
(
fs
);
return
0
;
#endif // SPIFFS_READ_ONLY
}
static
s32_t
spiffs_stat_pix
(
spiffs
*
fs
,
spiffs_page_ix
pix
,
spiffs_file
fh
,
spiffs_stat
*
s
)
{
(
void
)
fh
;
spiffs_page_object_ix_header
objix_hdr
;
spiffs_obj_id
obj_id
;
s32_t
res
=
_spiffs_rd
(
fs
,
SPIFFS_OP_T_OBJ_IX
|
SPIFFS_OP_C_READ
,
fh
,
...
...
@@ -566,23 +700,27 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi
obj_id_addr
,
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
obj_id
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
s
->
obj_id
=
obj_id
;
s
->
obj_id
=
obj_id
&
~
SPIFFS_OBJ_ID_IX_FLAG
;
s
->
type
=
objix_hdr
.
type
;
s
->
size
=
objix_hdr
.
size
==
SPIFFS_UNDEFINED_LEN
?
0
:
objix_hdr
.
size
;
s
->
pix
=
pix
;
strncpy
((
char
*
)
s
->
name
,
(
char
*
)
objix_hdr
.
name
,
SPIFFS_OBJ_NAME_LEN
);
return
res
;
}
s32_t
SPIFFS_stat
(
spiffs
*
fs
,
char
*
path
,
spiffs_stat
*
s
)
{
s32_t
SPIFFS_stat
(
spiffs
*
fs
,
const
char
*
path
,
spiffs_stat
*
s
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
if
(
strlen
(
path
)
>
SPIFFS_OBJ_NAME_LEN
-
1
)
{
SPIFFS_API_CHECK_RES
(
fs
,
SPIFFS_ERR_NAME_TOO_LONG
);
}
SPIFFS_LOCK
(
fs
);
s32_t
res
;
spiffs_page_ix
pix
;
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
u8_t
*
)
path
,
&
pix
);
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
const
u8_t
*
)
path
,
&
pix
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
res
=
spiffs_stat_pix
(
fs
,
pix
,
0
,
s
);
...
...
@@ -600,6 +738,7 @@ s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) {
spiffs_fd
*
fd
;
s32_t
res
;
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
...
...
@@ -616,15 +755,18 @@ s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) {
// Checks if there are any cached writes for the object id associated with
// given filehandle. If so, these writes are flushed.
#if SPIFFS_CACHE == 1
static
s32_t
spiffs_fflush_cache
(
spiffs
*
fs
,
spiffs_file
fh
)
{
(
void
)
fs
;
(
void
)
fh
;
s32_t
res
=
SPIFFS_OK
;
#if SPIFFS_CACHE_WR
#if
!SPIFFS_READ_ONLY &&
SPIFFS_CACHE_WR
spiffs_fd
*
fd
;
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
if
((
fd
->
flags
&
SPIFFS_DIRECT
)
==
0
)
{
if
((
fd
->
flags
&
SPIFFS_
O_
DIRECT
)
==
0
)
{
if
(
fd
->
cache_page
==
0
)
{
// see if object id is associated with cache already
fd
->
cache_page
=
spiffs_cache_page_get_by_fd
(
fs
,
fd
);
...
...
@@ -645,13 +787,16 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
return
res
;
}
#endif
s32_t
SPIFFS_fflush
(
spiffs
*
fs
,
spiffs_file
fh
)
{
(
void
)
fh
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
s32_t
res
=
SPIFFS_OK
;
#if SPIFFS_CACHE_WR
#if
!SPIFFS_READ_ONLY &&
SPIFFS_CACHE_WR
SPIFFS_LOCK
(
fs
);
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
res
=
spiffs_fflush_cache
(
fs
,
fh
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
...
...
@@ -660,38 +805,46 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
return
res
;
}
void
SPIFFS_close
(
spiffs
*
fs
,
spiffs_file
fh
)
{
if
(
!
SPIFFS_CHECK_CFG
((
fs
)))
{
(
fs
)
->
err_code
=
SPIFFS_ERR_NOT_CONFIGURED
;
return
;
}
s32_t
SPIFFS_close
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
{
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
return
;
}
s32_t
res
=
SPIFFS_OK
;
SPIFFS_LOCK
(
fs
);
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
#if SPIFFS_CACHE
spiffs_fflush_cache
(
fs
,
fh
);
res
=
spiffs_fflush_cache
(
fs
,
fh
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
#endif
spiffs_fd_return
(
fs
,
fh
);
res
=
spiffs_fd_return
(
fs
,
fh
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
return
res
;
}
s32_t
SPIFFS_rename
(
spiffs
*
fs
,
char
*
old
,
char
*
new
)
{
s32_t
SPIFFS_rename
(
spiffs
*
fs
,
const
char
*
old_path
,
const
char
*
new_path
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
(
void
)
old_path
;
(
void
)
new_path
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
if
(
strlen
(
new_path
)
>
SPIFFS_OBJ_NAME_LEN
-
1
||
strlen
(
old_path
)
>
SPIFFS_OBJ_NAME_LEN
-
1
)
{
SPIFFS_API_CHECK_RES
(
fs
,
SPIFFS_ERR_NAME_TOO_LONG
);
}
SPIFFS_LOCK
(
fs
);
spiffs_page_ix
pix_old
,
pix_dummy
;
spiffs_fd
*
fd
;
s32_t
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
u8_t
*
)
old
,
&
pix_old
);
s32_t
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
const
u8_t
*
)
old
_path
,
&
pix_old
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
u8_t
*
)
new
,
&
pix_dummy
);
res
=
spiffs_object_find_object_index_header_by_name
(
fs
,
(
const
u8_t
*
)
new
_path
,
&
pix_dummy
);
if
(
res
==
SPIFFS_ERR_NOT_FOUND
)
{
res
=
SPIFFS_OK
;
}
else
if
(
res
==
SPIFFS_OK
)
{
...
...
@@ -708,7 +861,7 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
res
=
spiffs_object_update_index_hdr
(
fs
,
fd
,
fd
->
obj_id
,
fd
->
objix_hdr_pix
,
0
,
(
u8_t
*
)
new
,
res
=
spiffs_object_update_index_hdr
(
fs
,
fd
,
fd
->
obj_id
,
fd
->
objix_hdr_pix
,
0
,
(
const
u8_t
*
)
new
_path
,
0
,
&
pix_dummy
);
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
...
...
@@ -718,9 +871,10 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
SPIFFS_UNLOCK
(
fs
);
return
res
;
#endif // SPIFFS_READ_ONLY
}
spiffs_DIR
*
SPIFFS_opendir
(
spiffs
*
fs
,
char
*
name
,
spiffs_DIR
*
d
)
{
spiffs_DIR
*
SPIFFS_opendir
(
spiffs
*
fs
,
const
char
*
name
,
spiffs_DIR
*
d
)
{
(
void
)
name
;
if
(
!
SPIFFS_CHECK_CFG
((
fs
)))
{
...
...
@@ -744,9 +898,9 @@ static s32_t spiffs_read_dir_v(
spiffs_obj_id
obj_id
,
spiffs_block_ix
bix
,
int
ix_entry
,
u32_t
user_data
,
void
*
user_p
)
{
(
void
)
user_
data
;
const
void
*
user_const_p
,
void
*
user_
var_
p
)
{
(
void
)
user_
const_p
;
s32_t
res
;
spiffs_page_object_ix_header
objix_hdr
;
if
(
obj_id
==
SPIFFS_OBJ_ID_FREE
||
obj_id
==
SPIFFS_OBJ_ID_DELETED
||
...
...
@@ -762,10 +916,9 @@ static s32_t spiffs_read_dir_v(
objix_hdr
.
p_hdr
.
span_ix
==
0
&&
(
objix_hdr
.
p_hdr
.
flags
&
(
SPIFFS_PH_FLAG_DELET
|
SPIFFS_PH_FLAG_FINAL
|
SPIFFS_PH_FLAG_IXDELE
))
==
(
SPIFFS_PH_FLAG_DELET
|
SPIFFS_PH_FLAG_IXDELE
))
{
struct
spiffs_dirent
*
e
=
(
struct
spiffs_dirent
*
)
user_p
;
struct
spiffs_dirent
*
e
=
(
struct
spiffs_dirent
*
)
user_
var_
p
;
e
->
obj_id
=
obj_id
;
strncpy
((
char
*
)
e
->
name
,
(
char
*
)
objix_hdr
.
name
,
SPIFFS_OBJ_NAME_LEN
);
strcpy
((
char
*
)
e
->
name
,
(
char
*
)
objix_hdr
.
name
);
e
->
type
=
objix_hdr
.
type
;
e
->
size
=
objix_hdr
.
size
==
SPIFFS_UNDEFINED_LEN
?
0
:
objix_hdr
.
size
;
e
->
pix
=
pix
;
...
...
@@ -780,7 +933,7 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
d
->
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
return
0
;
}
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
d
->
fs
);
spiffs_block_ix
bix
;
int
entry
;
...
...
@@ -804,7 +957,7 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
}
else
{
d
->
fs
->
err_code
=
res
;
}
SPIFFS_UNLOCK
(
fs
);
SPIFFS_UNLOCK
(
d
->
fs
);
return
ret
;
}
...
...
@@ -815,6 +968,10 @@ s32_t SPIFFS_closedir(spiffs_DIR *d) {
}
s32_t
SPIFFS_check
(
spiffs
*
fs
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
...
...
@@ -830,6 +987,7 @@ s32_t SPIFFS_check(spiffs *fs) {
SPIFFS_UNLOCK
(
fs
);
return
res
;
#endif // SPIFFS_READ_ONLY
}
s32_t
SPIFFS_info
(
spiffs
*
fs
,
u32_t
*
total
,
u32_t
*
used
)
{
...
...
@@ -856,91 +1014,96 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
return
res
;
}
s32_t
SPIFFS_tell
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
SPIFFS_gc_quick
(
spiffs
*
fs
,
u16_t
max_free_pages
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
(
void
)
max_free_pages
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
spiffs_fd
*
fd
;
s32_t
res
;
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
#if SPIFFS_CACHE_WR
spiffs_fflush_cache
(
fs
,
fh
);
#endif
res
=
fd
->
fdoffset
;
res
=
spiffs_gc_quick
(
fs
,
max_free_pages
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
return
res
;
return
0
;
#endif // SPIFFS_READ_ONLY
}
s32_t
SPIFFS_eof
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
spiffs_fd
*
fd
;
s32_t
SPIFFS_gc
(
spiffs
*
fs
,
u32_t
size
)
{
#if SPIFFS_READ_ONLY
(
void
)
fs
;
(
void
)
size
;
return
SPIFFS_ERR_RO_NOT_IMPL
;
#else
s32_t
res
;
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
#if SPIFFS_CACHE_WR
spiffs_fflush_cache
(
fs
,
fh
);
#endif
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
res
=
(
fd
->
fdoffset
==
fd
->
size
);
res
=
spiffs_gc_check
(
fs
,
size
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
return
res
;
return
0
;
#endif // SPIFFS_READ_ONLY
}
s32_t
SPIFFS_size
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
SPIFFS_eof
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
spiffs_fd
*
fd
;
s32_t
res
;
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES
(
fs
,
res
);
SPIFFS_API_CHECK_RES
_UNLOCK
(
fs
,
res
);
#if SPIFFS_CACHE_WR
spiffs_fflush_cache
(
fs
,
fh
);
res
=
spiffs_fflush_cache
(
fs
,
fh
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
#endif
res
=
fd
->
size
;
res
=
(
fd
->
fdoffset
>=
(
fd
->
size
==
SPIFFS_UNDEFINED_LEN
?
0
:
fd
->
size
))
;
SPIFFS_UNLOCK
(
fs
);
return
res
;
}
s32_t
SPIFFS_
gc_quick
(
spiffs
*
fs
,
u16_t
max_free_pages
)
{
s32_t
SPIFFS_
tell
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
res
=
spiffs_gc_quick
(
fs
,
max_free_pages
);
fh
=
SPIFFS_FH_UNOFFS
(
fs
,
fh
);
spiffs_fd
*
fd
;
res
=
spiffs_fd_get
(
fs
,
fh
,
&
fd
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
return
0
;
}
#if SPIFFS_CACHE_WR
res
=
spiffs_fflush_cache
(
fs
,
fh
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
#endif
s32_t
SPIFFS_gc
(
spiffs
*
fs
,
u32_t
size
)
{
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
res
=
fd
->
fdoffset
;
res
=
spiffs_gc_check
(
fs
,
size
);
SPIFFS_UNLOCK
(
fs
);
return
res
;
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
s32_t
SPIFFS_set_file_callback_func
(
spiffs
*
fs
,
spiffs_file_callback
cb_func
)
{
SPIFFS_LOCK
(
fs
);
fs
->
file_cb_f
=
cb_func
;
SPIFFS_UNLOCK
(
fs
);
return
0
;
}
#if SPIFFS_TEST_VISUALISATION
s32_t
SPIFFS_vis
(
spiffs
*
fs
)
{
s32_t
res
=
SPIFFS_OK
;
...
...
@@ -1008,11 +1171,10 @@ s32_t SPIFFS_vis(spiffs *fs) {
spiffs_printf
(
"free_blocks: %i
\n
"
,
fs
->
free_blocks
);
spiffs_printf
(
"page_alloc: %i
\n
"
,
fs
->
stats_p_allocated
);
spiffs_printf
(
"page_delet: %i
\n
"
,
fs
->
stats_p_deleted
);
SPIFFS_UNLOCK
(
fs
);
u32_t
total
,
used
;
SPIFFS_info
(
fs
,
&
total
,
&
used
);
spiffs_printf
(
"used: %i of %i
\n
"
,
used
,
total
);
SPIFFS_UNLOCK
(
fs
);
return
res
;
}
#endif
components/spiffs/spiffs_nucleus.c
View file @
4f1b33d5
#include "spiffs.h"
#include "spiffs_nucleus.h"
#include <string.h>
static
s32_t
spiffs_page_data_check
(
spiffs
*
fs
,
spiffs_fd
*
fd
,
spiffs_page_ix
pix
,
spiffs_span_ix
spix
)
{
s32_t
res
=
SPIFFS_OK
;
...
...
@@ -29,6 +30,7 @@ static s32_t spiffs_page_data_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pi
return
res
;
}
#if !SPIFFS_READ_ONLY
static
s32_t
spiffs_page_index_check
(
spiffs
*
fs
,
spiffs_fd
*
fd
,
spiffs_page_ix
pix
,
spiffs_span_ix
spix
)
{
s32_t
res
=
SPIFFS_OK
;
if
(
pix
==
(
spiffs_page_ix
)
-
1
)
{
...
...
@@ -56,6 +58,7 @@ static s32_t spiffs_page_index_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix p
#endif
return
res
;
}
#endif // !SPIFFS_READ_ONLY
#if !SPIFFS_CACHE
...
...
@@ -64,7 +67,7 @@ s32_t spiffs_phys_rd(
u32_t
addr
,
u32_t
len
,
u8_t
*
dst
)
{
return
fs
->
cfg
.
hal_read_f
(
addr
,
len
,
dst
);
return
SPIFFS_HAL_READ
(
fs
,
addr
,
len
,
dst
);
}
s32_t
spiffs_phys_wr
(
...
...
@@ -72,17 +75,19 @@ s32_t spiffs_phys_wr(
u32_t
addr
,
u32_t
len
,
u8_t
*
src
)
{
return
fs
->
cfg
.
hal_write_f
(
addr
,
len
,
src
);
return
SPIFFS_HAL_WRITE
(
fs
,
addr
,
len
,
src
);
}
#endif
#if !SPIFFS_READ_ONLY
s32_t
spiffs_phys_cpy
(
spiffs
*
fs
,
spiffs_file
fh
,
u32_t
dst
,
u32_t
src
,
u32_t
len
)
{
(
void
)
fh
;
s32_t
res
;
u8_t
b
[
SPIFFS_COPY_BUFFER_STACK
];
while
(
len
>
0
)
{
...
...
@@ -97,10 +102,11 @@ s32_t spiffs_phys_cpy(
}
return
SPIFFS_OK
;
}
#endif // !SPIFFS_READ_ONLY
// Find object lookup entry containing given id with visitor.
// Iterate over object lookup pages in each block until a given object id entry is found.
// When found, the visitor function is called with block index, entry index and user
_
data.
// When found, the visitor function is called with block index, entry index and user
data.
// If visitor returns SPIFFS_VIS_CONTINUE, the search goes on. Otherwise, the search will be
// ended and visitor's return code is returned to caller.
// If no visitor is given (0) the search returns on first entry with matching object id.
...
...
@@ -112,8 +118,8 @@ s32_t spiffs_phys_cpy(
// SPIFFS_VIS_NO_WRAP
// @param obj_id argument object id
// @param v visitor callback function
// @param user_
data
any
data
, passed to the callback visitor function
// @param user_
p
any pointer, passed to the callback visitor function
// @param user_
const_p
any
const pointer
, passed to the callback visitor function
// @param user_
var_p
any pointer, passed to the callback visitor function
// @param block_ix reported block index where match was found
// @param lu_entry reported look up index where match was found
s32_t
spiffs_obj_lu_find_entry_visitor
(
...
...
@@ -123,8 +129,8 @@ s32_t spiffs_obj_lu_find_entry_visitor(
u8_t
flags
,
spiffs_obj_id
obj_id
,
spiffs_visitor_f
v
,
u32_t
user_data
,
void
*
user_p
,
const
void
*
user_const_p
,
void
*
user_
var_
p
,
spiffs_block_ix
*
block_ix
,
int
*
lu_entry
)
{
s32_t
res
=
SPIFFS_OK
;
...
...
@@ -174,8 +180,8 @@ s32_t spiffs_obj_lu_find_entry_visitor(
(
flags
&
SPIFFS_VIS_CHECK_PH
)
?
obj_id
:
obj_lu_buf
[
cur_entry
-
entry_offset
],
cur_block
,
cur_entry
,
user_
data
,
user_p
);
user_
const_p
,
user_
var_
p
);
if
(
res
==
SPIFFS_VIS_COUNTINUE
||
res
==
SPIFFS_VIS_COUNTINUE_RELOAD
)
{
if
(
res
==
SPIFFS_VIS_COUNTINUE_RELOAD
)
{
res
=
_spiffs_rd
(
fs
,
SPIFFS_OP_T_OBJ_LU
|
SPIFFS_OP_C_READ
,
...
...
@@ -217,6 +223,7 @@ s32_t spiffs_obj_lu_find_entry_visitor(
return
SPIFFS_VIS_END
;
}
#if !SPIFFS_READ_ONLY
s32_t
spiffs_erase_block
(
spiffs
*
fs
,
spiffs_block_ix
bix
)
{
...
...
@@ -227,7 +234,8 @@ s32_t spiffs_erase_block(
// here we ignore res, just try erasing the block
while
(
size
>
0
)
{
SPIFFS_DBG
(
"erase %08x:%08x
\n
"
,
addr
,
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
));
(
void
)
fs
->
cfg
.
hal_erase_f
(
addr
,
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
));
SPIFFS_HAL_ERASE
(
fs
,
addr
,
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
));
addr
+=
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
);
size
-=
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
);
}
...
...
@@ -241,7 +249,7 @@ s32_t spiffs_erase_block(
#if SPIFFS_USE_MAGIC
// finally, write magic
spiffs_obj_id
magic
=
SPIFFS_MAGIC
(
fs
);
spiffs_obj_id
magic
=
SPIFFS_MAGIC
(
fs
,
bix
);
res
=
_spiffs_wr
(
fs
,
SPIFFS_OP_C_WRTHRU
|
SPIFFS_OP_T_OBJ_LU2
,
0
,
SPIFFS_MAGIC_PADDR
(
fs
,
bix
),
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
magic
);
...
...
@@ -255,6 +263,59 @@ s32_t spiffs_erase_block(
return
res
;
}
#endif // !SPIFFS_READ_ONLY
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
s32_t
spiffs_probe
(
spiffs_config
*
cfg
)
{
s32_t
res
;
u32_t
paddr
;
spiffs
dummy_fs
;
// create a dummy fs struct just to be able to use macros
memcpy
(
&
dummy_fs
.
cfg
,
cfg
,
sizeof
(
spiffs_config
));
dummy_fs
.
block_count
=
0
;
// Read three magics, as one block may be in an aborted erase state.
// At least two of these must contain magic and be in decreasing order.
spiffs_obj_id
magic
[
3
];
spiffs_obj_id
bix_count
[
3
];
spiffs_block_ix
bix
;
for
(
bix
=
0
;
bix
<
3
;
bix
++
)
{
paddr
=
SPIFFS_MAGIC_PADDR
(
&
dummy_fs
,
bix
);
#if SPIFFS_HAL_CALLBACK_EXTRA
// not any proper fs to report here, so callback with null
// (cross fingers that no-one gets angry)
res
=
cfg
->
hal_read_f
((
void
*
)
0
,
paddr
,
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
magic
[
bix
]);
#else
res
=
cfg
->
hal_read_f
(
paddr
,
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
magic
[
bix
]);
#endif
bix_count
[
bix
]
=
magic
[
bix
]
^
SPIFFS_MAGIC
(
&
dummy_fs
,
0
);
SPIFFS_CHECK_RES
(
res
);
}
// check that we have sane number of blocks
if
(
bix_count
[
0
]
<
3
)
return
SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS
;
// check that the order is correct, take aborted erases in calculation
// first block aborted erase
if
(
magic
[
0
]
==
(
spiffs_obj_id
)(
-
1
)
&&
bix_count
[
1
]
-
bix_count
[
2
]
==
1
)
{
return
(
bix_count
[
1
]
+
1
)
*
cfg
->
log_block_size
;
}
// second block aborted erase
if
(
magic
[
1
]
==
(
spiffs_obj_id
)(
-
1
)
&&
bix_count
[
0
]
-
bix_count
[
2
]
==
2
)
{
return
bix_count
[
0
]
*
cfg
->
log_block_size
;
}
// third block aborted erase
if
(
magic
[
2
]
==
(
spiffs_obj_id
)(
-
1
)
&&
bix_count
[
0
]
-
bix_count
[
1
]
==
1
)
{
return
bix_count
[
0
]
*
cfg
->
log_block_size
;
}
// no block has aborted erase
if
(
bix_count
[
0
]
-
bix_count
[
1
]
==
1
&&
bix_count
[
1
]
-
bix_count
[
2
]
==
1
)
{
return
bix_count
[
0
]
*
cfg
->
log_block_size
;
}
return
SPIFFS_ERR_PROBE_NOT_A_FS
;
}
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
static
s32_t
spiffs_obj_lu_scan_v
(
...
...
@@ -262,11 +323,11 @@ static s32_t spiffs_obj_lu_scan_v(
spiffs_obj_id
obj_id
,
spiffs_block_ix
bix
,
int
ix_entry
,
u32_t
user_data
,
void
*
user_p
)
{
const
void
*
user_const_p
,
void
*
user_
var_
p
)
{
(
void
)
bix
;
(
void
)
user_
data
;
(
void
)
user_p
;
(
void
)
user_
const_p
;
(
void
)
user_
var_
p
;
if
(
obj_id
==
SPIFFS_OBJ_ID_FREE
)
{
if
(
ix_entry
==
0
)
{
fs
->
free_blocks
++
;
...
...
@@ -309,7 +370,7 @@ s32_t spiffs_obj_lu_scan(
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
magic
);
SPIFFS_CHECK_RES
(
res
);
if
(
magic
!=
SPIFFS_MAGIC
(
fs
))
{
if
(
magic
!=
SPIFFS_MAGIC
(
fs
,
bix
))
{
if
(
unerased_bix
==
(
spiffs_block_ix
)
-
1
)
{
// allow one unerased block as it might be powered down during an erase
unerased_bix
=
bix
;
...
...
@@ -348,7 +409,11 @@ s32_t spiffs_obj_lu_scan(
if
(
unerased_bix
!=
(
spiffs_block_ix
)
-
1
)
{
// found one unerased block, remedy
SPIFFS_DBG
(
"mount: erase block %i
\n
"
,
bix
);
#if SPIFFS_READ_ONLY
res
=
SPIFFS_ERR_RO_ABORTED_OPERATION
;
#else
res
=
spiffs_erase_block
(
fs
,
unerased_bix
);
#endif // SPIFFS_READ_ONLY
SPIFFS_CHECK_RES
(
res
);
}
#endif
...
...
@@ -379,6 +444,7 @@ s32_t spiffs_obj_lu_scan(
return
res
;
}
#if !SPIFFS_READ_ONLY
// Find free object lookup entry
// Iterate over object lookup pages in each block until a free object id entry is found
s32_t
spiffs_obj_lu_find_free
(
...
...
@@ -407,12 +473,13 @@ s32_t spiffs_obj_lu_find_free(
fs
->
free_blocks
--
;
}
}
if
(
res
==
SPIFFS_
VIS_END
)
{
if
(
res
==
SPIFFS_
ERR_FULL
)
{
SPIFFS_DBG
(
"fs full
\n
"
);
}
return
res
==
SPIFFS_VIS_END
?
SPIFFS_ERR_FULL
:
res
;
return
res
;
}
#endif // !SPIFFS_READ_ONLY
// Find object lookup entry containing given id
// Iterate over object lookup pages in each block until a given object id entry is found
...
...
@@ -437,8 +504,8 @@ static s32_t spiffs_obj_lu_find_id_and_span_v(
spiffs_obj_id
obj_id
,
spiffs_block_ix
bix
,
int
ix_entry
,
u32_t
user_data
,
void
*
user_p
)
{
const
void
*
user_const_p
,
void
*
user_
var_
p
)
{
s32_t
res
;
spiffs_page_header
ph
;
spiffs_page_ix
pix
=
SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX
(
fs
,
bix
,
ix_entry
);
...
...
@@ -446,10 +513,10 @@ static s32_t spiffs_obj_lu_find_id_and_span_v(
SPIFFS_PAGE_TO_PADDR
(
fs
,
pix
),
sizeof
(
spiffs_page_header
),
(
u8_t
*
)
&
ph
);
SPIFFS_CHECK_RES
(
res
);
if
(
ph
.
obj_id
==
obj_id
&&
ph
.
span_ix
==
(
spiffs_span_ix
)
user_
data
&&
ph
.
span_ix
==
*
(
(
spiffs_span_ix
*
)
user_
var_p
)
&&
(
ph
.
flags
&
(
SPIFFS_PH_FLAG_FINAL
|
SPIFFS_PH_FLAG_DELET
|
SPIFFS_PH_FLAG_USED
))
==
SPIFFS_PH_FLAG_DELET
&&
!
((
obj_id
&
SPIFFS_OBJ_ID_IX_FLAG
)
&&
(
ph
.
flags
&
SPIFFS_PH_FLAG_IXDELE
)
==
0
&&
ph
.
span_ix
==
0
)
&&
(
user_p
==
0
||
*
((
spiffs_page_ix
*
)
user_p
)
!=
pix
))
{
(
user_
const_
p
==
0
||
*
((
const
spiffs_page_ix
*
)
user_
const_
p
)
!=
pix
))
{
return
SPIFFS_OK
;
}
else
{
return
SPIFFS_VIS_COUNTINUE
;
...
...
@@ -474,8 +541,8 @@ s32_t spiffs_obj_lu_find_id_and_span(
SPIFFS_VIS_CHECK_ID
,
obj_id
,
spiffs_obj_lu_find_id_and_span_v
,
(
u32_t
)
spix
,
exclusion_pix
?
&
exclusion_pix
:
0
,
&
spix
,
&
bix
,
&
entry
);
...
...
@@ -513,8 +580,8 @@ s32_t spiffs_obj_lu_find_id_and_span_by_phdr(
SPIFFS_VIS_CHECK_PH
,
obj_id
,
spiffs_obj_lu_find_id_and_span_v
,
(
u32_t
)
spix
,
exclusion_pix
?
&
exclusion_pix
:
0
,
&
spix
,
&
bix
,
&
entry
);
...
...
@@ -534,6 +601,7 @@ s32_t spiffs_obj_lu_find_id_and_span_by_phdr(
return
res
;
}
#if !SPIFFS_READ_ONLY
// Allocates a free defined page with given obj_id
// Occupies object lookup entry and page
// data may be NULL; where only page header is stored, len and page_offs is ignored
...
...
@@ -591,7 +659,9 @@ s32_t spiffs_page_allocate_data(
return
res
;
}
#endif // !SPIFFS_READ_ONLY
#if !SPIFFS_READ_ONLY
// Moves a page from src to a free page and finalizes it. Updates page index. Page data is given in param page.
// If page data is null, provided header is used for metainfo and page data is physically copied.
s32_t
spiffs_page_move
(
...
...
@@ -654,7 +724,9 @@ s32_t spiffs_page_move(
res
=
spiffs_page_delete
(
fs
,
src_pix
);
return
res
;
}
#endif // !SPIFFS_READ_ONLY
#if !SPIFFS_READ_ONLY
// Deletes a page and removes it from object lookup.
s32_t
spiffs_page_delete
(
spiffs
*
fs
,
...
...
@@ -683,12 +755,14 @@ s32_t spiffs_page_delete(
return
res
;
}
#endif // !SPIFFS_READ_ONLY
#if !SPIFFS_READ_ONLY
// Create an object index header page with empty index and undefined length
s32_t
spiffs_object_create
(
spiffs
*
fs
,
spiffs_obj_id
obj_id
,
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
const
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
spiffs_obj_type
type
,
spiffs_page_ix
*
objix_hdr_pix
)
{
s32_t
res
=
SPIFFS_OK
;
...
...
@@ -719,7 +793,7 @@ s32_t spiffs_object_create(
oix_hdr
.
p_hdr
.
flags
=
0xff
&
~
(
SPIFFS_PH_FLAG_FINAL
|
SPIFFS_PH_FLAG_INDEX
|
SPIFFS_PH_FLAG_USED
);
oix_hdr
.
type
=
type
;
oix_hdr
.
size
=
SPIFFS_UNDEFINED_LEN
;
// keep ones so we can update later without wasting this page
strncpy
((
char
*
)
&
oix_hdr
.
name
,
(
char
*
)
name
,
SPIFFS_OBJ_NAME_LEN
);
strncpy
((
char
*
)
&
oix_hdr
.
name
,
(
const
char
*
)
name
,
SPIFFS_OBJ_NAME_LEN
);
// update page
...
...
@@ -735,7 +809,9 @@ s32_t spiffs_object_create(
return
res
;
}
#endif // !SPIFFS_READ_ONLY
#if !SPIFFS_READ_ONLY
// update object index header with any combination of name/size/index
// new_objix_hdr_data may be null, if so the object index header page is loaded
// name may be null, if so name is not changed
...
...
@@ -746,7 +822,7 @@ s32_t spiffs_object_update_index_hdr(
spiffs_obj_id
obj_id
,
spiffs_page_ix
objix_hdr_pix
,
u8_t
*
new_objix_hdr_data
,
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
const
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
u32_t
size
,
spiffs_page_ix
*
new_pix
)
{
s32_t
res
=
SPIFFS_OK
;
...
...
@@ -770,7 +846,7 @@ s32_t spiffs_object_update_index_hdr(
// change name
if
(
name
)
{
strncpy
((
char
*
)
objix_hdr
->
name
,
(
char
*
)
name
,
SPIFFS_OBJ_NAME_LEN
);
strncpy
((
char
*
)
objix_hdr
->
name
,
(
const
char
*
)
name
,
SPIFFS_OBJ_NAME_LEN
);
}
if
(
size
)
{
objix_hdr
->
size
=
size
;
...
...
@@ -790,18 +866,19 @@ s32_t spiffs_object_update_index_hdr(
return
res
;
}
#endif // !SPIFFS_READ_ONLY
void
spiffs_cb_object_event
(
spiffs
*
fs
,
spiffs_fd
*
fd
,
int
ev
,
spiffs_obj_id
obj_id
,
spiffs_obj_id
obj_id
_raw
,
spiffs_span_ix
spix
,
spiffs_page_ix
new_pix
,
u32_t
new_size
)
{
(
void
)
fd
;
// update index caches in all file descriptors
obj_id
&=
~
SPIFFS_OBJ_ID_IX_FLAG
;
spiffs_obj_id
obj_id
=
obj_id_raw
&
~
SPIFFS_OBJ_ID_IX_FLAG
;
u32_t
i
;
spiffs_fd
*
fds
=
(
spiffs_fd
*
)
fs
->
fd_space
;
for
(
i
=
0
;
i
<
fs
->
fd_count
;
i
++
)
{
...
...
@@ -828,6 +905,22 @@ void spiffs_cb_object_event(
}
}
}
// callback to user if object index header
if
(
fs
->
file_cb_f
&&
spix
==
0
&&
(
obj_id_raw
&
SPIFFS_OBJ_ID_IX_FLAG
))
{
spiffs_fileop_type
op
;
if
(
ev
==
SPIFFS_EV_IX_NEW
)
{
op
=
SPIFFS_CB_CREATED
;
}
else
if
(
ev
==
SPIFFS_EV_IX_UPD
)
{
op
=
SPIFFS_CB_UPDATED
;
}
else
if
(
ev
==
SPIFFS_EV_IX_DEL
)
{
op
=
SPIFFS_CB_DELETED
;
}
else
{
SPIFFS_DBG
(
" callback: WARNING unknown callback event %02x
\n
"
,
ev
);
return
;
// bail out
}
fs
->
file_cb_f
(
fs
,
op
,
obj_id
,
new_pix
);
}
}
// Open object by id
...
...
@@ -886,6 +979,7 @@ s32_t spiffs_object_open_by_page(
return
res
;
}
#if !SPIFFS_READ_ONLY
// Append to object
// keep current object index (header) page in fs->work buffer
s32_t
spiffs_object_append
(
spiffs_fd
*
fd
,
u32_t
offset
,
u8_t
*
data
,
u32_t
len
)
{
...
...
@@ -1125,8 +1219,10 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) {
}
return
res
;
}
}
// spiffs_object_append
#endif // !SPIFFS_READ_ONLY
#if !SPIFFS_READ_ONLY
// Modify object
// keep current object index (header) page in fs->work buffer
s32_t
spiffs_object_modify
(
spiffs_fd
*
fd
,
u32_t
offset
,
u8_t
*
data
,
u32_t
len
)
{
...
...
@@ -1326,16 +1422,17 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) {
}
return
res
;
}
}
// spiffs_object_modify
#endif // !SPIFFS_READ_ONLY
static
s32_t
spiffs_object_find_object_index_header_by_name_v
(
spiffs
*
fs
,
spiffs_obj_id
obj_id
,
spiffs_block_ix
bix
,
int
ix_entry
,
u32_t
user_data
,
void
*
user_p
)
{
(
void
)
user_
data
;
const
void
*
user_const_p
,
void
*
user_
var_
p
)
{
(
void
)
user_
var_p
;
s32_t
res
;
spiffs_page_object_ix_header
objix_hdr
;
spiffs_page_ix
pix
=
SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX
(
fs
,
bix
,
ix_entry
);
...
...
@@ -1349,7 +1446,7 @@ static s32_t spiffs_object_find_object_index_header_by_name_v(
if
(
objix_hdr
.
p_hdr
.
span_ix
==
0
&&
(
objix_hdr
.
p_hdr
.
flags
&
(
SPIFFS_PH_FLAG_DELET
|
SPIFFS_PH_FLAG_FINAL
|
SPIFFS_PH_FLAG_IXDELE
))
==
(
SPIFFS_PH_FLAG_DELET
|
SPIFFS_PH_FLAG_IXDELE
))
{
if
(
str
n
cmp
((
char
*
)
user_p
,
(
char
*
)
objix_hdr
.
name
,
SPIFFS_OBJ_NAME_LEN
)
==
0
)
{
if
(
strcmp
((
const
char
*
)
user_
const_
p
,
(
char
*
)
objix_hdr
.
name
)
==
0
)
{
return
SPIFFS_OK
;
}
}
...
...
@@ -1360,7 +1457,7 @@ static s32_t spiffs_object_find_object_index_header_by_name_v(
// Finds object index header page by name
s32_t
spiffs_object_find_object_index_header_by_name
(
spiffs
*
fs
,
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
const
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
spiffs_page_ix
*
pix
)
{
s32_t
res
;
spiffs_block_ix
bix
;
...
...
@@ -1372,8 +1469,8 @@ s32_t spiffs_object_find_object_index_header_by_name(
0
,
0
,
spiffs_object_find_object_index_header_by_name_v
,
0
,
name
,
0
,
&
bix
,
&
entry
);
...
...
@@ -1392,6 +1489,7 @@ s32_t spiffs_object_find_object_index_header_by_name(
return
res
;
}
#if !SPIFFS_READ_ONLY
// Truncates object to new size. If new size is null, object may be removed totally
s32_t
spiffs_object_truncate
(
spiffs_fd
*
fd
,
...
...
@@ -1400,8 +1498,16 @@ s32_t spiffs_object_truncate(
s32_t
res
=
SPIFFS_OK
;
spiffs
*
fs
=
fd
->
fs
;
res
=
spiffs_gc_check
(
fs
,
remove
?
0
:
SPIFFS_DATA_PAGE_SIZE
(
fs
));
if
((
fd
->
size
==
SPIFFS_UNDEFINED_LEN
||
fd
->
size
==
0
)
&&
!
remove
)
{
// no op
return
res
;
}
// need 2 pages if not removing: object index page + possibly chopped data page
if
(
remove
==
0
)
{
res
=
spiffs_gc_check
(
fs
,
SPIFFS_DATA_PAGE_SIZE
(
fs
)
*
2
);
SPIFFS_CHECK_RES
(
res
);
}
spiffs_page_ix
objix_pix
=
fd
->
objix_hdr_pix
;
spiffs_span_ix
data_spix
=
(
fd
->
size
>
0
?
fd
->
size
-
1
:
0
)
/
SPIFFS_DATA_PAGE_SIZE
(
fs
);
...
...
@@ -1440,11 +1546,18 @@ s32_t spiffs_object_truncate(
SPIFFS_CHECK_RES
(
res
);
spiffs_cb_object_event
(
fs
,
fd
,
SPIFFS_EV_IX_DEL
,
fd
->
obj_id
,
objix
->
p_hdr
.
span_ix
,
objix_pix
,
0
);
if
(
prev_objix_spix
>
0
)
{
// update object index header page
// Update object index header page, unless we totally want to remove the file.
// If fully removing, we're not keeping consistency as good as when storing the header between chunks,
// would we be aborted. But when removing full files, a crammed system may otherwise
// report ERR_FULL a la windows. We cannot have that.
// Hence, take the risk - if aborted, a file check would free the lost pages and mend things
// as the file is marked as fully deleted in the beginning.
if
(
remove
==
0
)
{
SPIFFS_DBG
(
"truncate: update objix hdr page %04x:%04x to size %i
\n
"
,
fd
->
objix_hdr_pix
,
prev_objix_spix
,
cur_size
);
res
=
spiffs_object_update_index_hdr
(
fs
,
fd
,
fd
->
obj_id
,
fd
->
objix_hdr_pix
,
0
,
0
,
cur_size
,
&
new_objix_hdr_pix
);
SPIFFS_CHECK_RES
(
res
);
}
fd
->
size
=
cur_size
;
}
}
...
...
@@ -1480,7 +1593,7 @@ s32_t spiffs_object_truncate(
SPIFFS_DBG
(
"truncate: got data pix %04x
\n
"
,
data_pix
);
if
(
cur_size
-
SPIFFS_DATA_PAGE_SIZE
(
fs
)
>=
new_size
)
{
if
(
new_size
==
0
||
remove
||
cur_size
-
new_size
>=
SPIFFS_DATA_PAGE_SIZE
(
fs
))
{
// delete full data page
res
=
spiffs_page_data_check
(
fs
,
fd
,
data_pix
,
data_spix
);
if
(
res
!=
SPIFFS_ERR_DELETED
&&
res
!=
SPIFFS_OK
&&
res
!=
SPIFFS_ERR_INDEX_REF_FREE
)
{
...
...
@@ -1611,7 +1724,8 @@ s32_t spiffs_object_truncate(
fd
->
size
=
cur_size
;
return
res
;
}
}
// spiffs_object_truncate
#endif // !SPIFFS_READ_ONLY
s32_t
spiffs_object_read
(
spiffs_fd
*
fd
,
...
...
@@ -1691,6 +1805,7 @@ s32_t spiffs_object_read(
return
res
;
}
#if !SPIFFS_READ_ONLY
typedef
struct
{
spiffs_obj_id
min_obj_id
;
spiffs_obj_id
max_obj_id
;
...
...
@@ -1699,10 +1814,10 @@ typedef struct {
}
spiffs_free_obj_id_state
;
static
s32_t
spiffs_obj_lu_find_free_obj_id_bitmap_v
(
spiffs
*
fs
,
spiffs_obj_id
id
,
spiffs_block_ix
bix
,
int
ix_entry
,
u32_t
user_data
,
void
*
user_p
)
{
const
void
*
user_const_p
,
void
*
user_
var_
p
)
{
if
(
id
!=
SPIFFS_OBJ_ID_FREE
&&
id
!=
SPIFFS_OBJ_ID_DELETED
)
{
spiffs_obj_id
min_obj_id
=
user_data
;
u8_t
*
conflicting_name
=
(
u8_t
*
)
user_p
;
spiffs_obj_id
min_obj_id
=
*
((
spiffs_obj_id
*
)
user_var_p
)
;
const
u8_t
*
conflicting_name
=
(
const
u8_t
*
)
user_
const_
p
;
// if conflicting name parameter is given, also check if this name is found in object index hdrs
if
(
conflicting_name
&&
(
id
&
SPIFFS_OBJ_ID_IX_FLAG
))
{
...
...
@@ -1715,7 +1830,7 @@ static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id i
if
(
objix_hdr
.
p_hdr
.
span_ix
==
0
&&
(
objix_hdr
.
p_hdr
.
flags
&
(
SPIFFS_PH_FLAG_DELET
|
SPIFFS_PH_FLAG_FINAL
|
SPIFFS_PH_FLAG_IXDELE
))
==
(
SPIFFS_PH_FLAG_DELET
|
SPIFFS_PH_FLAG_IXDELE
))
{
if
(
str
n
cmp
((
char
*
)
user_p
,
(
char
*
)
objix_hdr
.
name
,
SPIFFS_OBJ_NAME_LEN
)
==
0
)
{
if
(
strcmp
((
const
char
*
)
user_
const_
p
,
(
char
*
)
objix_hdr
.
name
)
==
0
)
{
return
SPIFFS_ERR_CONFLICTING_NAME
;
}
}
...
...
@@ -1732,11 +1847,11 @@ static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id i
}
static
s32_t
spiffs_obj_lu_find_free_obj_id_compact_v
(
spiffs
*
fs
,
spiffs_obj_id
id
,
spiffs_block_ix
bix
,
int
ix_entry
,
u32_t
user_data
,
void
*
user_p
)
{
(
void
)
user_
data
;
const
void
*
user_const_p
,
void
*
user_
var_
p
)
{
(
void
)
user_
var_p
;
if
(
id
!=
SPIFFS_OBJ_ID_FREE
&&
id
!=
SPIFFS_OBJ_ID_DELETED
&&
(
id
&
SPIFFS_OBJ_ID_IX_FLAG
))
{
s32_t
res
;
spiffs_free_obj_id_state
*
state
=
(
spiffs_free_obj_id_state
*
)
user_p
;
const
spiffs_free_obj_id_state
*
state
=
(
const
spiffs_free_obj_id_state
*
)
user_
const_
p
;
spiffs_page_object_ix_header
objix_hdr
;
res
=
_spiffs_rd
(
fs
,
SPIFFS_OP_T_OBJ_LU2
|
SPIFFS_OP_C_READ
,
...
...
@@ -1745,7 +1860,7 @@ static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id
((
objix_hdr
.
p_hdr
.
flags
&
(
SPIFFS_PH_FLAG_INDEX
|
SPIFFS_PH_FLAG_FINAL
|
SPIFFS_PH_FLAG_DELET
))
==
(
SPIFFS_PH_FLAG_DELET
)))
{
// ok object look up entry
if
(
state
->
conflicting_name
&&
str
n
cmp
((
const
char
*
)
state
->
conflicting_name
,
(
char
*
)
objix_hdr
.
name
,
SPIFFS_OBJ_NAME_LEN
)
==
0
)
{
if
(
state
->
conflicting_name
&&
strcmp
((
const
char
*
)
state
->
conflicting_name
,
(
char
*
)
objix_hdr
.
name
)
==
0
)
{
return
SPIFFS_ERR_CONFLICTING_NAME
;
}
...
...
@@ -1764,10 +1879,10 @@ static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id
// Scans thru all object lookup for object index header pages. If total possible number of
// object ids cannot fit into a work buffer, these are grouped. When a group containing free
// object ids is found, the object lu is again scanned for object ids within group and bitmasked.
// Finally, the bitmask
ed
is searched for a free id
s32_t
spiffs_obj_lu_find_free_obj_id
(
spiffs
*
fs
,
spiffs_obj_id
*
obj_id
,
u8_t
*
conflicting_name
)
{
// Finally, the bitmask is searched for a free id
s32_t
spiffs_obj_lu_find_free_obj_id
(
spiffs
*
fs
,
spiffs_obj_id
*
obj_id
,
const
u8_t
*
conflicting_name
)
{
s32_t
res
=
SPIFFS_OK
;
u32_t
max_objects
=
(
SPIFFS_CFG_PHYS_SZ
(
fs
)
/
(
u32_t
)
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
))
/
2
;
u32_t
max_objects
=
(
fs
->
block_count
*
SPIFFS_OBJ_LOOKUP_MAX_ENTRIES
(
fs
))
/
2
;
spiffs_free_obj_id_state
state
;
spiffs_obj_id
free_obj_id
=
SPIFFS_OBJ_ID_FREE
;
state
.
min_obj_id
=
1
;
...
...
@@ -1784,8 +1899,8 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, u8_t *co
SPIFFS_DBG
(
"free_obj_id: BITM min:%04x max:%04x
\n
"
,
state
.
min_obj_id
,
state
.
max_obj_id
);
memset
(
fs
->
work
,
0
,
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
));
res
=
spiffs_obj_lu_find_entry_visitor
(
fs
,
0
,
0
,
0
,
0
,
spiffs_obj_lu_find_free_obj_id_bitmap_v
,
state
.
min_obj_id
,
conflicting_name
,
0
,
0
);
res
=
spiffs_obj_lu_find_entry_visitor
(
fs
,
0
,
0
,
0
,
0
,
spiffs_obj_lu_find_free_obj_id_bitmap_v
,
conflicting_name
,
&
state
.
min_obj_id
,
0
,
0
);
if
(
res
==
SPIFFS_VIS_END
)
res
=
SPIFFS_OK
;
SPIFFS_CHECK_RES
(
res
);
// traverse bitmask until found free obj_id
...
...
@@ -1849,7 +1964,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, u8_t *co
SPIFFS_DBG
(
"free_obj_id: COMP min:%04x max:%04x compact:%i
\n
"
,
state
.
min_obj_id
,
state
.
max_obj_id
,
state
.
compaction
);
memset
(
fs
->
work
,
0
,
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
));
res
=
spiffs_obj_lu_find_entry_visitor
(
fs
,
0
,
0
,
0
,
0
,
spiffs_obj_lu_find_free_obj_id_compact_v
,
0
,
&
state
,
0
,
0
);
res
=
spiffs_obj_lu_find_entry_visitor
(
fs
,
0
,
0
,
0
,
0
,
spiffs_obj_lu_find_free_obj_id_compact_v
,
&
state
,
0
,
0
,
0
);
if
(
res
==
SPIFFS_VIS_END
)
res
=
SPIFFS_OK
;
SPIFFS_CHECK_RES
(
res
);
state
.
conflicting_name
=
0
;
// searched for conflicting name once, no need to do it again
...
...
@@ -1858,6 +1973,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, u8_t *co
return
res
;
}
#endif // !SPIFFS_READ_ONLY
s32_t
spiffs_fd_find_new
(
spiffs
*
fs
,
spiffs_fd
**
fd
)
{
u32_t
i
;
...
...
components/spiffs/spiffs_nucleus.h
View file @
4f1b33d5
...
...
@@ -131,7 +131,15 @@
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
#define SPIFFS_MAGIC(fs) ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
#if SPIFFS_USE_MAGIC
#if !SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_MAGIC(fs, bix) \
((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
#else // SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_MAGIC(fs, bix) \
((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs) ^ ((fs)->block_count - (bix))))
#endif // SPIFFS_USE_MAGIC_LENGTH
#endif // SPIFFS_USE_MAGIC
#define SPIFFS_CONFIG_MAGIC (0x20090315)
...
...
@@ -264,26 +272,26 @@
#define SPIFFS_API_CHECK_MOUNT(fs) \
if (!SPIFFS_CHECK_MOUNT((fs))) { \
(fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \
return
-1
; \
return
SPIFFS_ERR_NOT_MOUNTED
; \
}
#define SPIFFS_API_CHECK_CFG(fs) \
if (!SPIFFS_CHECK_CFG((fs))) { \
(fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \
return
-1
; \
return
SPIFFS_ERR_NOT_CONFIGURED
; \
}
#define SPIFFS_API_CHECK_RES(fs, res) \
if ((res) < SPIFFS_OK) { \
(fs)->err_code = (res); \
return
-1
; \
return
(res)
; \
}
#define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \
if ((res) < SPIFFS_OK) { \
(fs)->err_code = (res); \
SPIFFS_UNLOCK(fs); \
return
-1
; \
return
(res)
; \
}
#define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \
...
...
@@ -311,6 +319,26 @@
// stop searching at end of all look up pages
#define SPIFFS_VIS_NO_WRAP (1<<2)
#if SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
(_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src))
#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
(_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst))
#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
(_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len))
#else // SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
(_fs)->cfg.hal_write_f((_paddr), (_len), (_src))
#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
(_fs)->cfg.hal_read_f((_paddr), (_len), (_dst))
#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
(_fs)->cfg.hal_erase_f((_paddr), (_len))
#endif // SPIFFS_HAL_CALLBACK_EXTRA
#if SPIFFS_CACHE
#define SPIFFS_CACHE_FLAG_DIRTY (1<<0)
...
...
@@ -416,9 +444,14 @@ typedef struct __attribute(( packed )) {
// object index header page header
typedef
struct
__attribute
((
packed
))
#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
__attribute
((
aligned
(
sizeof
(
spiffs_page_ix
))
))
#endif
{
// common page header
spiffs_page_header
p_hdr
;
// alignment
u8_t
_align
[
4
-
((
sizeof
(
spiffs_page_header
)
&
3
)
==
0
?
4
:
(
sizeof
(
spiffs_page_header
)
&
3
))];
// size of object
u32_t
size
;
// type of object
...
...
@@ -430,11 +463,12 @@ typedef struct __attribute(( packed ))
// object index page header
typedef
struct
__attribute
((
packed
))
{
spiffs_page_header
p_hdr
;
u8_t
_align
[
4
-
((
sizeof
(
spiffs_page_header
)
&
3
)
==
0
?
4
:
(
sizeof
(
spiffs_page_header
)
&
3
))];
}
spiffs_page_object_ix
;
// callback func for object lookup visitor
typedef
s32_t
(
*
spiffs_visitor_f
)(
spiffs
*
fs
,
spiffs_obj_id
id
,
spiffs_block_ix
bix
,
int
ix_entry
,
u32_t
user_data
,
void
*
user_p
);
const
void
*
user_const_p
,
void
*
user_
var_
p
);
#if SPIFFS_CACHE
...
...
@@ -495,8 +529,8 @@ s32_t spiffs_obj_lu_find_entry_visitor(
u8_t
flags
,
spiffs_obj_id
obj_id
,
spiffs_visitor_f
v
,
u32_t
user_data
,
void
*
user_p
,
const
void
*
user_const_p
,
void
*
user_
var_
p
,
spiffs_block_ix
*
block_ix
,
int
*
lu_entry
);
...
...
@@ -504,6 +538,11 @@ s32_t spiffs_erase_block(
spiffs
*
fs
,
spiffs_block_ix
bix
);
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
s32_t
spiffs_probe
(
spiffs_config
*
cfg
);
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
// ---------------
s32_t
spiffs_obj_lu_scan
(
...
...
@@ -512,7 +551,7 @@ s32_t spiffs_obj_lu_scan(
s32_t
spiffs_obj_lu_find_free_obj_id
(
spiffs
*
fs
,
spiffs_obj_id
*
obj_id
,
u8_t
*
conflicting_name
);
const
u8_t
*
conflicting_name
);
s32_t
spiffs_obj_lu_find_free
(
spiffs
*
fs
,
...
...
@@ -573,7 +612,7 @@ s32_t spiffs_page_delete(
s32_t
spiffs_object_create
(
spiffs
*
fs
,
spiffs_obj_id
obj_id
,
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
const
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
spiffs_obj_type
type
,
spiffs_page_ix
*
objix_hdr_pix
);
...
...
@@ -583,7 +622,7 @@ s32_t spiffs_object_update_index_hdr(
spiffs_obj_id
obj_id
,
spiffs_page_ix
objix_hdr_pix
,
u8_t
*
new_objix_hdr_data
,
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
const
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
u32_t
size
,
spiffs_page_ix
*
new_pix
);
...
...
@@ -635,7 +674,7 @@ s32_t spiffs_object_truncate(
s32_t
spiffs_object_find_object_index_header_by_name
(
spiffs
*
fs
,
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
const
u8_t
name
[
SPIFFS_OBJ_NAME_LEN
],
spiffs_page_ix
*
pix
);
// ---------------
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment