forked from Imagelibrary/rtems
JFFS2: Add RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION
Add IO control to force a garbage collection. Update #2844.
This commit is contained in:
@@ -555,6 +555,14 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
#define RTEMS_JFFS2_GET_INFO _IOR('F', 1, rtems_jffs2_info)
|
#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
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -568,6 +568,9 @@ static int rtems_jffs2_ioctl(
|
|||||||
rtems_jffs2_get_info(&inode->i_sb->jffs2_sb, buffer);
|
rtems_jffs2_get_info(&inode->i_sb->jffs2_sb, buffer);
|
||||||
eno = 0;
|
eno = 0;
|
||||||
break;
|
break;
|
||||||
|
case RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION:
|
||||||
|
eno = -jffs2_garbage_collect_pass(&inode->i_sb->jffs2_sb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
eno = EINVAL;
|
eno = EINVAL;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -109,6 +109,38 @@ static const rtems_jffs2_info info_some_files_removed = {
|
|||||||
.bad_blocks = 0
|
.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 char big[] = "big";
|
||||||
|
|
||||||
static const char * const more[] = {
|
static const char * const more[] = {
|
||||||
@@ -225,6 +257,7 @@ void test(void)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int rv;
|
int rv;
|
||||||
|
int counter;
|
||||||
rtems_jffs2_info info;
|
rtems_jffs2_info info;
|
||||||
|
|
||||||
init_keg();
|
init_keg();
|
||||||
@@ -246,6 +279,30 @@ void test(void)
|
|||||||
remove_some_files();
|
remove_some_files();
|
||||||
ASSERT_INFO(&info, &info_some_files_removed);
|
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);
|
rv = close(fd);
|
||||||
rtems_test_assert(rv == 0);
|
rtems_test_assert(rv == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user