ESP8266
spiffs_nucleus.h
1 /*
2  * spiffs_nucleus.h
3  *
4  * Created on: Jun 15, 2013
5  * Author: petera
6  */
7 
8 /* SPIFFS layout
9  *
10  * spiffs is designed for following spi flash characteristics:
11  * - only big areas of data (blocks) can be erased
12  * - erasing resets all bits in a block to ones
13  * - writing pulls ones to zeroes
14  * - zeroes cannot be pulled to ones, without erase
15  * - wear leveling
16  *
17  * spiffs is also meant to be run on embedded, memory constraint devices.
18  *
19  * Entire area is divided in blocks. Entire area is also divided in pages.
20  * Each block contains same number of pages. A page cannot be erased, but a
21  * block can be erased.
22  *
23  * Entire area must be block_size * x
24  * page_size must be block_size / (2^y) where y > 2
25  *
26  * ex: area = 1024*1024 bytes, block size = 65536 bytes, page size = 256 bytes
27  *
28  * BLOCK 0 PAGE 0 object lookup 1
29  * PAGE 1 object lookup 2
30  * ...
31  * PAGE n-1 object lookup n
32  * PAGE n object data 1
33  * PAGE n+1 object data 2
34  * ...
35  * PAGE n+m-1 object data m
36  *
37  * BLOCK 1 PAGE n+m object lookup 1
38  * PAGE n+m+1 object lookup 2
39  * ...
40  * PAGE 2n+m-1 object lookup n
41  * PAGE 2n+m object data 1
42  * PAGE 2n+m object data 2
43  * ...
44  * PAGE 2n+2m-1 object data m
45  * ...
46  *
47  * n is number of object lookup pages, which is number of pages needed to index all pages
48  * in a block by object id
49  * : block_size / page_size * sizeof(obj_id) / page_size
50  * m is number data pages, which is number of pages in block minus number of lookup pages
51  * : block_size / page_size - block_size / page_size * sizeof(obj_id) / page_size
52  * thus, n+m is total number of pages in a block
53  * : block_size / page_size
54  *
55  * ex: n = 65536/256*2/256 = 2, m = 65536/256 - 2 = 254 => n+m = 65536/256 = 256
56  *
57  * Object lookup pages contain object id entries. Each entry represent the corresponding
58  * data page.
59  * Assuming a 16 bit object id, an object id being 0xffff represents a free page.
60  * An object id being 0x0000 represents a deleted page.
61  *
62  * ex: page 0 : lookup : 0008 0001 0aaa ffff ffff ffff ffff ffff ..
63  * page 1 : lookup : ffff ffff ffff ffff ffff ffff ffff ffff ..
64  * page 2 : data : data for object id 0008
65  * page 3 : data : data for object id 0001
66  * page 4 : data : data for object id 0aaa
67  * ...
68  *
69  *
70  * Object data pages can be either object index pages or object content.
71  * All object data pages contains a data page header, containing object id and span index.
72  * The span index denotes the object page ordering amongst data pages with same object id.
73  * This applies to both object index pages (when index spans more than one page of entries),
74  * and object data pages.
75  * An object index page contains page entries pointing to object content page. The entry index
76  * in a object index page correlates to the span index in the actual object data page.
77  * The first object index page (span index 0) is called object index header page, and also
78  * contains object flags (directory/file), size, object name etc.
79  *
80  * ex:
81  * BLOCK 1
82  * PAGE 256: objectl lookup page 1
83  * [*123] [ 123] [ 123] [ 123]
84  * [ 123] [*123] [ 123] [ 123]
85  * [free] [free] [free] [free] ...
86  * PAGE 257: objectl lookup page 2
87  * [free] [free] [free] [free] ...
88  * PAGE 258: object index page (header)
89  * obj.id:0123 span.ix:0000 flags:INDEX
90  * size:1600 name:ex.txt type:file
91  * [259] [260] [261] [262]
92  * PAGE 259: object data page
93  * obj.id:0123 span.ix:0000 flags:DATA
94  * PAGE 260: object data page
95  * obj.id:0123 span.ix:0001 flags:DATA
96  * PAGE 261: object data page
97  * obj.id:0123 span.ix:0002 flags:DATA
98  * PAGE 262: object data page
99  * obj.id:0123 span.ix:0003 flags:DATA
100  * PAGE 263: object index page
101  * obj.id:0123 span.ix:0001 flags:INDEX
102  * [264] [265] [fre] [fre]
103  * [fre] [fre] [fre] [fre]
104  * PAGE 264: object data page
105  * obj.id:0123 span.ix:0004 flags:DATA
106  * PAGE 265: object data page
107  * obj.id:0123 span.ix:0005 flags:DATA
108  *
109  */
110 #ifndef SPIFFS_NUCLEUS_H_
111 #define SPIFFS_NUCLEUS_H_
112 
113 #define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1)
114 #define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1)
115 #define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2)
116 #define SPIFFS_ERR_CHECK_FLAGS_BAD (SPIFFS_ERR_INTERNAL - 3)
117 #define _SPIFFS_ERR_CHECK_LAST (SPIFFS_ERR_INTERNAL - 4)
118 
119 #define SPIFFS_VIS_COUNTINUE (SPIFFS_ERR_INTERNAL - 20)
120 #define SPIFFS_VIS_COUNTINUE_RELOAD (SPIFFS_ERR_INTERNAL - 21)
121 #define SPIFFS_VIS_END (SPIFFS_ERR_INTERNAL - 22)
122 
123 #define SPIFFS_EV_IX_UPD 0
124 #define SPIFFS_EV_IX_NEW 1
125 #define SPIFFS_EV_IX_DEL 2
126 
127 #define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1)))
128 
129 #define SPIFFS_UNDEFINED_LEN (u32_t)(-1)
130 
131 #define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
132 #define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
133 
134 #define SPIFFS_MAGIC(fs) ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
135 
136 #define SPIFFS_CONFIG_MAGIC (0x20090315)
137 
138 #if SPIFFS_SINGLETON == 0
139 #define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
140  ((fs)->cfg.log_page_size)
141 #define SPIFFS_CFG_LOG_BLOCK_SZ(fs) \
142  ((fs)->cfg.log_block_size)
143 #define SPIFFS_CFG_PHYS_SZ(fs) \
144  ((fs)->cfg.phys_size)
145 #define SPIFFS_CFG_PHYS_ERASE_SZ(fs) \
146  ((fs)->cfg.phys_erase_block)
147 #define SPIFFS_CFG_PHYS_ADDR(fs) \
148  ((fs)->cfg.phys_addr)
149 #endif
150 
151 // total number of pages
152 #define SPIFFS_MAX_PAGES(fs) \
153  ( SPIFFS_CFG_PHYS_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) )
154 // total number of pages per block, including object lookup pages
155 #define SPIFFS_PAGES_PER_BLOCK(fs) \
156  ( SPIFFS_CFG_LOG_BLOCK_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) )
157 // number of object lookup pages per block
158 #define SPIFFS_OBJ_LOOKUP_PAGES(fs) \
159  (MAX(1, (SPIFFS_PAGES_PER_BLOCK(fs) * sizeof(spiffs_obj_id)) / SPIFFS_CFG_LOG_PAGE_SZ(fs)) )
160 // checks if page index belongs to object lookup
161 #define SPIFFS_IS_LOOKUP_PAGE(fs,pix) \
162  (((pix) % SPIFFS_PAGES_PER_BLOCK(fs)) < SPIFFS_OBJ_LOOKUP_PAGES(fs))
163 // number of object lookup entries in all object lookup pages
164 #define SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) \
165  (SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))
166 // converts a block to physical address
167 #define SPIFFS_BLOCK_TO_PADDR(fs, block) \
168  ( SPIFFS_CFG_PHYS_ADDR(fs) + (block)* SPIFFS_CFG_LOG_BLOCK_SZ(fs) )
169 // converts a object lookup entry to page index
170 #define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, block, entry) \
171  ((block)*SPIFFS_PAGES_PER_BLOCK(fs) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry))
172 // converts a object lookup entry to physical address of corresponding page
173 #define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, block, entry) \
174  (SPIFFS_BLOCK_TO_PADDR(fs, block) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry) * SPIFFS_CFG_LOG_PAGE_SZ(fs) )
175 // converts a page to physical address
176 #define SPIFFS_PAGE_TO_PADDR(fs, page) \
177  ( SPIFFS_CFG_PHYS_ADDR(fs) + (page) * SPIFFS_CFG_LOG_PAGE_SZ(fs) )
178 // converts a physical address to page
179 #define SPIFFS_PADDR_TO_PAGE(fs, addr) \
180  ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) / SPIFFS_CFG_LOG_PAGE_SZ(fs) )
181 // gives index in page for a physical address
182 #define SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr) \
183  ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) % SPIFFS_CFG_LOG_PAGE_SZ(fs) )
184 // returns containing block for given page
185 #define SPIFFS_BLOCK_FOR_PAGE(fs, page) \
186  ( (page) / SPIFFS_PAGES_PER_BLOCK(fs) )
187 // returns starting page for block
188 #define SPIFFS_PAGE_FOR_BLOCK(fs, block) \
189  ( (block) * SPIFFS_PAGES_PER_BLOCK(fs) )
190 // converts page to entry in object lookup page
191 #define SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, page) \
192  ( (page) % SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) )
193 // returns data size in a data page
194 #define SPIFFS_DATA_PAGE_SIZE(fs) \
195  ( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) )
196 // returns physical address for block's erase count,
197 // always in the physical last entry of the last object lookup page
198 #define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \
199  ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) )
200 // returns physical address for block's magic,
201 // always in the physical second last entry of the last object lookup page
202 #define SPIFFS_MAGIC_PADDR(fs, bix) \
203  ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 )
204 // checks if there is any room for magic in the object luts
205 #define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \
206  ( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \
207  <= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) )
208 
209 // define helpers object
210 
211 // entries in an object header page index
212 #define SPIFFS_OBJ_HDR_IX_LEN(fs) \
213  ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header))/sizeof(spiffs_page_ix))
214 // entries in an object page index
215 #define SPIFFS_OBJ_IX_LEN(fs) \
216  ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix))/sizeof(spiffs_page_ix))
217 // object index entry for given data span index
218 #define SPIFFS_OBJ_IX_ENTRY(fs, spix) \
219  ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? (spix) : (((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))%SPIFFS_OBJ_IX_LEN(fs)))
220 // object index span index number for given data span index or entry
221 #define SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, spix) \
222  ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? 0 : (1+((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))/SPIFFS_OBJ_IX_LEN(fs)))
223 
224 
225 #define SPIFFS_OP_T_OBJ_LU (0<<0)
226 #define SPIFFS_OP_T_OBJ_LU2 (1<<0)
227 #define SPIFFS_OP_T_OBJ_IX (2<<0)
228 #define SPIFFS_OP_T_OBJ_DA (3<<0)
229 #define SPIFFS_OP_C_DELE (0<<2)
230 #define SPIFFS_OP_C_UPDT (1<<2)
231 #define SPIFFS_OP_C_MOVS (2<<2)
232 #define SPIFFS_OP_C_MOVD (3<<2)
233 #define SPIFFS_OP_C_FLSH (4<<2)
234 #define SPIFFS_OP_C_READ (5<<2)
235 #define SPIFFS_OP_C_WRTHRU (6<<2)
236 
237 #define SPIFFS_OP_TYPE_MASK (3<<0)
238 #define SPIFFS_OP_COM_MASK (7<<2)
239 
240 
241 // if 0, this page is written to, else clean
242 #define SPIFFS_PH_FLAG_USED (1<<0)
243 // if 0, writing is finalized, else under modification
244 #define SPIFFS_PH_FLAG_FINAL (1<<1)
245 // if 0, this is an index page, else a data page
246 #define SPIFFS_PH_FLAG_INDEX (1<<2)
247 // if 0, page is deleted, else valid
248 #define SPIFFS_PH_FLAG_DELET (1<<7)
249 // if 0, this index header is being deleted
250 #define SPIFFS_PH_FLAG_IXDELE (1<<6)
251 
252 
253 #define SPIFFS_CHECK_MOUNT(fs) \
254  ((fs)->mounted != 0)
255 
256 #define SPIFFS_CHECK_CFG(fs) \
257  ((fs)->config_magic == SPIFFS_CONFIG_MAGIC)
258 
259 #define SPIFFS_CHECK_RES(res) \
260  do { \
261  if ((res) < SPIFFS_OK) return (res); \
262  } while (0);
263 
264 #define SPIFFS_API_CHECK_MOUNT(fs) \
265  if (!SPIFFS_CHECK_MOUNT((fs))) { \
266  (fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \
267  return -1; \
268  }
269 
270 #define SPIFFS_API_CHECK_CFG(fs) \
271  if (!SPIFFS_CHECK_CFG((fs))) { \
272  (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \
273  return -1; \
274  }
275 
276 #define SPIFFS_API_CHECK_RES(fs, res) \
277  if ((res) < SPIFFS_OK) { \
278  (fs)->err_code = (res); \
279  return -1; \
280  }
281 
282 #define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \
283  if ((res) < SPIFFS_OK) { \
284  (fs)->err_code = (res); \
285  SPIFFS_UNLOCK(fs); \
286  return -1; \
287  }
288 
289 #define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \
290  if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \
291  if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \
292  if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \
293  if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \
294  if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \
295  if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH;
296  //if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED;
297 
298 #define SPIFFS_VALIDATE_DATA(ph, objid, spix) \
299  if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \
300  if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \
301  if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \
302  if (((ph).flags & SPIFFS_PH_FLAG_INDEX) == 0) return SPIFFS_ERR_IS_INDEX; \
303  if ((objid) & SPIFFS_OBJ_ID_IX_FLAG) return SPIFFS_ERR_IS_INDEX; \
304  if ((ph).span_ix != (spix)) return SPIFFS_ERR_DATA_SPAN_MISMATCH;
305 
306 
307 // check id
308 #define SPIFFS_VIS_CHECK_ID (1<<0)
309 // report argument object id to visitor - else object lookup id is reported
310 #define SPIFFS_VIS_CHECK_PH (1<<1)
311 // stop searching at end of all look up pages
312 #define SPIFFS_VIS_NO_WRAP (1<<2)
313 
314 #if SPIFFS_HAL_CALLBACK_EXTRA
315 
316 #define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
317  (_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src))
318 #define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
319  (_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst))
320 #define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
321  (_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len))
322 
323 #else // SPIFFS_HAL_CALLBACK_EXTRA
324 
325 #define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
326  (_fs)->cfg.hal_write_f((_paddr), (_len), (_src))
327 #define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
328  (_fs)->cfg.hal_read_f((_paddr), (_len), (_dst))
329 #define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
330  (_fs)->cfg.hal_erase_f((_paddr), (_len))
331 
332 #endif // SPIFFS_HAL_CALLBACK_EXTRA
333 
334 #if SPIFFS_CACHE
335 
336 #define SPIFFS_CACHE_FLAG_DIRTY (1<<0)
337 #define SPIFFS_CACHE_FLAG_WRTHRU (1<<1)
338 #define SPIFFS_CACHE_FLAG_OBJLU (1<<2)
339 #define SPIFFS_CACHE_FLAG_OBJIX (1<<3)
340 #define SPIFFS_CACHE_FLAG_DATA (1<<4)
341 #define SPIFFS_CACHE_FLAG_TYPE_WR (1<<7)
342 
343 #define SPIFFS_CACHE_PAGE_SIZE(fs) \
344  (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs))
345 
346 #define spiffs_get_cache(fs) \
347  ((spiffs_cache *)((fs)->cache))
348 
349 #define spiffs_get_cache_page_hdr(fs, c, ix) \
350  ((spiffs_cache_page *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])))
351 
352 #define spiffs_get_cache_page(fs, c, ix) \
353  ((u8_t *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])) + sizeof(spiffs_cache_page))
354 
355 // cache page struct
356 typedef struct {
357  // cache flags
358  u8_t flags;
359  // cache page index
360  u8_t ix;
361  // last access of this cache page
362  u32_t last_access;
363  union {
364  // type read cache
365  struct {
366  // read cache page index
367  spiffs_page_ix pix;
368  };
369 #if SPIFFS_CACHE_WR
370  // type write cache
371  struct {
372  // write cache
373  spiffs_obj_id obj_id;
374  // offset in cache page
375  u32_t offset;
376  // size of cache page
377  u16_t size;
378  };
379 #endif
380  };
381 } spiffs_cache_page;
382 
383 // cache struct
384 typedef struct {
385  u8_t cpage_count;
386  u32_t last_access;
387  u32_t cpage_use_map;
388  u32_t cpage_use_mask;
389  u8_t *cpages;
390 } spiffs_cache;
391 
392 #endif
393 
394 
395 // spiffs nucleus file descriptor
396 typedef struct {
397  // the filesystem of this descriptor
399  // number of file descriptor - if 0, the file descriptor is closed
400  spiffs_file file_nbr;
401  // object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted
402  spiffs_obj_id obj_id;
403  // size of the file
404  u32_t size;
405  // cached object index header page index
406  spiffs_page_ix objix_hdr_pix;
407  // cached offset object index page index
408  spiffs_page_ix cursor_objix_pix;
409  // cached offset object index span index
410  spiffs_span_ix cursor_objix_spix;
411  // current absolute offset
412  u32_t offset;
413  // current file descriptor offset
414  u32_t fdoffset;
415  // fd flags
416  spiffs_flags flags;
417 #if SPIFFS_CACHE_WR
418  spiffs_cache_page *cache_page;
419 #endif
420 } spiffs_fd;
421 
422 
423 // object structs
424 
425 // page header, part of each page except object lookup pages
426 // NB: this is always aligned when the data page is an object index,
427 // as in this case struct spiffs_page_object_ix is used
428 typedef struct __attribute(( packed )) {
429  // object id
430  spiffs_obj_id obj_id;
431  // object span index
432  spiffs_span_ix span_ix;
433  // flags
434  u8_t flags;
435 } spiffs_page_header;
436 
437 // object index header page header
438 typedef struct __attribute(( packed ))
439 #if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
440  __attribute(( aligned(sizeof(spiffs_page_ix)) ))
441 #endif
442 {
443  // common page header
444  spiffs_page_header p_hdr;
445  // alignment
446  u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
447  // size of object
448  u32_t size;
449  // type of object
450  spiffs_obj_type type;
451  // name of object
452  u8_t name[SPIFFS_OBJ_NAME_LEN];
453 } spiffs_page_object_ix_header;
454 
455 // object index page header
456 typedef struct __attribute(( packed )) {
457  spiffs_page_header p_hdr;
458  u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
459 } spiffs_page_object_ix;
460 
461 // callback func for object lookup visitor
462 typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry,
463  const void *user_const_p, void *user_var_p);
464 
465 
466 #if SPIFFS_CACHE
467 #define _spiffs_rd(fs, op, fh, addr, len, dst) \
468  spiffs_phys_rd((fs), (op), (fh), (addr), (len), (dst))
469 #define _spiffs_wr(fs, op, fh, addr, len, src) \
470  spiffs_phys_wr((fs), (op), (fh), (addr), (len), (src))
471 #else
472 #define _spiffs_rd(fs, op, fh, addr, len, dst) \
473  spiffs_phys_rd((fs), (addr), (len), (dst))
474 #define _spiffs_wr(fs, op, fh, addr, len, src) \
475  spiffs_phys_wr((fs), (addr), (len), (src))
476 #endif
477 
478 #ifndef MIN
479 #define MIN(a,b) ((a) < (b) ? (a) : (b))
480 #endif
481 #ifndef MAX
482 #define MAX(a,b) ((a) > (b) ? (a) : (b))
483 #endif
484 
485 // ---------------
486 
487 s32_t spiffs_phys_rd(
488  spiffs *fs,
489 #if SPIFFS_CACHE
490  u8_t op,
491  spiffs_file fh,
492 #endif
493  u32_t addr,
494  u32_t len,
495  u8_t *dst);
496 
497 s32_t spiffs_phys_wr(
498  spiffs *fs,
499 #if SPIFFS_CACHE
500  u8_t op,
501  spiffs_file fh,
502 #endif
503  u32_t addr,
504  u32_t len,
505  u8_t *src);
506 
507 s32_t spiffs_phys_cpy(
508  spiffs *fs,
509  spiffs_file fh,
510  u32_t dst,
511  u32_t src,
512  u32_t len);
513 
514 s32_t spiffs_phys_count_free_blocks(
515  spiffs *fs);
516 
517 s32_t spiffs_obj_lu_find_entry_visitor(
518  spiffs *fs,
519  spiffs_block_ix starting_block,
520  int starting_lu_entry,
521  u8_t flags,
522  spiffs_obj_id obj_id,
523  spiffs_visitor_f v,
524  const void *user_const_p,
525  void *user_var_p,
526  spiffs_block_ix *block_ix,
527  int *lu_entry);
528 
529 s32_t spiffs_erase_block(
530  spiffs *fs,
531  spiffs_block_ix bix);
532 
533 // ---------------
534 
535 s32_t spiffs_obj_lu_scan(
536  spiffs *fs);
537 
538 s32_t spiffs_obj_lu_find_free_obj_id(
539  spiffs *fs,
540  spiffs_obj_id *obj_id,
541  const u8_t *conflicting_name);
542 
543 s32_t spiffs_obj_lu_find_free(
544  spiffs *fs,
545  spiffs_block_ix starting_block,
546  int starting_lu_entry,
547  spiffs_block_ix *block_ix,
548  int *lu_entry);
549 
550 s32_t spiffs_obj_lu_find_id(
551  spiffs *fs,
552  spiffs_block_ix starting_block,
553  int starting_lu_entry,
554  spiffs_obj_id obj_id,
555  spiffs_block_ix *block_ix,
556  int *lu_entry);
557 
558 s32_t spiffs_obj_lu_find_id_and_span(
559  spiffs *fs,
560  spiffs_obj_id obj_id,
561  spiffs_span_ix spix,
562  spiffs_page_ix exclusion_pix,
563  spiffs_page_ix *pix);
564 
565 s32_t spiffs_obj_lu_find_id_and_span_by_phdr(
566  spiffs *fs,
567  spiffs_obj_id obj_id,
568  spiffs_span_ix spix,
569  spiffs_page_ix exclusion_pix,
570  spiffs_page_ix *pix);
571 
572 // ---------------
573 
574 s32_t spiffs_page_allocate_data(
575  spiffs *fs,
576  spiffs_obj_id obj_id,
577  spiffs_page_header *ph,
578  u8_t *data,
579  u32_t len,
580  u32_t page_offs,
581  u8_t finalize,
582  spiffs_page_ix *pix);
583 
584 s32_t spiffs_page_move(
585  spiffs *fs,
586  spiffs_file fh,
587  u8_t *page_data,
588  spiffs_obj_id obj_id,
589  spiffs_page_header *page_hdr,
590  spiffs_page_ix src_pix,
591  spiffs_page_ix *dst_pix);
592 
593 s32_t spiffs_page_delete(
594  spiffs *fs,
595  spiffs_page_ix pix);
596 
597 // ---------------
598 
599 s32_t spiffs_object_create(
600  spiffs *fs,
601  spiffs_obj_id obj_id,
602  const u8_t name[SPIFFS_OBJ_NAME_LEN],
603  spiffs_obj_type type,
604  spiffs_page_ix *objix_hdr_pix);
605 
606 s32_t spiffs_object_update_index_hdr(
607  spiffs *fs,
608  spiffs_fd *fd,
609  spiffs_obj_id obj_id,
610  spiffs_page_ix objix_hdr_pix,
611  u8_t *new_objix_hdr_data,
612  const u8_t name[SPIFFS_OBJ_NAME_LEN],
613  u32_t size,
614  spiffs_page_ix *new_pix);
615 
616 void spiffs_cb_object_event(
617  spiffs *fs,
618  spiffs_fd *fd,
619  int ev,
620  spiffs_obj_id obj_id,
621  spiffs_span_ix spix,
622  spiffs_page_ix new_pix,
623  u32_t new_size);
624 
625 s32_t spiffs_object_open_by_id(
626  spiffs *fs,
627  spiffs_obj_id obj_id,
628  spiffs_fd *f,
629  spiffs_flags flags,
630  spiffs_mode mode);
631 
632 s32_t spiffs_object_open_by_page(
633  spiffs *fs,
634  spiffs_page_ix pix,
635  spiffs_fd *f,
636  spiffs_flags flags,
637  spiffs_mode mode);
638 
639 s32_t spiffs_object_append(
640  spiffs_fd *fd,
641  u32_t offset,
642  u8_t *data,
643  u32_t len);
644 
645 s32_t spiffs_object_modify(
646  spiffs_fd *fd,
647  u32_t offset,
648  u8_t *data,
649  u32_t len);
650 
651 s32_t spiffs_object_read(
652  spiffs_fd *fd,
653  u32_t offset,
654  u32_t len,
655  u8_t *dst);
656 
657 s32_t spiffs_object_truncate(
658  spiffs_fd *fd,
659  u32_t new_len,
660  u8_t remove_object);
661 
662 s32_t spiffs_object_find_object_index_header_by_name(
663  spiffs *fs,
664  const u8_t name[SPIFFS_OBJ_NAME_LEN],
665  spiffs_page_ix *pix);
666 
667 // ---------------
668 
669 s32_t spiffs_gc_check(
670  spiffs *fs,
671  u32_t len);
672 
673 s32_t spiffs_gc_erase_page_stats(
674  spiffs *fs,
675  spiffs_block_ix bix);
676 
677 s32_t spiffs_gc_find_candidate(
678  spiffs *fs,
679  spiffs_block_ix **block_candidate,
680  int *candidate_count,
681  char fs_crammed);
682 
683 s32_t spiffs_gc_clean(
684  spiffs *fs,
685  spiffs_block_ix bix);
686 
687 s32_t spiffs_gc_quick(
688  spiffs *fs, u16_t max_free_pages);
689 
690 // ---------------
691 
692 s32_t spiffs_fd_find_new(
693  spiffs *fs,
694  spiffs_fd **fd);
695 
696 s32_t spiffs_fd_return(
697  spiffs *fs,
698  spiffs_file f);
699 
700 s32_t spiffs_fd_get(
701  spiffs *fs,
702  spiffs_file f,
703  spiffs_fd **fd);
704 
705 #if SPIFFS_CACHE
706 void spiffs_cache_init(
707  spiffs *fs);
708 
709 void spiffs_cache_drop_page(
710  spiffs *fs,
711  spiffs_page_ix pix);
712 
713 #if SPIFFS_CACHE_WR
714 spiffs_cache_page *spiffs_cache_page_allocate_by_fd(
715  spiffs *fs,
716  spiffs_fd *fd);
717 
718 void spiffs_cache_fd_release(
719  spiffs *fs,
720  spiffs_cache_page *cp);
721 
722 spiffs_cache_page *spiffs_cache_page_get_by_fd(
723  spiffs *fs,
724  spiffs_fd *fd);
725 #endif
726 #endif
727 
728 s32_t spiffs_lookup_consistency_check(
729  spiffs *fs,
730  u8_t check_all_objects);
731 
732 s32_t spiffs_page_consistency_check(
733  spiffs *fs);
734 
735 s32_t spiffs_object_index_consistency_check(
736  spiffs *fs);
737 
738 #endif /* SPIFFS_NUCLEUS_H_ */
u32_t size
Definition: spiffs.h:271
u32_t offset
Definition: spiffs_nucleus.h:412
spiffs_span_ix cursor_objix_spix
Definition: spiffs_nucleus.h:410
u32_t size
Definition: spiffs_nucleus.h:404
spiffs_file file_nbr
Definition: spiffs_nucleus.h:400
spiffs_page_ix objix_hdr_pix
Definition: spiffs_nucleus.h:406
Definition: ESP8266WebServer.h:55
spiffs_page_ix cursor_objix_pix
Definition: spiffs_nucleus.h:408
Definition: spiffs.h:195
spiffs * fs
Definition: spiffs_nucleus.h:398
spiffs_page_ix pix
Definition: spiffs.h:272
spiffs_obj_id obj_id
Definition: spiffs_nucleus.h:402
spiffs_flags flags
Definition: spiffs_nucleus.h:416
Definition: spiffs_nucleus.h:396
u32_t fdoffset
Definition: spiffs_nucleus.h:414
spiffs_obj_id obj_id
Definition: spiffs.h:268