diff --git a/dts/bindings/fs/zephyr,fstab,littlefs.yaml b/dts/bindings/fs/zephyr,fstab,littlefs.yaml index b557f4f83f3..92e667712b1 100644 --- a/dts/bindings/fs/zephyr,fstab,littlefs.yaml +++ b/dts/bindings/fs/zephyr,fstab,littlefs.yaml @@ -76,3 +76,13 @@ properties: leveling. This corresponds to CONFIG_FS_LITTLEFS_BLOCK_CYCLES. + + disk-version: + type: int + description: | + The littlefs disk version. + + To maintain backward compatibility with existing littlefs + with the same major disk version. + + The default version is LFS_DISK_VERSION. diff --git a/include/zephyr/fs/littlefs.h b/include/zephyr/fs/littlefs.h index 87618b4cc85..59a87492ae2 100644 --- a/include/zephyr/fs/littlefs.h +++ b/include/zephyr/fs/littlefs.h @@ -17,6 +17,22 @@ extern "C" { #endif +/** + * @brief Get the major part of the littlefs disk version + * + * @param disk_version The disk version of littlefs partition + * @return The major part of the littlefs disk version. + */ +#define FS_LITTLEFS_DISK_VERSION_MAJOR_GET(disk_version) FIELD_GET(GENMASK(31, 16), disk_version) + +/** + * @brief Get the minor part of the littlefs disk version + * + * @param disk_version The disk version of littlefs partition + * @return The minor part of the littlefs disk version. + */ +#define FS_LITTLEFS_DISK_VERSION_MINOR_GET(disk_version) FIELD_GET(GENMASK(15, 0), disk_version) + /** @brief Filesystem info structure for LittleFS mount */ struct fs_littlefs { /* Defaulted in driver, customizable before mount. */ diff --git a/modules/littlefs/zephyr_lfs_config.h b/modules/littlefs/zephyr_lfs_config.h index a7ab27deda9..32bd1e36f9b 100644 --- a/modules/littlefs/zephyr_lfs_config.h +++ b/modules/littlefs/zephyr_lfs_config.h @@ -43,6 +43,10 @@ extern "C" { #endif +#ifdef CONFIG_FS_LITTLEFS_DISK_VERSION +#define LFS_MULTIVERSION +#endif + /* Logging functions when using LittleFS with Zephyr. */ #ifndef LFS_TRACE #ifdef LFS_YES_TRACE diff --git a/subsys/fs/Kconfig.littlefs b/subsys/fs/Kconfig.littlefs index c3ebde18c39..bef620ed715 100644 --- a/subsys/fs/Kconfig.littlefs +++ b/subsys/fs/Kconfig.littlefs @@ -118,4 +118,12 @@ config FS_LITTLEFS_BLK_DEV Enable this option to provide support for littlefs on the block devices (like for example SD card). +config FS_LITTLEFS_DISK_VERSION + bool "Support for selecting littlefs disk version" + default y if $(dt_compat_any_has_prop,$(DT_COMPAT_ZEPHYR_FSTAB_LITTLEFS),disk-version) + help + Enable this option to provide support for selecting littlefs disk version + to maintain backward compatibility with existing littlefs + with the same major disk version. + endif # FILE_SYSTEM_LITTLEFS diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index 8840433b325..5634f290d75 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -789,6 +789,14 @@ static int littlefs_init_cfg(struct fs_littlefs *fs, int flags) lookahead_size = CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE; } +#ifdef CONFIG_FS_LITTLEFS_DISK_VERSION + uint32_t disk_version = lcp->disk_version; + + if (disk_version == 0) { + disk_version = LFS_DISK_VERSION; + } +#endif /* CONFIG_FS_LITTLEFS_DISK_VERSION */ + /* No, you don't get to override this. */ lfs_size_t block_count = 0; @@ -817,7 +825,7 @@ static int littlefs_init_cfg(struct fs_littlefs *fs, int flags) dev->name, (uint32_t)((struct flash_area *)fs->backend)->fa_off, block_count, block_size, block_cycles); - LOG_INF("sizes: rd %u ; pr %u ; ca %u ; la %u", + LOG_INF("partition sizes: rd %u ; pr %u ; ca %u ; la %u", read_size, prog_size, cache_size, lookahead_size); } #endif /* CONFIG_FS_LITTLEFS_FMP_DEV */ @@ -862,7 +870,7 @@ static int littlefs_init_cfg(struct fs_littlefs *fs, int flags) lcp->sync = lfs_api_sync_blk; - LOG_INF("sizes: rd %u ; pr %u ; ca %u ; la %u", + LOG_INF("partition sizes: rd %u ; pr %u ; ca %u ; la %u", lcp->read_size, lcp->prog_size, lcp->cache_size, lcp->lookahead_size); } else { @@ -882,6 +890,13 @@ static int littlefs_init_cfg(struct fs_littlefs *fs, int flags) lcp->sync = lfs_api_sync; } +#ifdef CONFIG_FS_LITTLEFS_DISK_VERSION + lcp->disk_version = disk_version; + LOG_INF("partition disk version: %u.%u", + (uint32_t)FS_LITTLEFS_DISK_VERSION_MAJOR_GET(disk_version), + (uint32_t)FS_LITTLEFS_DISK_VERSION_MINOR_GET(disk_version)); +#endif /* CONFIG_FS_LITTLEFS_DISK_VERSION */ + lcp->block_size = block_size; lcp->block_count = block_count; lcp->block_cycles = block_cycles; @@ -1054,6 +1069,12 @@ static const struct fs_file_system_t littlefs_fs = { #define DT_DRV_COMPAT zephyr_fstab_littlefs #define FS_PARTITION(inst) DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), partition, 0) +#ifdef CONFIG_FS_LITTLEFS_DISK_VERSION +#define FS_DISK_VERSION(inst) \ + .disk_version = DT_INST_PROP_OR(inst, disk_version, LFS_DISK_VERSION), +#else +#define FS_DISK_VERSION(inst) +#endif #define DEFINE_FS(inst) \ static uint8_t __aligned(4) \ @@ -1081,6 +1102,7 @@ static struct fs_littlefs fs_data_##inst = { \ .read_buffer = read_buffer_##inst, \ .prog_buffer = prog_buffer_##inst, \ .lookahead_buffer = lookahead_buffer_##inst, \ + FS_DISK_VERSION(inst) \ }, \ }; \ struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \