Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
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