-

Committer:
aguscahya
Date:
Thu Apr 22 03:49:45 2021 +0000
Revision:
0:1f44439df816
-

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aguscahya 0:1f44439df816 1 /*
aguscahya 0:1f44439df816 2 * spiffs_hydrogen.c
aguscahya 0:1f44439df816 3 *
aguscahya 0:1f44439df816 4 * Created on: Jun 16, 2013
aguscahya 0:1f44439df816 5 * Author: petera
aguscahya 0:1f44439df816 6 */
aguscahya 0:1f44439df816 7
aguscahya 0:1f44439df816 8 #include "spiffs.h"
aguscahya 0:1f44439df816 9 #include "spiffs_nucleus.h"
aguscahya 0:1f44439df816 10
aguscahya 0:1f44439df816 11 static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh);
aguscahya 0:1f44439df816 12
aguscahya 0:1f44439df816 13 #if SPIFFS_BUFFER_HELP
aguscahya 0:1f44439df816 14 u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) {
aguscahya 0:1f44439df816 15 return num_descs * sizeof(spiffs_fd);
aguscahya 0:1f44439df816 16 }
aguscahya 0:1f44439df816 17 #if SPIFFS_CACHE
aguscahya 0:1f44439df816 18 u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) {
aguscahya 0:1f44439df816 19 return sizeof(spiffs_cache) + num_pages * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs));
aguscahya 0:1f44439df816 20 }
aguscahya 0:1f44439df816 21 #endif
aguscahya 0:1f44439df816 22 #endif
aguscahya 0:1f44439df816 23
aguscahya 0:1f44439df816 24 s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
aguscahya 0:1f44439df816 25 u8_t *fd_space, u32_t fd_space_size,
aguscahya 0:1f44439df816 26 u8_t *cache, u32_t cache_size,
aguscahya 0:1f44439df816 27 spiffs_check_callback check_cb_f) {
aguscahya 0:1f44439df816 28 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 29 memset(fs, 0, sizeof(spiffs));
aguscahya 0:1f44439df816 30 memcpy(&fs->cfg, config, sizeof(spiffs_config));
aguscahya 0:1f44439df816 31 fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs);
aguscahya 0:1f44439df816 32 fs->work = &work[0];
aguscahya 0:1f44439df816 33 fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)];
aguscahya 0:1f44439df816 34 memset(fd_space, 0, fd_space_size);
aguscahya 0:1f44439df816 35 // align fd_space pointer to pointer size byte boundary, below is safe
aguscahya 0:1f44439df816 36 u8_t ptr_size = sizeof(void*);
aguscahya 0:1f44439df816 37 #pragma GCC diagnostic push
aguscahya 0:1f44439df816 38 #pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
aguscahya 0:1f44439df816 39 u8_t addr_lsb = ((u8_t)fd_space) & (ptr_size-1);
aguscahya 0:1f44439df816 40 #pragma GCC diagnostic pop
aguscahya 0:1f44439df816 41 if (addr_lsb) {
aguscahya 0:1f44439df816 42 fd_space += (ptr_size-addr_lsb);
aguscahya 0:1f44439df816 43 fd_space_size -= (ptr_size-addr_lsb);
aguscahya 0:1f44439df816 44 }
aguscahya 0:1f44439df816 45 fs->fd_space = fd_space;
aguscahya 0:1f44439df816 46 fs->fd_count = (fd_space_size/sizeof(spiffs_fd));
aguscahya 0:1f44439df816 47
aguscahya 0:1f44439df816 48 // align cache pointer to 4 byte boundary, below is safe
aguscahya 0:1f44439df816 49 #pragma GCC diagnostic push
aguscahya 0:1f44439df816 50 #pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
aguscahya 0:1f44439df816 51 addr_lsb = ((u8_t)cache) & (ptr_size-1);
aguscahya 0:1f44439df816 52 #pragma GCC diagnostic pop
aguscahya 0:1f44439df816 53 if (addr_lsb) {
aguscahya 0:1f44439df816 54 cache += (ptr_size-addr_lsb);
aguscahya 0:1f44439df816 55 cache_size -= (ptr_size-addr_lsb);
aguscahya 0:1f44439df816 56 }
aguscahya 0:1f44439df816 57 if (cache_size & (ptr_size-1)) {
aguscahya 0:1f44439df816 58 cache_size -= (cache_size & (ptr_size-1));
aguscahya 0:1f44439df816 59 }
aguscahya 0:1f44439df816 60 #if SPIFFS_CACHE
aguscahya 0:1f44439df816 61 fs->cache = cache;
aguscahya 0:1f44439df816 62 fs->cache_size = cache_size;
aguscahya 0:1f44439df816 63 spiffs_cache_init(fs);
aguscahya 0:1f44439df816 64 #endif
aguscahya 0:1f44439df816 65
aguscahya 0:1f44439df816 66 s32_t res = spiffs_obj_lu_scan(fs);
aguscahya 0:1f44439df816 67 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 68
aguscahya 0:1f44439df816 69 SPIFFS_DBG("page index byte len: %i\n", SPIFFS_CFG_LOG_PAGE_SZ(fs));
aguscahya 0:1f44439df816 70 SPIFFS_DBG("object lookup pages: %i\n", SPIFFS_OBJ_LOOKUP_PAGES(fs));
aguscahya 0:1f44439df816 71 SPIFFS_DBG("page pages per block: %i\n", SPIFFS_PAGES_PER_BLOCK(fs));
aguscahya 0:1f44439df816 72 SPIFFS_DBG("page header length: %i\n", sizeof(spiffs_page_header));
aguscahya 0:1f44439df816 73 SPIFFS_DBG("object header index entries: %i\n", SPIFFS_OBJ_HDR_IX_LEN(fs));
aguscahya 0:1f44439df816 74 SPIFFS_DBG("object index entries: %i\n", SPIFFS_OBJ_IX_LEN(fs));
aguscahya 0:1f44439df816 75 SPIFFS_DBG("available file descriptors: %i\n", fs->fd_count);
aguscahya 0:1f44439df816 76 SPIFFS_DBG("free blocks: %i\n", fs->free_blocks);
aguscahya 0:1f44439df816 77
aguscahya 0:1f44439df816 78 fs->check_cb_f = check_cb_f;
aguscahya 0:1f44439df816 79
aguscahya 0:1f44439df816 80 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 81
aguscahya 0:1f44439df816 82 return 0;
aguscahya 0:1f44439df816 83 }
aguscahya 0:1f44439df816 84
aguscahya 0:1f44439df816 85 void SPIFFS_unmount(spiffs *fs) {
aguscahya 0:1f44439df816 86 if (!SPIFFS_CHECK_MOUNT(fs)) return;
aguscahya 0:1f44439df816 87 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 88 int i;
aguscahya 0:1f44439df816 89 spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
aguscahya 0:1f44439df816 90 for (i = 0; i < fs->fd_count; i++) {
aguscahya 0:1f44439df816 91 spiffs_fd *cur_fd = &fds[i];
aguscahya 0:1f44439df816 92 if (cur_fd->file_nbr != 0) {
aguscahya 0:1f44439df816 93 #if SPIFFS_CACHE
aguscahya 0:1f44439df816 94 (void)spiffs_fflush_cache(fs, cur_fd->file_nbr);
aguscahya 0:1f44439df816 95 #endif
aguscahya 0:1f44439df816 96 spiffs_fd_return(fs, cur_fd->file_nbr);
aguscahya 0:1f44439df816 97 }
aguscahya 0:1f44439df816 98 }
aguscahya 0:1f44439df816 99 fs->block_count = 0;
aguscahya 0:1f44439df816 100 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 101 }
aguscahya 0:1f44439df816 102
aguscahya 0:1f44439df816 103 s32_t SPIFFS_errno(spiffs *fs) {
aguscahya 0:1f44439df816 104 return fs->errno;
aguscahya 0:1f44439df816 105 }
aguscahya 0:1f44439df816 106
aguscahya 0:1f44439df816 107 s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) {
aguscahya 0:1f44439df816 108 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 109 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 110 spiffs_obj_id obj_id;
aguscahya 0:1f44439df816 111 s32_t res;
aguscahya 0:1f44439df816 112
aguscahya 0:1f44439df816 113 res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id);
aguscahya 0:1f44439df816 114 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 115 res = spiffs_object_create(fs, obj_id, (u8_t*)path, SPIFFS_TYPE_FILE, 0);
aguscahya 0:1f44439df816 116 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 117 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 118 return 0;
aguscahya 0:1f44439df816 119 }
aguscahya 0:1f44439df816 120
aguscahya 0:1f44439df816 121 spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) {
aguscahya 0:1f44439df816 122 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 123 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 124
aguscahya 0:1f44439df816 125 spiffs_fd *fd;
aguscahya 0:1f44439df816 126 spiffs_page_ix pix;
aguscahya 0:1f44439df816 127
aguscahya 0:1f44439df816 128 s32_t res = spiffs_fd_find_new(fs, &fd);
aguscahya 0:1f44439df816 129 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 130
aguscahya 0:1f44439df816 131 res = spiffs_object_find_object_index_header_by_name(fs, (u8_t*)path, &pix);
aguscahya 0:1f44439df816 132 if ((flags & SPIFFS_CREAT) == 0) {
aguscahya 0:1f44439df816 133 if (res < SPIFFS_OK) {
aguscahya 0:1f44439df816 134 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 135 }
aguscahya 0:1f44439df816 136 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 137 }
aguscahya 0:1f44439df816 138
aguscahya 0:1f44439df816 139 if ((flags & SPIFFS_CREAT) && res == SPIFFS_ERR_NOT_FOUND) {
aguscahya 0:1f44439df816 140 spiffs_obj_id obj_id;
aguscahya 0:1f44439df816 141 res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id);
aguscahya 0:1f44439df816 142 if (res < SPIFFS_OK) {
aguscahya 0:1f44439df816 143 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 144 }
aguscahya 0:1f44439df816 145 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 146 res = spiffs_object_create(fs, obj_id, (u8_t*)path, SPIFFS_TYPE_FILE, &pix);
aguscahya 0:1f44439df816 147 if (res < SPIFFS_OK) {
aguscahya 0:1f44439df816 148 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 149 }
aguscahya 0:1f44439df816 150 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 151 flags &= ~SPIFFS_TRUNC;
aguscahya 0:1f44439df816 152 } else {
aguscahya 0:1f44439df816 153 if (res < SPIFFS_OK) {
aguscahya 0:1f44439df816 154 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 155 }
aguscahya 0:1f44439df816 156 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 157 }
aguscahya 0:1f44439df816 158 res = spiffs_object_open_by_page(fs, pix, fd, flags, flags);
aguscahya 0:1f44439df816 159 if (res < SPIFFS_OK) {
aguscahya 0:1f44439df816 160 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 161 }
aguscahya 0:1f44439df816 162 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 163 if (flags & SPIFFS_TRUNC) {
aguscahya 0:1f44439df816 164 res = spiffs_object_truncate(fd, 0, 0);
aguscahya 0:1f44439df816 165 if (res < SPIFFS_OK) {
aguscahya 0:1f44439df816 166 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 167 }
aguscahya 0:1f44439df816 168 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 169 }
aguscahya 0:1f44439df816 170
aguscahya 0:1f44439df816 171 fd->fdoffset = 0;
aguscahya 0:1f44439df816 172
aguscahya 0:1f44439df816 173 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 174
aguscahya 0:1f44439df816 175 return fd->file_nbr;
aguscahya 0:1f44439df816 176 }
aguscahya 0:1f44439df816 177
aguscahya 0:1f44439df816 178 s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
aguscahya 0:1f44439df816 179 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 180 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 181
aguscahya 0:1f44439df816 182 spiffs_fd *fd;
aguscahya 0:1f44439df816 183 s32_t res;
aguscahya 0:1f44439df816 184
aguscahya 0:1f44439df816 185 res = spiffs_fd_get(fs, fh, &fd);
aguscahya 0:1f44439df816 186 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 187
aguscahya 0:1f44439df816 188 if ((fd->flags & SPIFFS_RDONLY) == 0) {
aguscahya 0:1f44439df816 189 res = SPIFFS_ERR_NOT_READABLE;
aguscahya 0:1f44439df816 190 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 191 }
aguscahya 0:1f44439df816 192
aguscahya 0:1f44439df816 193 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 194 spiffs_fflush_cache(fs, fh);
aguscahya 0:1f44439df816 195 #endif
aguscahya 0:1f44439df816 196
aguscahya 0:1f44439df816 197 if (fd->fdoffset + len >= fd->size) {
aguscahya 0:1f44439df816 198 // reading beyond file size
aguscahya 0:1f44439df816 199 s32_t avail = fd->size - fd->fdoffset;
aguscahya 0:1f44439df816 200 if (avail <= 0) {
aguscahya 0:1f44439df816 201 SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT);
aguscahya 0:1f44439df816 202 }
aguscahya 0:1f44439df816 203 res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t*)buf);
aguscahya 0:1f44439df816 204 if (res == SPIFFS_ERR_END_OF_OBJECT) {
aguscahya 0:1f44439df816 205 fd->fdoffset += avail;
aguscahya 0:1f44439df816 206 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 207 return avail;
aguscahya 0:1f44439df816 208 } else {
aguscahya 0:1f44439df816 209 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 210 }
aguscahya 0:1f44439df816 211 } else {
aguscahya 0:1f44439df816 212 // reading within file size
aguscahya 0:1f44439df816 213 res = spiffs_object_read(fd, fd->fdoffset, len, (u8_t*)buf);
aguscahya 0:1f44439df816 214 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 215 }
aguscahya 0:1f44439df816 216 fd->fdoffset += len;
aguscahya 0:1f44439df816 217
aguscahya 0:1f44439df816 218 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 219
aguscahya 0:1f44439df816 220 return len;
aguscahya 0:1f44439df816 221 }
aguscahya 0:1f44439df816 222
aguscahya 0:1f44439df816 223 static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offset, s32_t len) {
aguscahya 0:1f44439df816 224 s32_t res = SPIFFS_OK;
aguscahya 0:1f44439df816 225 s32_t remaining = len;
aguscahya 0:1f44439df816 226 if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) {
aguscahya 0:1f44439df816 227 s32_t m_len = MIN(fd->size - offset, len);
aguscahya 0:1f44439df816 228 res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len);
aguscahya 0:1f44439df816 229 SPIFFS_CHECK_RES(res);
aguscahya 0:1f44439df816 230 remaining -= m_len;
aguscahya 0:1f44439df816 231 buf = (u8_t*)buf + m_len;
aguscahya 0:1f44439df816 232 offset += m_len;
aguscahya 0:1f44439df816 233 }
aguscahya 0:1f44439df816 234 if (remaining > 0) {
aguscahya 0:1f44439df816 235 res = spiffs_object_append(fd, offset, (u8_t *)buf, remaining);
aguscahya 0:1f44439df816 236 SPIFFS_CHECK_RES(res);
aguscahya 0:1f44439df816 237 }
aguscahya 0:1f44439df816 238 return len;
aguscahya 0:1f44439df816 239
aguscahya 0:1f44439df816 240 }
aguscahya 0:1f44439df816 241
aguscahya 0:1f44439df816 242 s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
aguscahya 0:1f44439df816 243 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 244 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 245
aguscahya 0:1f44439df816 246 spiffs_fd *fd;
aguscahya 0:1f44439df816 247 s32_t res;
aguscahya 0:1f44439df816 248 u32_t offset;
aguscahya 0:1f44439df816 249
aguscahya 0:1f44439df816 250 res = spiffs_fd_get(fs, fh, &fd);
aguscahya 0:1f44439df816 251 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 252
aguscahya 0:1f44439df816 253 if ((fd->flags & SPIFFS_WRONLY) == 0) {
aguscahya 0:1f44439df816 254 res = SPIFFS_ERR_NOT_WRITABLE;
aguscahya 0:1f44439df816 255 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 256 }
aguscahya 0:1f44439df816 257
aguscahya 0:1f44439df816 258 offset = fd->fdoffset;
aguscahya 0:1f44439df816 259
aguscahya 0:1f44439df816 260 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 261 if (fd->cache_page == 0) {
aguscahya 0:1f44439df816 262 // see if object id is associated with cache already
aguscahya 0:1f44439df816 263 fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd);
aguscahya 0:1f44439df816 264 }
aguscahya 0:1f44439df816 265 #endif
aguscahya 0:1f44439df816 266 if (fd->flags & SPIFFS_APPEND) {
aguscahya 0:1f44439df816 267 if (fd->size == SPIFFS_UNDEFINED_LEN) {
aguscahya 0:1f44439df816 268 offset = 0;
aguscahya 0:1f44439df816 269 } else {
aguscahya 0:1f44439df816 270 offset = fd->size;
aguscahya 0:1f44439df816 271 }
aguscahya 0:1f44439df816 272 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 273 if (fd->cache_page) {
aguscahya 0:1f44439df816 274 offset = MAX(offset, fd->cache_page->offset + fd->cache_page->size);
aguscahya 0:1f44439df816 275 }
aguscahya 0:1f44439df816 276 #endif
aguscahya 0:1f44439df816 277 }
aguscahya 0:1f44439df816 278
aguscahya 0:1f44439df816 279 SPIFFS_DBG("SPIFFS_write %i %04x offs:%i len %i\n", fh, fd->obj_id, offset, len);
aguscahya 0:1f44439df816 280
aguscahya 0:1f44439df816 281 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 282 if ((fd->flags & SPIFFS_DIRECT) == 0) {
aguscahya 0:1f44439df816 283 if (len < SPIFFS_CFG_LOG_PAGE_SZ(fs)) {
aguscahya 0:1f44439df816 284 // small write, try to cache it
aguscahya 0:1f44439df816 285 u8_t alloc_cpage = 1;
aguscahya 0:1f44439df816 286 if (fd->cache_page) {
aguscahya 0:1f44439df816 287 // have a cached page for this fd already, check cache page boundaries
aguscahya 0:1f44439df816 288 if (offset < fd->cache_page->offset || // writing before cache
aguscahya 0:1f44439df816 289 offset > fd->cache_page->offset + fd->cache_page->size || // writing after cache
aguscahya 0:1f44439df816 290 offset + len > fd->cache_page->offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) // writing beyond cache page
aguscahya 0:1f44439df816 291 {
aguscahya 0:1f44439df816 292 // boundary violation, write back cache first and allocate new
aguscahya 0:1f44439df816 293 SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:&04x, boundary viol, offs:%i size:%i\n",
aguscahya 0:1f44439df816 294 fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size);
aguscahya 0:1f44439df816 295 res = spiffs_hydro_write(fs, fd,
aguscahya 0:1f44439df816 296 spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
aguscahya 0:1f44439df816 297 fd->cache_page->offset, fd->cache_page->size);
aguscahya 0:1f44439df816 298 spiffs_cache_fd_release(fs, fd->cache_page);
aguscahya 0:1f44439df816 299 } else {
aguscahya 0:1f44439df816 300 // writing within cache
aguscahya 0:1f44439df816 301 alloc_cpage = 0;
aguscahya 0:1f44439df816 302 }
aguscahya 0:1f44439df816 303 }
aguscahya 0:1f44439df816 304
aguscahya 0:1f44439df816 305 if (alloc_cpage) {
aguscahya 0:1f44439df816 306 fd->cache_page = spiffs_cache_page_allocate_by_fd(fs, fd);
aguscahya 0:1f44439df816 307 if (fd->cache_page) {
aguscahya 0:1f44439df816 308 fd->cache_page->offset = offset;
aguscahya 0:1f44439df816 309 fd->cache_page->size = 0;
aguscahya 0:1f44439df816 310 SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page %i for fd %i:%04x\n",
aguscahya 0:1f44439df816 311 fd->cache_page->ix, fd->file_nbr, fd->obj_id);
aguscahya 0:1f44439df816 312 }
aguscahya 0:1f44439df816 313 }
aguscahya 0:1f44439df816 314
aguscahya 0:1f44439df816 315 if (fd->cache_page) {
aguscahya 0:1f44439df816 316 u32_t offset_in_cpage = offset - fd->cache_page->offset;
aguscahya 0:1f44439df816 317 SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page %i for fd %i:%04x, offs %i:%i len %i\n",
aguscahya 0:1f44439df816 318 fd->cache_page->ix, fd->file_nbr, fd->obj_id,
aguscahya 0:1f44439df816 319 offset, offset_in_cpage, len);
aguscahya 0:1f44439df816 320 spiffs_cache *cache = spiffs_get_cache(fs);
aguscahya 0:1f44439df816 321 u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix);
aguscahya 0:1f44439df816 322 memcpy(&cpage_data[offset_in_cpage], buf, len);
aguscahya 0:1f44439df816 323 fd->cache_page->size = MAX(fd->cache_page->size, offset_in_cpage + len);
aguscahya 0:1f44439df816 324 fd->fdoffset += len;
aguscahya 0:1f44439df816 325 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 326 return len;
aguscahya 0:1f44439df816 327 } else {
aguscahya 0:1f44439df816 328 res = spiffs_hydro_write(fs, fd, buf, offset, len);
aguscahya 0:1f44439df816 329 SPIFFS_API_CHECK_RES(fs, res);
aguscahya 0:1f44439df816 330 fd->fdoffset += len;
aguscahya 0:1f44439df816 331 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 332 return res;
aguscahya 0:1f44439df816 333 }
aguscahya 0:1f44439df816 334 } else {
aguscahya 0:1f44439df816 335 // big write, no need to cache it - but first check if there is a cached write already
aguscahya 0:1f44439df816 336 if (fd->cache_page) {
aguscahya 0:1f44439df816 337 // write back cache first
aguscahya 0:1f44439df816 338 SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, big write, offs:%i size:%i\n",
aguscahya 0:1f44439df816 339 fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size);
aguscahya 0:1f44439df816 340 res = spiffs_hydro_write(fs, fd,
aguscahya 0:1f44439df816 341 spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
aguscahya 0:1f44439df816 342 fd->cache_page->offset, fd->cache_page->size);
aguscahya 0:1f44439df816 343 spiffs_cache_fd_release(fs, fd->cache_page);
aguscahya 0:1f44439df816 344 res = spiffs_hydro_write(fs, fd, buf, offset, len);
aguscahya 0:1f44439df816 345 SPIFFS_API_CHECK_RES(fs, res);
aguscahya 0:1f44439df816 346 }
aguscahya 0:1f44439df816 347 }
aguscahya 0:1f44439df816 348 }
aguscahya 0:1f44439df816 349 #endif
aguscahya 0:1f44439df816 350
aguscahya 0:1f44439df816 351 res = spiffs_hydro_write(fs, fd, buf, offset, len);
aguscahya 0:1f44439df816 352 SPIFFS_API_CHECK_RES(fs, res);
aguscahya 0:1f44439df816 353 fd->fdoffset += len;
aguscahya 0:1f44439df816 354
aguscahya 0:1f44439df816 355 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 356
aguscahya 0:1f44439df816 357 return res;
aguscahya 0:1f44439df816 358 }
aguscahya 0:1f44439df816 359
aguscahya 0:1f44439df816 360 s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
aguscahya 0:1f44439df816 361 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 362 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 363
aguscahya 0:1f44439df816 364 spiffs_fd *fd;
aguscahya 0:1f44439df816 365 s32_t res;
aguscahya 0:1f44439df816 366 res = spiffs_fd_get(fs, fh, &fd);
aguscahya 0:1f44439df816 367 SPIFFS_API_CHECK_RES(fs, res);
aguscahya 0:1f44439df816 368
aguscahya 0:1f44439df816 369 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 370 spiffs_fflush_cache(fs, fh);
aguscahya 0:1f44439df816 371 #endif
aguscahya 0:1f44439df816 372
aguscahya 0:1f44439df816 373 switch (whence) {
aguscahya 0:1f44439df816 374 case SPIFFS_SEEK_CUR:
aguscahya 0:1f44439df816 375 offs = fd->fdoffset+offs;
aguscahya 0:1f44439df816 376 break;
aguscahya 0:1f44439df816 377 case SPIFFS_SEEK_END:
aguscahya 0:1f44439df816 378 offs = (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size) + offs;
aguscahya 0:1f44439df816 379 break;
aguscahya 0:1f44439df816 380 }
aguscahya 0:1f44439df816 381
aguscahya 0:1f44439df816 382 if (offs > fd->size) {
aguscahya 0:1f44439df816 383 res = SPIFFS_ERR_END_OF_OBJECT;
aguscahya 0:1f44439df816 384 }
aguscahya 0:1f44439df816 385 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 386
aguscahya 0:1f44439df816 387 spiffs_span_ix data_spix = offs / SPIFFS_DATA_PAGE_SIZE(fs);
aguscahya 0:1f44439df816 388 spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix);
aguscahya 0:1f44439df816 389 if (fd->cursor_objix_spix != objix_spix) {
aguscahya 0:1f44439df816 390 spiffs_page_ix pix;
aguscahya 0:1f44439df816 391 res = spiffs_obj_lu_find_id_and_span(
aguscahya 0:1f44439df816 392 fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, &pix);
aguscahya 0:1f44439df816 393 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 394 fd->cursor_objix_spix = objix_spix;
aguscahya 0:1f44439df816 395 fd->cursor_objix_pix = pix;
aguscahya 0:1f44439df816 396 }
aguscahya 0:1f44439df816 397 fd->fdoffset = offs;
aguscahya 0:1f44439df816 398
aguscahya 0:1f44439df816 399 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 400
aguscahya 0:1f44439df816 401 return 0;
aguscahya 0:1f44439df816 402 }
aguscahya 0:1f44439df816 403
aguscahya 0:1f44439df816 404 s32_t SPIFFS_remove(spiffs *fs, const char *path) {
aguscahya 0:1f44439df816 405 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 406 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 407
aguscahya 0:1f44439df816 408 spiffs_fd *fd;
aguscahya 0:1f44439df816 409 spiffs_page_ix pix;
aguscahya 0:1f44439df816 410 s32_t res;
aguscahya 0:1f44439df816 411
aguscahya 0:1f44439df816 412 res = spiffs_fd_find_new(fs, &fd);
aguscahya 0:1f44439df816 413 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 414
aguscahya 0:1f44439df816 415 res = spiffs_object_find_object_index_header_by_name(fs, (u8_t*)path, &pix);
aguscahya 0:1f44439df816 416 if (res != SPIFFS_OK) {
aguscahya 0:1f44439df816 417 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 418 }
aguscahya 0:1f44439df816 419 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 420
aguscahya 0:1f44439df816 421 res = spiffs_object_open_by_page(fs, pix, fd, 0,0);
aguscahya 0:1f44439df816 422 if (res != SPIFFS_OK) {
aguscahya 0:1f44439df816 423 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 424 }
aguscahya 0:1f44439df816 425 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 426
aguscahya 0:1f44439df816 427 res = spiffs_object_truncate(fd, 0, 1);
aguscahya 0:1f44439df816 428 if (res != SPIFFS_OK) {
aguscahya 0:1f44439df816 429 spiffs_fd_return(fs, fd->file_nbr);
aguscahya 0:1f44439df816 430 }
aguscahya 0:1f44439df816 431 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 432
aguscahya 0:1f44439df816 433 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 434 return 0;
aguscahya 0:1f44439df816 435 }
aguscahya 0:1f44439df816 436
aguscahya 0:1f44439df816 437 s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) {
aguscahya 0:1f44439df816 438 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 439 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 440
aguscahya 0:1f44439df816 441 spiffs_fd *fd;
aguscahya 0:1f44439df816 442 s32_t res;
aguscahya 0:1f44439df816 443 res = spiffs_fd_get(fs, fh, &fd);
aguscahya 0:1f44439df816 444 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 445
aguscahya 0:1f44439df816 446 if ((fd->flags & SPIFFS_WRONLY) == 0) {
aguscahya 0:1f44439df816 447 res = SPIFFS_ERR_NOT_WRITABLE;
aguscahya 0:1f44439df816 448 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 449 }
aguscahya 0:1f44439df816 450
aguscahya 0:1f44439df816 451 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 452 spiffs_cache_fd_release(fs, fd->cache_page);
aguscahya 0:1f44439df816 453 #endif
aguscahya 0:1f44439df816 454
aguscahya 0:1f44439df816 455 res = spiffs_object_truncate(fd, 0, 1);
aguscahya 0:1f44439df816 456
aguscahya 0:1f44439df816 457 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 458
aguscahya 0:1f44439df816 459 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 460
aguscahya 0:1f44439df816 461 return 0;
aguscahya 0:1f44439df816 462 }
aguscahya 0:1f44439df816 463
aguscahya 0:1f44439df816 464 static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) {
aguscahya 0:1f44439df816 465 spiffs_page_object_ix_header objix_hdr;
aguscahya 0:1f44439df816 466 spiffs_obj_id obj_id;
aguscahya 0:1f44439df816 467 s32_t res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh,
aguscahya 0:1f44439df816 468 SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr);
aguscahya 0:1f44439df816 469 SPIFFS_API_CHECK_RES(fs, res);
aguscahya 0:1f44439df816 470
aguscahya 0:1f44439df816 471 u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs , pix)) +
aguscahya 0:1f44439df816 472 SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_obj_id);
aguscahya 0:1f44439df816 473 res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, fh,
aguscahya 0:1f44439df816 474 obj_id_addr, sizeof(spiffs_obj_id), (u8_t *)&obj_id);
aguscahya 0:1f44439df816 475 SPIFFS_API_CHECK_RES(fs, res);
aguscahya 0:1f44439df816 476
aguscahya 0:1f44439df816 477 s->obj_id = obj_id;
aguscahya 0:1f44439df816 478 s->type = objix_hdr.type;
aguscahya 0:1f44439df816 479 s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size;
aguscahya 0:1f44439df816 480 strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN);
aguscahya 0:1f44439df816 481
aguscahya 0:1f44439df816 482 return res;
aguscahya 0:1f44439df816 483 }
aguscahya 0:1f44439df816 484
aguscahya 0:1f44439df816 485 s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) {
aguscahya 0:1f44439df816 486 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 487 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 488
aguscahya 0:1f44439df816 489 s32_t res;
aguscahya 0:1f44439df816 490 spiffs_page_ix pix;
aguscahya 0:1f44439df816 491
aguscahya 0:1f44439df816 492 res = spiffs_object_find_object_index_header_by_name(fs, (u8_t*)path, &pix);
aguscahya 0:1f44439df816 493 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 494
aguscahya 0:1f44439df816 495 res = spiffs_stat_pix(fs, pix, 0, s);
aguscahya 0:1f44439df816 496
aguscahya 0:1f44439df816 497 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 498
aguscahya 0:1f44439df816 499 return res;
aguscahya 0:1f44439df816 500 }
aguscahya 0:1f44439df816 501
aguscahya 0:1f44439df816 502 s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) {
aguscahya 0:1f44439df816 503 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 504 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 505
aguscahya 0:1f44439df816 506 spiffs_fd *fd;
aguscahya 0:1f44439df816 507 s32_t res;
aguscahya 0:1f44439df816 508
aguscahya 0:1f44439df816 509 res = spiffs_fd_get(fs, fh, &fd);
aguscahya 0:1f44439df816 510 SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
aguscahya 0:1f44439df816 511
aguscahya 0:1f44439df816 512 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 513 spiffs_fflush_cache(fs, fh);
aguscahya 0:1f44439df816 514 #endif
aguscahya 0:1f44439df816 515
aguscahya 0:1f44439df816 516 res = spiffs_stat_pix(fs, fd->objix_hdr_pix, fh, s);
aguscahya 0:1f44439df816 517
aguscahya 0:1f44439df816 518 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 519
aguscahya 0:1f44439df816 520 return res;
aguscahya 0:1f44439df816 521 }
aguscahya 0:1f44439df816 522
aguscahya 0:1f44439df816 523 // Checks if there are any cached writes for the object id associated with
aguscahya 0:1f44439df816 524 // given filehandle. If so, these writes are flushed.
aguscahya 0:1f44439df816 525 static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
aguscahya 0:1f44439df816 526 s32_t res = SPIFFS_OK;
aguscahya 0:1f44439df816 527 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 528
aguscahya 0:1f44439df816 529 spiffs_fd *fd;
aguscahya 0:1f44439df816 530 res = spiffs_fd_get(fs, fh, &fd);
aguscahya 0:1f44439df816 531 SPIFFS_API_CHECK_RES(fs, res);
aguscahya 0:1f44439df816 532
aguscahya 0:1f44439df816 533 if ((fd->flags & SPIFFS_DIRECT) == 0) {
aguscahya 0:1f44439df816 534 if (fd->cache_page == 0) {
aguscahya 0:1f44439df816 535 // see if object id is associated with cache already
aguscahya 0:1f44439df816 536 fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd);
aguscahya 0:1f44439df816 537 }
aguscahya 0:1f44439df816 538 if (fd->cache_page) {
aguscahya 0:1f44439df816 539 SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, flush, offs:%i size:%i\n",
aguscahya 0:1f44439df816 540 fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size);
aguscahya 0:1f44439df816 541 res = spiffs_hydro_write(fs, fd,
aguscahya 0:1f44439df816 542 spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
aguscahya 0:1f44439df816 543 fd->cache_page->offset, fd->cache_page->size);
aguscahya 0:1f44439df816 544 if (res < SPIFFS_OK) {
aguscahya 0:1f44439df816 545 fs->errno = res;
aguscahya 0:1f44439df816 546 }
aguscahya 0:1f44439df816 547 spiffs_cache_fd_release(fs, fd->cache_page);
aguscahya 0:1f44439df816 548 }
aguscahya 0:1f44439df816 549 }
aguscahya 0:1f44439df816 550 #endif
aguscahya 0:1f44439df816 551
aguscahya 0:1f44439df816 552 return res;
aguscahya 0:1f44439df816 553 }
aguscahya 0:1f44439df816 554
aguscahya 0:1f44439df816 555 s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
aguscahya 0:1f44439df816 556 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 557 s32_t res = SPIFFS_OK;
aguscahya 0:1f44439df816 558 #if SPIFFS_CACHE_WR
aguscahya 0:1f44439df816 559 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 560 res = spiffs_fflush_cache(fs, fh);
aguscahya 0:1f44439df816 561 SPIFFS_API_CHECK_RES_UNLOCK(fs,res);
aguscahya 0:1f44439df816 562 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 563 #endif
aguscahya 0:1f44439df816 564
aguscahya 0:1f44439df816 565 return res;
aguscahya 0:1f44439df816 566 }
aguscahya 0:1f44439df816 567
aguscahya 0:1f44439df816 568 void SPIFFS_close(spiffs *fs, spiffs_file fh) {
aguscahya 0:1f44439df816 569 if (!SPIFFS_CHECK_MOUNT(fs)) {
aguscahya 0:1f44439df816 570 fs->errno = SPIFFS_ERR_NOT_MOUNTED;
aguscahya 0:1f44439df816 571 return;
aguscahya 0:1f44439df816 572 }
aguscahya 0:1f44439df816 573 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 574
aguscahya 0:1f44439df816 575 #if SPIFFS_CACHE
aguscahya 0:1f44439df816 576 spiffs_fflush_cache(fs, fh);
aguscahya 0:1f44439df816 577 #endif
aguscahya 0:1f44439df816 578 spiffs_fd_return(fs, fh);
aguscahya 0:1f44439df816 579
aguscahya 0:1f44439df816 580 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 581 }
aguscahya 0:1f44439df816 582
aguscahya 0:1f44439df816 583 spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) {
aguscahya 0:1f44439df816 584 if (!SPIFFS_CHECK_MOUNT(fs)) {
aguscahya 0:1f44439df816 585 fs->errno = SPIFFS_ERR_NOT_MOUNTED;
aguscahya 0:1f44439df816 586 return 0;
aguscahya 0:1f44439df816 587 }
aguscahya 0:1f44439df816 588 d->fs = fs;
aguscahya 0:1f44439df816 589 d->block = 0;
aguscahya 0:1f44439df816 590 d->entry = 0;
aguscahya 0:1f44439df816 591 return d;
aguscahya 0:1f44439df816 592 }
aguscahya 0:1f44439df816 593
aguscahya 0:1f44439df816 594 static s32_t spiffs_read_dir_v(
aguscahya 0:1f44439df816 595 spiffs *fs,
aguscahya 0:1f44439df816 596 spiffs_obj_id obj_id,
aguscahya 0:1f44439df816 597 spiffs_block_ix bix,
aguscahya 0:1f44439df816 598 int ix_entry,
aguscahya 0:1f44439df816 599 u32_t user_data,
aguscahya 0:1f44439df816 600 void *user_p) {
aguscahya 0:1f44439df816 601 s32_t res;
aguscahya 0:1f44439df816 602 spiffs_page_object_ix_header objix_hdr;
aguscahya 0:1f44439df816 603 if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED ||
aguscahya 0:1f44439df816 604 (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) {
aguscahya 0:1f44439df816 605 return SPIFFS_VIS_COUNTINUE;
aguscahya 0:1f44439df816 606 }
aguscahya 0:1f44439df816 607
aguscahya 0:1f44439df816 608 spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry);
aguscahya 0:1f44439df816 609 res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
aguscahya 0:1f44439df816 610 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr);
aguscahya 0:1f44439df816 611 if (res != SPIFFS_OK) return res;
aguscahya 0:1f44439df816 612 if ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) &&
aguscahya 0:1f44439df816 613 objix_hdr.p_hdr.span_ix == 0 &&
aguscahya 0:1f44439df816 614 (objix_hdr.p_hdr.flags& (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) ==
aguscahya 0:1f44439df816 615 (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) {
aguscahya 0:1f44439df816 616 struct spiffs_dirent *e = (struct spiffs_dirent *)user_p;
aguscahya 0:1f44439df816 617 e->obj_id = obj_id;
aguscahya 0:1f44439df816 618 strcpy((char *)e->name, (char *)objix_hdr.name);
aguscahya 0:1f44439df816 619 e->type = objix_hdr.type;
aguscahya 0:1f44439df816 620 e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size;
aguscahya 0:1f44439df816 621 return SPIFFS_OK;
aguscahya 0:1f44439df816 622 }
aguscahya 0:1f44439df816 623
aguscahya 0:1f44439df816 624 return SPIFFS_VIS_COUNTINUE;
aguscahya 0:1f44439df816 625 }
aguscahya 0:1f44439df816 626
aguscahya 0:1f44439df816 627 struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
aguscahya 0:1f44439df816 628 if (!SPIFFS_CHECK_MOUNT(d->fs)) {
aguscahya 0:1f44439df816 629 d->fs->errno = SPIFFS_ERR_NOT_MOUNTED;
aguscahya 0:1f44439df816 630 return 0;
aguscahya 0:1f44439df816 631 }
aguscahya 0:1f44439df816 632 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 633
aguscahya 0:1f44439df816 634 spiffs_block_ix bix;
aguscahya 0:1f44439df816 635 int entry;
aguscahya 0:1f44439df816 636 s32_t res;
aguscahya 0:1f44439df816 637 struct spiffs_dirent *ret = 0;
aguscahya 0:1f44439df816 638
aguscahya 0:1f44439df816 639 res = spiffs_obj_lu_find_entry_visitor(d->fs,
aguscahya 0:1f44439df816 640 d->block,
aguscahya 0:1f44439df816 641 d->entry,
aguscahya 0:1f44439df816 642 SPIFFS_VIS_NO_WRAP,
aguscahya 0:1f44439df816 643 0,
aguscahya 0:1f44439df816 644 spiffs_read_dir_v,
aguscahya 0:1f44439df816 645 0,
aguscahya 0:1f44439df816 646 e,
aguscahya 0:1f44439df816 647 &bix,
aguscahya 0:1f44439df816 648 &entry);
aguscahya 0:1f44439df816 649 if (res == SPIFFS_OK) {
aguscahya 0:1f44439df816 650 d->block = bix;
aguscahya 0:1f44439df816 651 d->entry = entry + 1;
aguscahya 0:1f44439df816 652 ret = e;
aguscahya 0:1f44439df816 653 } else {
aguscahya 0:1f44439df816 654 d->fs->errno = res;
aguscahya 0:1f44439df816 655 }
aguscahya 0:1f44439df816 656 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 657 return ret;
aguscahya 0:1f44439df816 658 }
aguscahya 0:1f44439df816 659
aguscahya 0:1f44439df816 660 s32_t SPIFFS_closedir(spiffs_DIR *d) {
aguscahya 0:1f44439df816 661 SPIFFS_API_CHECK_MOUNT(d->fs);
aguscahya 0:1f44439df816 662 return 0;
aguscahya 0:1f44439df816 663 }
aguscahya 0:1f44439df816 664
aguscahya 0:1f44439df816 665 s32_t SPIFFS_check(spiffs *fs) {
aguscahya 0:1f44439df816 666 s32_t res;
aguscahya 0:1f44439df816 667 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 668 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 669
aguscahya 0:1f44439df816 670 res = spiffs_lookup_consistency_check(fs, 0);
aguscahya 0:1f44439df816 671
aguscahya 0:1f44439df816 672 res = spiffs_object_index_consistency_check(fs);
aguscahya 0:1f44439df816 673
aguscahya 0:1f44439df816 674 res = spiffs_page_consistency_check(fs);
aguscahya 0:1f44439df816 675
aguscahya 0:1f44439df816 676 res = spiffs_obj_lu_scan(fs);
aguscahya 0:1f44439df816 677
aguscahya 0:1f44439df816 678 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 679 return res;
aguscahya 0:1f44439df816 680 }
aguscahya 0:1f44439df816 681
aguscahya 0:1f44439df816 682 #if SPIFFS_TEST_VISUALISATION
aguscahya 0:1f44439df816 683 s32_t SPIFFS_vis(spiffs *fs) {
aguscahya 0:1f44439df816 684 s32_t res = SPIFFS_OK;
aguscahya 0:1f44439df816 685 SPIFFS_API_CHECK_MOUNT(fs);
aguscahya 0:1f44439df816 686 SPIFFS_LOCK(fs);
aguscahya 0:1f44439df816 687
aguscahya 0:1f44439df816 688 u32_t entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
aguscahya 0:1f44439df816 689 spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
aguscahya 0:1f44439df816 690 spiffs_block_ix bix = 0;
aguscahya 0:1f44439df816 691
aguscahya 0:1f44439df816 692 while (bix < fs->block_count) {
aguscahya 0:1f44439df816 693 // check each object lookup page
aguscahya 0:1f44439df816 694 int obj_lookup_page = 0;
aguscahya 0:1f44439df816 695 int cur_entry = 0;
aguscahya 0:1f44439df816 696
aguscahya 0:1f44439df816 697 while (res == SPIFFS_OK && obj_lookup_page < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
aguscahya 0:1f44439df816 698 int entry_offset = obj_lookup_page * entries_per_page;
aguscahya 0:1f44439df816 699 res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
aguscahya 0:1f44439df816 700 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
aguscahya 0:1f44439df816 701 // check each entry
aguscahya 0:1f44439df816 702 while (res == SPIFFS_OK &&
aguscahya 0:1f44439df816 703 cur_entry - entry_offset < entries_per_page && cur_entry < SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
aguscahya 0:1f44439df816 704 spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
aguscahya 0:1f44439df816 705 if (cur_entry == 0) {
aguscahya 0:1f44439df816 706 spiffs_printf("%4i ", bix);
aguscahya 0:1f44439df816 707 } else if ((cur_entry & 0x3f) == 0) {
aguscahya 0:1f44439df816 708 spiffs_printf(" ");
aguscahya 0:1f44439df816 709 }
aguscahya 0:1f44439df816 710 if (obj_id == SPIFFS_OBJ_ID_FREE) {
aguscahya 0:1f44439df816 711 spiffs_printf(SPIFFS_TEST_VIS_FREE_STR);
aguscahya 0:1f44439df816 712 } else if (obj_id == SPIFFS_OBJ_ID_DELETED) {
aguscahya 0:1f44439df816 713 spiffs_printf(SPIFFS_TEST_VIS_DELE_STR);
aguscahya 0:1f44439df816 714 } else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG){
aguscahya 0:1f44439df816 715 spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id));
aguscahya 0:1f44439df816 716 } else {
aguscahya 0:1f44439df816 717 spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id));
aguscahya 0:1f44439df816 718 }
aguscahya 0:1f44439df816 719 cur_entry++;
aguscahya 0:1f44439df816 720 if ((cur_entry & 0x3f) == 0) {
aguscahya 0:1f44439df816 721 spiffs_printf("\n");
aguscahya 0:1f44439df816 722 }
aguscahya 0:1f44439df816 723 } // per entry
aguscahya 0:1f44439df816 724 obj_lookup_page++;
aguscahya 0:1f44439df816 725 } // per object lookup page
aguscahya 0:1f44439df816 726
aguscahya 0:1f44439df816 727 spiffs_obj_id erase_count;
aguscahya 0:1f44439df816 728 res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0,
aguscahya 0:1f44439df816 729 SPIFFS_ERASE_COUNT_PADDR(fs, bix),
aguscahya 0:1f44439df816 730 sizeof(spiffs_obj_id), (u8_t *)&erase_count);
aguscahya 0:1f44439df816 731 SPIFFS_CHECK_RES(res);
aguscahya 0:1f44439df816 732
aguscahya 0:1f44439df816 733 if (erase_count != (spiffs_obj_id)-1) {
aguscahya 0:1f44439df816 734 spiffs_printf("\tera_cnt: %i\n", erase_count);
aguscahya 0:1f44439df816 735 } else {
aguscahya 0:1f44439df816 736 spiffs_printf("\tera_cnt: N/A\n");
aguscahya 0:1f44439df816 737 }
aguscahya 0:1f44439df816 738
aguscahya 0:1f44439df816 739 bix++;
aguscahya 0:1f44439df816 740 } // per block
aguscahya 0:1f44439df816 741
aguscahya 0:1f44439df816 742 spiffs_printf("era_cnt_max: %i\n", fs->max_erase_count);
aguscahya 0:1f44439df816 743 spiffs_printf("last_errno: %i\n", fs->errno);
aguscahya 0:1f44439df816 744 spiffs_printf("blocks: %i\n", fs->block_count);
aguscahya 0:1f44439df816 745 spiffs_printf("free_blocks: %i\n", fs->free_blocks);
aguscahya 0:1f44439df816 746 spiffs_printf("page_alloc: %i\n", fs->stats_p_allocated);
aguscahya 0:1f44439df816 747 spiffs_printf("page_delet: %i\n", fs->stats_p_deleted);
aguscahya 0:1f44439df816 748
aguscahya 0:1f44439df816 749 SPIFFS_UNLOCK(fs);
aguscahya 0:1f44439df816 750 return res;
aguscahya 0:1f44439df816 751 }
aguscahya 0:1f44439df816 752 #endif