JFFS2: Add RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION

Add IO control to force a garbage collection.

Update #2844.
This commit is contained in:
Sebastian Huber
2016-12-19 10:19:44 +01:00
parent 07c833f8f9
commit ade135d455
3 changed files with 68 additions and 0 deletions

View File

@@ -555,6 +555,14 @@ typedef struct {
*/
#define RTEMS_JFFS2_GET_INFO _IOR('F', 1, rtems_jffs2_info)
/**
* @brief IO control to force a garbage collection in a JFFS2 filesystem
* instance.
*
* Use this operation with care since it may wear out your flash.
*/
#define RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION _IO('F', 3)
/** @} */
#ifdef __cplusplus

View File

@@ -568,6 +568,9 @@ static int rtems_jffs2_ioctl(
rtems_jffs2_get_info(&inode->i_sb->jffs2_sb, buffer);
eno = 0;
break;
case RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION:
eno = -jffs2_garbage_collect_pass(&inode->i_sb->jffs2_sb);
break;
default:
eno = EINVAL;
break;

View File

@@ -109,6 +109,38 @@ static const rtems_jffs2_info info_some_files_removed = {
.bad_blocks = 0
};
static const rtems_jffs2_info info_after_first_gc = {
.flash_size = 131072,
.flash_blocks = 8,
.flash_block_size = 16384,
.used_size = 23540,
.dirty_size = 30988,
.wasted_size = 7368,
.free_size = 69176,
.bad_size = 0,
.clean_blocks = 0,
.dirty_blocks = 3,
.erasable_blocks = 0,
.free_blocks = 5,
.bad_blocks = 0
};
static const rtems_jffs2_info info_after_excessive_gc = {
.flash_size = 131072,
.flash_blocks = 8,
.flash_block_size = 16384,
.used_size = 7224,
.dirty_size = 0,
.wasted_size = 12,
.free_size = 123836,
.bad_size = 0,
.clean_blocks = 0,
.dirty_blocks = 0,
.erasable_blocks = 0,
.free_blocks = 8,
.bad_blocks = 0
};
static char big[] = "big";
static const char * const more[] = {
@@ -225,6 +257,7 @@ void test(void)
{
int fd;
int rv;
int counter;
rtems_jffs2_info info;
init_keg();
@@ -246,6 +279,30 @@ void test(void)
remove_some_files();
ASSERT_INFO(&info, &info_some_files_removed);
rv = ioctl(fd, RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION);
rtems_test_assert(rv == 0);
ASSERT_INFO(&info, &info_after_first_gc);
counter = 0;
while (true) {
errno = ENXIO;
rv = ioctl(fd, RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION);
if (rv == -1) {
rtems_test_assert(errno == EIO);
break;
}
++counter;
rtems_test_assert(rv == 0);
}
rtems_test_assert(counter == 19);
rv = ioctl(fd, RTEMS_JFFS2_GET_INFO, &info);
rtems_test_assert(rv == 0);
ASSERT_INFO(&info, &info_after_excessive_gc);
rv = close(fd);
rtems_test_assert(rv == 0);
}