static int fs_format(int cidx) { s32_t r; struct mount_info *m = &s_fsm; _u32 fsc_size = FS_CONTAINER_SIZE(FS_SIZE); dprintf(("formatting %d s=%u, cs=%d\n", cidx, FS_SIZE, (int) fsc_size)); m->cidx = cidx; r = fs_create_container(cidx, FS_SIZE); if (r < 0) goto out; m->fh = r; m->valid = m->rw = m->formatting = 1; /* Touch a byte at the end to open a "hole". */ r = sl_FsWrite(m->fh, fsc_size - 1, (_u8 *) "\xff", 1); dprintf(("write 1 @ %d %d\n", (int) (fsc_size - 1), (int) r)); if (r != 1) goto out_close; /* There must be a mount attempt before format. It'll fail and that's ok. */ r = fs_mount_spiffs(m, FS_SIZE, FS_BLOCK_SIZE, FS_PAGE_SIZE); dprintf(("mount: %d\n", (int) r)); r = SPIFFS_format(&m->fs); dprintf(("format: %d\n", (int) r)); if (r != SPIFFS_OK) goto out_close; m->seq = INITIAL_SEQ; r = fs_write_meta(m); out_close: sl_FsClose(m->fh, NULL, NULL, 0); out: m->fh = -1; m->valid = m->formatting = m->rw = 0; return r; }
static _i32 fs_switch_container(struct mount_info *m, _u32 mask_begin, _u32 mask_len) { int r; int new_cidx = m->cidx ^ 1; _i32 old_fh = m->fh, new_fh; _u8 *buf; _u32 offset, len, buf_size; LOG(LL_DEBUG, ("%s %d -> %d", m->cpfx, m->cidx, new_cidx)); if (old_fh > 0 && m->rw) { /* * During the switch the destination container will be unusable. * If switching from a writeable container (likely in response to an erase), * close the old container first to make it safe and reopen for reading. */ fs_close_container(m); old_fh = -1; } if (old_fh < 0) { _u8 fname[MAX_FS_CONTAINER_FNAME_LEN]; fs_container_fname(m->cpfx, m->cidx, fname); r = sl_FsOpen(fname, FS_MODE_OPEN_READ, NULL, &old_fh); DBG(("fopen %s %d", m->cpfx, r)); if (r < 0) { r = SPIFFS_ERR_NOT_READABLE; goto out_close_old; } } miot_wdt_feed(); new_fh = fs_create_container(m->cpfx, new_cidx, m->fs.cfg.phys_size); if (new_fh < 0) { r = new_fh; goto out_close_old; } buf_size = 1024; buf = get_buf(&buf_size); if (buf == NULL) { r = SPIFFS_ERR_INTERNAL; goto out_close_new; } for (offset = 0; offset < m->fs.cfg.phys_size;) { len = buf_size; if (offset == mask_begin) { offset = mask_begin + mask_len; } else if (offset + len > mask_begin && offset < mask_begin + mask_len) { len = mask_begin - offset; } if (offset + len > m->fs.cfg.phys_size) { len = m->fs.cfg.phys_size - offset; } DBG(("copy %d @ %d", (int) len, (int) offset)); if (len > 0) { r = sl_FsRead(old_fh, offset, buf, len); if (r != len) { r = SPIFFS_ERR_NOT_READABLE; goto out_free; } r = sl_FsWrite(new_fh, offset, buf, len); if (r != len) { r = SPIFFS_ERR_NOT_WRITABLE; goto out_free; } offset += len; } } m->seq--; m->cidx = new_cidx; m->fh = new_fh; new_fh = -1; m->rw = 1; r = fs_write_mount_meta(m); m->last_write = mg_time(); out_free: free(buf); out_close_new: if (new_fh > 0) sl_FsClose(new_fh, NULL, NULL, 0); out_close_old: sl_FsClose(old_fh, NULL, NULL, 0); LOG((r == 0 ? LL_DEBUG : LL_ERROR), ("%d", r)); return r; }
static _i32 fs_switch_container(struct mount_info *m, _u32 mask_begin, _u32 mask_len) { int r; int new_cidx = m->cidx ^ 1; _i32 old_fh = m->fh, new_fh; _u8 *buf; _u32 offset, len, buf_size; dprintf(("switch %d -> %d\n", m->cidx, new_cidx)); if (old_fh < 0) { r = sl_FsOpen(container_fname(m->cidx), FS_MODE_OPEN_READ, NULL, &old_fh); dprintf(("fopen %d\n", r)); if (r < 0) { r = SPIFFS_ERR_NOT_READABLE; goto out_close_old; } } new_fh = fs_create_container(new_cidx, m->fs.cfg.phys_size); if (new_fh < 0) { r = new_fh; goto out_close_old; } buf_size = 8192; buf = get_buf(&buf_size); if (buf == NULL) { r = SPIFFS_ERR_INTERNAL; goto out_close_new; } for (offset = 0; offset < m->fs.cfg.phys_size;) { len = buf_size; if (offset == mask_begin) { offset = mask_begin + mask_len; } else if (offset + len > mask_begin && offset < mask_begin + mask_len) { len = mask_begin - offset; } if (offset + len > m->fs.cfg.phys_size) { len = m->fs.cfg.phys_size - offset; } dprintf(("copy %d @ %d\n", (int) len, (int) offset)); if (len > 0) { r = sl_FsRead(old_fh, offset, buf, len); if (r != len) { r = SPIFFS_ERR_NOT_READABLE; goto out_free; } r = sl_FsWrite(new_fh, offset, buf, len); if (r != len) { r = SPIFFS_ERR_NOT_WRITABLE; goto out_free; } offset += len; } } m->seq--; m->cidx = new_cidx; m->fh = new_fh; new_fh = -1; m->rw = 1; r = fs_write_meta(m); out_free: free(buf); out_close_new: if (new_fh > 0) sl_FsClose(new_fh, NULL, NULL, 0); out_close_old: sl_FsClose(old_fh, NULL, NULL, 0); dprintf(("switch: %d\n", r)); return r; }