Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/zephyr/fs/zms.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ typedef uint32_t zms_id_t;
* @brief Mount a ZMS file system onto the device specified in `fs`.
*
* @param fs Pointer to the file system.
* @param wipe_on_failure If true, the partition will be wiped if mounting fails the first time.
*
* @retval 0 on success.
* @retval -ENOTSUP if the detected file system is not ZMS.
Expand All @@ -100,7 +101,7 @@ typedef uint32_t zms_id_t;
* @retval -ENXIO if there is a device error.
* @retval -EIO if there is a memory read/write error.
*/
int zms_mount(struct zms_fs *fs);
int zms_mount(struct zms_fs *fs, bool wipe_on_failure);

/**
* @brief Clear the ZMS file system from device. The ZMS file system must be re-mounted after this
Expand Down
47 changes: 32 additions & 15 deletions subsys/fs/zms/zms.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(fs_zms, CONFIG_ZMS_LOG_LEVEL);

static int zms_prev_ate(struct zms_fs *fs, uint64_t *addr, struct zms_ate *ate);
static int zms_ate_valid(struct zms_fs *fs, const struct zms_ate *entry);
static int zms_add_empty_ate(struct zms_fs *fs, uint64_t addr);
static int zms_get_sector_cycle(struct zms_fs *fs, uint64_t addr, uint8_t *cycle_cnt);
static int zms_get_sector_header(struct zms_fs *fs, uint64_t addr, struct zms_ate *empty_ate,
struct zms_ate *close_ate);
Expand Down Expand Up @@ -598,6 +599,26 @@ static int zms_flash_write_entry(struct zms_fs *fs, zms_id_t id, const void *dat
return 0;
}

/* zms_wipe_partition erases the whole partition used by ZMS */
static int zms_wipe_partition(struct zms_fs *fs)
{
int rc;
uint64_t addr;

for (uint32_t i = 0; i < fs->sector_count; i++) {
addr = (uint64_t)i << ADDR_SECT_SHIFT;
rc = zms_flash_erase_sector(fs, addr);
if (rc) {
return rc;
}
rc = zms_add_empty_ate(fs, addr);
if (rc) {
return rc;
}
}
return 0;
}

/* end of flash routines */

/* Search for the last valid ATE written in a sector and also update data write address
Expand Down Expand Up @@ -1128,7 +1149,6 @@ static int zms_gc(struct zms_fs *fs)
int zms_clear(struct zms_fs *fs)
{
int rc;
uint64_t addr;

if (!fs) {
LOG_ERR("Invalid fs");
Expand All @@ -1141,25 +1161,15 @@ int zms_clear(struct zms_fs *fs)
}

k_mutex_lock(&fs->zms_lock, K_FOREVER);
for (uint32_t i = 0; i < fs->sector_count; i++) {
addr = (uint64_t)i << ADDR_SECT_SHIFT;
rc = zms_flash_erase_sector(fs, addr);
if (rc) {
goto end;
}
rc = zms_add_empty_ate(fs, addr);
if (rc) {
goto end;
}
}

rc = zms_wipe_partition(fs);

/* zms needs to be reinitialized after clearing */
fs->ready = false;

end:
k_mutex_unlock(&fs->zms_lock);

return 0;
return rc;
}

static int zms_init(struct zms_fs *fs)
Expand Down Expand Up @@ -1459,7 +1469,7 @@ static int zms_init(struct zms_fs *fs)
return rc;
}

int zms_mount(struct zms_fs *fs)
int zms_mount(struct zms_fs *fs, bool wipe_on_failure)
{
int rc;
struct flash_pages_info info;
Expand Down Expand Up @@ -1519,6 +1529,13 @@ int zms_mount(struct zms_fs *fs)

rc = zms_init(fs);

if (rc && wipe_on_failure) {
/* wipe partition and try once more */
LOG_WRN("ZMS init failed (%d), wiping partition", rc);
zms_wipe_partition(fs);
rc = zms_init(fs);
}

if (rc) {
return rc;
}
Expand Down
7 changes: 7 additions & 0 deletions subsys/settings/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ config SETTINGS_ZMS_LL_CACHE_SIZE
help
Number of entries in Settings ZMS linked list cache.

config SETTINGS_ZMS_WIPE_ON_MOUNT_FAILURE
bool "ZMS wipe on mount failure"
default n
help
Enable wiping of ZMS storage on mount failure to recover from
corrupted data.

endif # SETTINGS_ZMS

config SETTINGS_FCB
Expand Down
3 changes: 2 additions & 1 deletion subsys/settings/src/settings_zms.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,13 +680,14 @@ static int settings_zms_get_last_hash_ids(struct settings_zms *cf)
static int settings_zms_backend_init(struct settings_zms *cf)
{
int rc;
bool wipe_on_failure = IS_ENABLED(CONFIG_SETTINGS_ZMS_WIPE_ON_MOUNT_FAILURE);

cf->cf_zms.flash_device = cf->flash_dev;
if (cf->cf_zms.flash_device == NULL) {
return -ENODEV;
}

rc = zms_mount(&cf->cf_zms);
rc = zms_mount(&cf->cf_zms, wipe_on_failure);
if (rc) {
return rc;
}
Expand Down
Loading