File indexing completed on 2025-05-11 08:24:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include <tmacros.h>
0033 #include <fstest.h>
0034
0035 #include <sys/stat.h>
0036 #include <string.h>
0037 #include <fcntl.h>
0038 #include <unistd.h>
0039 #include <errno.h>
0040
0041 #include <rtems/jffs2.h>
0042
0043 const char rtems_test_name[] = "FSJFFS2GC 1";
0044 const RTEMS_TEST_STATE rtems_test_state = TEST_STATE;
0045
0046 static const rtems_jffs2_info info_initial = {
0047 .flash_size = 131072,
0048 .flash_blocks = 8,
0049 .flash_block_size = 16384,
0050 .used_size = 96,
0051 .dirty_size = 0,
0052 .wasted_size = 0,
0053 .free_size = 130976,
0054 .bad_size = 0,
0055 .clean_blocks = 0,
0056 .dirty_blocks = 0,
0057 .erasable_blocks = 0,
0058 .free_blocks = 8,
0059 .bad_blocks = 0
0060 };
0061
0062 static const rtems_jffs2_info info_big_created = {
0063 .flash_size = 131072,
0064 .flash_blocks = 8,
0065 .flash_block_size = 16384,
0066 .used_size = 22292,
0067 .dirty_size = 0,
0068 .wasted_size = 164,
0069 .free_size = 108616,
0070 .bad_size = 0,
0071 .clean_blocks = 1,
0072 .dirty_blocks = 0,
0073 .erasable_blocks = 0,
0074 .free_blocks = 7,
0075 .bad_blocks = 0
0076 };
0077
0078 static const rtems_jffs2_info info_big_removed = {
0079 .flash_size = 131072,
0080 .flash_blocks = 8,
0081 .flash_block_size = 16384,
0082 .used_size = 72,
0083 .dirty_size = 16384,
0084 .wasted_size = 6000,
0085 .free_size = 108616,
0086 .bad_size = 0,
0087 .clean_blocks = 0,
0088 .dirty_blocks = 0,
0089 .erasable_blocks = 1,
0090 .free_blocks = 7,
0091 .bad_blocks = 0
0092 };
0093
0094 static const rtems_jffs2_info info_more_files_created = {
0095 .flash_size = 131072,
0096 .flash_blocks = 8,
0097 .flash_block_size = 16384,
0098 .used_size = 54896,
0099 .dirty_size = 23336,
0100 .wasted_size = 36,
0101 .free_size = 52804,
0102 .bad_size = 0,
0103 .clean_blocks = 2,
0104 .dirty_blocks = 1,
0105 .erasable_blocks = 1,
0106 .free_blocks = 4,
0107 .bad_blocks = 0
0108 };
0109
0110 static const rtems_jffs2_info info_some_files_removed = {
0111 .flash_size = 131072,
0112 .flash_blocks = 8,
0113 .flash_block_size = 16384,
0114 .used_size = 23528,
0115 .dirty_size = 47372,
0116 .wasted_size = 7368,
0117 .free_size = 52804,
0118 .bad_size = 0,
0119 .clean_blocks = 0,
0120 .dirty_blocks = 3,
0121 .erasable_blocks = 1,
0122 .free_blocks = 4,
0123 .bad_blocks = 0
0124 };
0125
0126 static const rtems_jffs2_info info_after_first_gc = {
0127 .flash_size = 131072,
0128 .flash_blocks = 8,
0129 .flash_block_size = 16384,
0130 .used_size = 23540,
0131 .dirty_size = 30988,
0132 .wasted_size = 7368,
0133 .free_size = 69176,
0134 .bad_size = 0,
0135 .clean_blocks = 0,
0136 .dirty_blocks = 3,
0137 .erasable_blocks = 0,
0138 .free_blocks = 5,
0139 .bad_blocks = 0
0140 };
0141
0142 static const rtems_jffs2_info info_after_excessive_gc = {
0143 .flash_size = 131072,
0144 .flash_blocks = 8,
0145 .flash_block_size = 16384,
0146 .used_size = 7224,
0147 .dirty_size = 0,
0148 .wasted_size = 12,
0149 .free_size = 123836,
0150 .bad_size = 0,
0151 .clean_blocks = 0,
0152 .dirty_blocks = 0,
0153 .erasable_blocks = 0,
0154 .free_blocks = 8,
0155 .bad_blocks = 0
0156 };
0157
0158 static char big[] = "big";
0159
0160 static const char * const more[] = {
0161 "1",
0162 "2",
0163 "3",
0164 "4",
0165 "5",
0166 "6",
0167 "7"
0168 };
0169
0170 #define ASSERT_INFO(a, b) do { \
0171 rv = ioctl(fd, RTEMS_JFFS2_GET_INFO, &info); \
0172 rtems_test_assert(rv == 0); \
0173 rtems_test_assert(memcmp(a, b, sizeof(*a)) == 0); \
0174 } while (0)
0175
0176 static const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0177
0178 static char keg[523];
0179
0180 static uint32_t simple_random(uint32_t v)
0181 {
0182 v *= 1664525;
0183 v += 1013904223;
0184
0185 return v;
0186 }
0187
0188 static void init_keg(void)
0189 {
0190 size_t i;
0191 uint32_t v;
0192
0193 v = 123;
0194 for (i = 0; i < sizeof(keg); ++i) {
0195 v = simple_random(v);
0196 keg[i] = (uint8_t) (v >> 23);
0197 }
0198 }
0199
0200 static void write_kegs(int fd, int kegs)
0201 {
0202 int i;
0203
0204 for (i = 0; i < kegs; ++i) {
0205 ssize_t n;
0206
0207 n = write(fd, &keg[0], sizeof(keg));
0208 rtems_test_assert(n == (ssize_t) sizeof(keg));
0209 }
0210 }
0211
0212 static void create_big_file(void)
0213 {
0214 int fd;
0215 int rv;
0216
0217 fd = open(&big[0], O_WRONLY | O_TRUNC | O_CREAT, mode);
0218 rtems_test_assert(fd >= 0);
0219
0220 write_kegs(fd, 37);
0221
0222 rv = close(fd);
0223 rtems_test_assert(rv == 0);
0224 }
0225
0226 static void remove_big_file(void)
0227 {
0228 int rv;
0229
0230 rv = unlink(&big[0]);
0231 rtems_test_assert(rv == 0);
0232 }
0233
0234 static void create_more_files(void)
0235 {
0236 int fds[RTEMS_ARRAY_SIZE(more)];
0237 int rv;
0238 size_t i;
0239 int j;
0240
0241 for (i = 0; i < RTEMS_ARRAY_SIZE(fds); ++i) {
0242 fds[i] = open(more[i], O_WRONLY | O_TRUNC | O_CREAT, mode);
0243 rtems_test_assert(fds[i] >= 0);
0244 }
0245
0246 for (j = 0; j < 13; ++j) {
0247 for (i = 0; i < RTEMS_ARRAY_SIZE(fds); ++i) {
0248 write_kegs(fds[i], 1);
0249 }
0250 }
0251
0252 for (i = 0; i < RTEMS_ARRAY_SIZE(fds); ++i) {
0253 rv = close(fds[i]);
0254 rtems_test_assert(rv == 0);
0255 }
0256 }
0257
0258 static void remove_some_files(void)
0259 {
0260 size_t i;
0261
0262 for (i = 0; i < RTEMS_ARRAY_SIZE(more); i += 2) {
0263 int rv;
0264
0265 rv = unlink(more[i]);
0266 rtems_test_assert(rv == 0);
0267 }
0268 }
0269
0270 void test(void)
0271 {
0272 int fd;
0273 int rv;
0274 int counter;
0275 rtems_jffs2_info info;
0276
0277 init_keg();
0278
0279
0280
0281
0282
0283 while (rtems_clock_get_ticks_since_boot() == 0) {
0284
0285 }
0286
0287 fd = open("/", O_RDONLY);
0288 rtems_test_assert(fd >= 0);
0289
0290 ASSERT_INFO(&info, &info_initial);
0291
0292 create_big_file();
0293 ASSERT_INFO(&info, &info_big_created);
0294
0295 remove_big_file();
0296 ASSERT_INFO(&info, &info_big_removed);
0297
0298 create_more_files();
0299 ASSERT_INFO(&info, &info_more_files_created);
0300
0301 remove_some_files();
0302 ASSERT_INFO(&info, &info_some_files_removed);
0303
0304 rv = ioctl(fd, RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION);
0305 rtems_test_assert(rv == 0);
0306 ASSERT_INFO(&info, &info_after_first_gc);
0307
0308 rv = ioctl(fd, RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION);
0309 rtems_test_assert(rv == 0);
0310 ASSERT_INFO(&info, &info_after_first_gc);
0311
0312 counter = 0;
0313
0314 while (true) {
0315 errno = ENXIO;
0316 rv = ioctl(fd, RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION);
0317 if (rv == -1) {
0318 rtems_test_assert(errno == EIO);
0319 break;
0320 }
0321
0322 ++counter;
0323 rtems_test_assert(rv == 0);
0324 }
0325
0326 rtems_test_assert(counter == 19);
0327
0328 rv = ioctl(fd, RTEMS_JFFS2_GET_INFO, &info);
0329 rtems_test_assert(rv == 0);
0330 ASSERT_INFO(&info, &info_after_excessive_gc);
0331
0332 rv = close(fd);
0333 rtems_test_assert(rv == 0);
0334 }