Skip to content

Commit b69b064

Browse files
Maciej Zagrabskicfriedt
authored andcommitted
fs: littlefs: add api call for lfs_fs_gc
Lfs provide lfs_fs_gc function for some time now. Function allow offloading of expensive block allocation scan. Introduce lfs_fs_gc via api call fc_gc. Signed-off-by: Maciej Zagrabski <[email protected]>
1 parent 3ac4f92 commit b69b064

File tree

9 files changed

+137
-0
lines changed

9 files changed

+137
-0
lines changed

include/zephyr/fs/fs.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,21 @@ int fs_register(int type, const struct fs_file_system_t *fs);
690690
*/
691691
int fs_unregister(int type, const struct fs_file_system_t *fs);
692692

693+
/**
694+
* @brief Attempt to proactively clean file system
695+
*
696+
* Returns a negative error code on failure.
697+
* Ignored cleaning request is not a failure.
698+
*
699+
* @param mp Pointer to the mounted fs_mount_t structure.
700+
*
701+
* @retval 0 on success;
702+
* @retval -EINVAL when a bad path to a directory, or a file, is given;
703+
* @retval -ENOTSUP when not implemented by underlying file system driver;
704+
* @retval <0 an other negative errno code on error.
705+
*/
706+
int fs_gc(struct fs_mount_t *mp);
707+
693708
/**
694709
* @}
695710
*/

include/zephyr/fs/fs_sys.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ struct fs_file_system_t {
186186
*/
187187
int (*statvfs)(struct fs_mount_t *mountp, const char *path,
188188
struct fs_statvfs *stat);
189+
#if defined(CONFIG_FILE_SYSTEM_GC) || defined(__DOXYGEN__)
190+
/**
191+
* Attempt to proactively clean file system
192+
*
193+
* @param mountp Mount point.
194+
* @return 0 on success, negative errno code on fail.
195+
*/
196+
int (*gc)(struct fs_mount_t *mountp);
197+
#endif
189198
#if defined(CONFIG_FILE_SYSTEM_MKFS) || defined(__DOXYGEN__)
190199
/**
191200
* Formats a device to specified file system type.

subsys/fs/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ config FILE_SYSTEM_MKFS
9999
help
100100
Enables function fs_mkfs that can be used to format a storage device.
101101

102+
config FILE_SYSTEM_GC
103+
bool "Allow explicit garbage collector call"
104+
help
105+
Enables function fs_gc that can be used to proactively run garbage collector.
106+
102107
config FUSE_FS_ACCESS
103108
bool "FUSE based access to file system partitions"
104109
depends on ARCH_POSIX

subsys/fs/fs.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,26 @@ int fs_statvfs(const char *abs_path, struct fs_statvfs *stat)
661661
return rc;
662662
}
663663

664+
#if defined(CONFIG_FILE_SYSTEM_GC)
665+
666+
int fs_gc(struct fs_mount_t *mp)
667+
{
668+
int rc;
669+
670+
CHECKIF(mp->fs->gc == NULL) {
671+
return -ENOTSUP;
672+
}
673+
674+
rc = mp->fs->gc(mp);
675+
if (rc < 0) {
676+
LOG_ERR("failed to run garbage collection (%d)", rc);
677+
}
678+
679+
return rc;
680+
}
681+
682+
#endif /* CONFIG_FILE_SYSTEM_GC */
683+
664684
int fs_mount(struct fs_mount_t *mp)
665685
{
666686
struct fs_mount_t *itr;

subsys/fs/littlefs_fs.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,25 @@ static int littlefs_statvfs(struct fs_mount_t *mountp,
582582
return lfs_to_errno(ret);
583583
}
584584

585+
#if defined(CONFIG_FILE_SYSTEM_GC)
586+
587+
static int littlefs_gc(struct fs_mount_t *mountp)
588+
{
589+
ssize_t ret;
590+
struct fs_littlefs *fs = mountp->fs_data;
591+
struct lfs *lfs = &fs->lfs;
592+
593+
fs_lock(fs);
594+
595+
ret = lfs_fs_gc(lfs);
596+
597+
fs_unlock(fs);
598+
599+
return lfs_to_errno(ret);
600+
}
601+
602+
#endif /* CONFIG_FILE_SYSTEM_GC */
603+
585604
#ifdef CONFIG_FS_LITTLEFS_FMP_DEV
586605

587606
#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE)
@@ -1056,6 +1075,9 @@ static const struct fs_file_system_t littlefs_fs = {
10561075
.mkdir = littlefs_mkdir,
10571076
.stat = littlefs_stat,
10581077
.statvfs = littlefs_statvfs,
1078+
#if defined(CONFIG_FILE_SYSTEM_GC)
1079+
.gc = littlefs_gc,
1080+
#endif
10591081
#if defined(CONFIG_FILE_SYSTEM_MKFS)
10601082
.mkfs = littlefs_mkfs,
10611083
#endif
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2025 Trackunit
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/ztest.h>
9+
#include <zephyr/fs/fs.h>
10+
11+
/* Mount point and paths must be provided by test runner. */
12+
extern struct fs_mount_t *fs_gc_mp;
13+
14+
void test_fs_gc_simple(void)
15+
{
16+
int ret = 0;
17+
18+
TC_PRINT("Mount\n");
19+
ret = fs_mount(fs_gc_mp);
20+
zassert_equal(ret, 0, "Expected fs_mount success (%d)", ret);
21+
22+
TC_PRINT("Try gc\n");
23+
ret = fs_gc(fs_gc_mp);
24+
zassert_equal(ret, 0, "Expected fs_gc success (%d)", ret);
25+
26+
TC_PRINT("Remount filesystem\n");
27+
ret = fs_unmount(fs_gc_mp);
28+
zassert_equal(ret, 0, "Expected fs_unmount success (%d)", ret);
29+
30+
ret = fs_mount(fs_gc_mp);
31+
zassert_equal(ret, 0, "Expected fs_mount success (%d)", ret);
32+
33+
ret = fs_unmount(fs_gc_mp);
34+
zassert_equal(ret, 0, "Expected fs_unmount success (%d)", ret);
35+
}

tests/subsys/fs/littlefs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ target_sources(app PRIVATE
2020
../common/test_fs_basic.c
2121
../common/test_fs_mount_flags.c
2222
../common/test_fs_mkfs.c
23+
../common/test_fs_gc.c
2324
)

tests/subsys/fs/littlefs/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
CONFIG_FILE_SYSTEM=y
22
CONFIG_FILE_SYSTEM_MKFS=y
3+
CONFIG_FILE_SYSTEM_GC=y
34
CONFIG_FILE_SYSTEM_LITTLEFS=y
45
CONFIG_MAIN_STACK_SIZE=4096
56

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2025 Trackunit
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/ztest.h>
8+
#include <zephyr/fs/littlefs.h>
9+
#include "testfs_tests.h"
10+
#include "testfs_lfs.h"
11+
12+
void test_fs_gc_simple(void);
13+
14+
struct fs_mount_t *fs_gc_mp = &testfs_small_mnt;
15+
16+
static void cleanup(struct fs_mount_t *mp)
17+
{
18+
TC_PRINT("Clean %s\n", mp->mnt_point);
19+
20+
zassert_equal(testfs_lfs_wipe_partition(mp), TC_PASS,
21+
"Failed to clean partition");
22+
}
23+
24+
ZTEST(littlefs, test_fs_gc_simple_lfs)
25+
{
26+
cleanup(fs_gc_mp);
27+
28+
test_fs_gc_simple();
29+
}

0 commit comments

Comments
 (0)