Filesystem library designed for flash devices

Dependents:   flash-fs-example Dragonfly_Filesystem_Example STM32F407VET6_SPIFlash Dragonfly_Filesystem_Example_mbed_5

Committer:
Mike Fiore
Date:
Mon Dec 29 14:10:45 2014 -0600
Revision:
2:de478b250060
Parent:
0:bb4e812f7c97
Child:
3:9adcf49bb77d
more changes to appease the IAR gods - fix void pointer arithmetic not allowed by IAR

Who changed what in which revision?

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