From ab834d65e4a96bb59901f4349857ffe3e57a3f54 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 20 Dec 2016 08:23:49 +0100 Subject: JFFS2: RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION Update #2844. --- cpukit/libfs/src/jffs2/include/rtems/jffs2.h | 32 ++++++++++++++++++++++++++++ cpukit/libfs/src/jffs2/src/fs-rtems.c | 12 +++++++++++ cpukit/libfs/src/jffs2/src/os-rtems.h | 7 +++++- testsuites/fstests/fsjffs2gc01/init.c | 6 +++++- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/cpukit/libfs/src/jffs2/include/rtems/jffs2.h b/cpukit/libfs/src/jffs2/include/rtems/jffs2.h index 11735cbb09..b786415b68 100644 --- a/cpukit/libfs/src/jffs2/include/rtems/jffs2.h +++ b/cpukit/libfs/src/jffs2/include/rtems/jffs2.h @@ -229,6 +229,20 @@ typedef void (*rtems_jffs2_flash_destroy)( rtems_jffs2_flash_control *self ); +/** + * @brief Trigger garbage collection operation. + * + * An optional garbage collection thread may perform now a garbage collection + * using the RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION IO control. + * + * The garbage collection must not run in the executing context. + * + * @param[in] self The flash control. + */ +typedef void (*rtems_jffs2_trigger_garbage_collection)( + rtems_jffs2_flash_control *self +); + /** * @brief JFFS2 flash device control. */ @@ -275,6 +289,15 @@ struct rtems_jffs2_flash_control { * file system node in the system. */ dev_t device_identifier; + + /** + * @brief Trigger garbage collection operation. + * + * This operation is optional and may be NULL. This operation should wake up + * a garbage collection thread. The garbage collection thread should use the + * RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION IO control to carry out the work. + */ + rtems_jffs2_trigger_garbage_collection trigger_garbage_collection; }; typedef struct rtems_jffs2_compressor_control rtems_jffs2_compressor_control; @@ -555,6 +578,15 @@ typedef struct { */ #define RTEMS_JFFS2_GET_INFO _IOR('F', 1, rtems_jffs2_info) +/** + * @brief IO control to perform an on demand garbage collection in a JFFS2 + * filesystem instance. + * + * This operation is intended to be used by an optional garbage collection + * thread. See rtems_jffs2_flash_control::trigger_garbage_collection. + */ +#define RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION _IO('F', 2) + /** * @brief IO control to force a garbage collection in a JFFS2 filesystem * instance. diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c index 5f57a16bcb..8084776659 100644 --- a/cpukit/libfs/src/jffs2/src/fs-rtems.c +++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c @@ -552,6 +552,15 @@ static void rtems_jffs2_get_info( info->bad_blocks = rtems_jffs2_count_blocks(&c->bad_list); } +static int rtems_jffs2_on_demand_garbage_collection(struct jffs2_sb_info *c) +{ + if (jffs2_thread_should_wake(c)) { + return -jffs2_garbage_collect_pass(c); + } else { + return 0; + } +} + static int rtems_jffs2_ioctl( rtems_libio_t *iop, ioctl_command_t request, @@ -568,6 +577,9 @@ static int rtems_jffs2_ioctl( rtems_jffs2_get_info(&inode->i_sb->jffs2_sb, buffer); eno = 0; break; + case RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION: + eno = rtems_jffs2_on_demand_garbage_collection(&inode->i_sb->jffs2_sb); + break; case RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION: eno = -jffs2_garbage_collect_pass(&inode->i_sb->jffs2_sb); break; diff --git a/cpukit/libfs/src/jffs2/src/os-rtems.h b/cpukit/libfs/src/jffs2/src/os-rtems.h index 7946f85566..8dbde681d8 100644 --- a/cpukit/libfs/src/jffs2/src/os-rtems.h +++ b/cpukit/libfs/src/jffs2/src/os-rtems.h @@ -120,7 +120,12 @@ static inline bool jffs2_is_readonly(struct jffs2_sb_info *c) static inline void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c) { - /* We don't have a GC thread in RTEMS (yet) */ + const struct super_block *sb = OFNI_BS_2SFFJ(c); + rtems_jffs2_flash_control *fc = sb->s_flash_control; + + if (fc->trigger_garbage_collection != NULL) { + (*fc->trigger_garbage_collection)(fc); + } } /* fs-rtems.c */ diff --git a/testsuites/fstests/fsjffs2gc01/init.c b/testsuites/fstests/fsjffs2gc01/init.c index 8b5658c594..329f734d8f 100644 --- a/testsuites/fstests/fsjffs2gc01/init.c +++ b/testsuites/fstests/fsjffs2gc01/init.c @@ -279,7 +279,11 @@ void test(void) remove_some_files(); ASSERT_INFO(&info, &info_some_files_removed); - rv = ioctl(fd, RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION); + rv = ioctl(fd, RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION); + rtems_test_assert(rv == 0); + ASSERT_INFO(&info, &info_after_first_gc); + + rv = ioctl(fd, RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION); rtems_test_assert(rv == 0); ASSERT_INFO(&info, &info_after_first_gc); -- cgit v1.2.3