[rtems commit] JFFS2: RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION

Sebastian Huber sebh at rtems.org
Tue Dec 20 07:32:53 UTC 2016


Module:    rtems
Branch:    master
Commit:    ab834d65e4a96bb59901f4349857ffe3e57a3f54
Changeset: http://git.rtems.org/rtems/commit/?id=ab834d65e4a96bb59901f4349857ffe3e57a3f54

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Dec 20 08:23:49 2016 +0100

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 11735cb..b786415 100644
--- a/cpukit/libfs/src/jffs2/include/rtems/jffs2.h
+++ b/cpukit/libfs/src/jffs2/include/rtems/jffs2.h
@@ -230,6 +230,20 @@ typedef void (*rtems_jffs2_flash_destroy)(
 );
 
 /**
+ * @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.
  */
 struct rtems_jffs2_flash_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;
@@ -556,6 +579,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 5f57a16..8084776 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 7946f85..8dbde68 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 8b5658c..329f734 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);
 




More information about the vc mailing list