-
spiffs_hydrogen.c@0:1f44439df816, 2021-04-22 (annotated)
- Committer:
- aguscahya
- Date:
- Thu Apr 22 03:49:45 2021 +0000
- Revision:
- 0:1f44439df816
-
Who changed what in which revision?
User | Revision | Line number | New 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 |