Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:30

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2024 On-Line Applications Research (OAR)
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include <fcntl.h>
0033 #include <stdio.h>
0034 #include <tmacros.h>
0035 
0036 #include <rtems.h>
0037 #include <rtems/jffs2.h>
0038 #include <rtems/libio.h>
0039 
0040 #define BLOCK_SIZE (16UL * 1024UL)
0041 
0042 #define FLASH_SIZE (8UL * BLOCK_SIZE)
0043 
0044 const char rtems_test_name[] = "FSJFFS2EMPTY 1";
0045 
0046 #define BASE_FOR_TEST "/mnt"
0047 static char big[] = BASE_FOR_TEST "/big";
0048 
0049 static char keg[523];
0050 
0051 static void init_keg(void)
0052 {
0053   uint32_t v = 123;
0054 
0055   for (size_t i = 0; i < sizeof(keg); ++i) {
0056     v = v * 1664525 + 1013904223;
0057     keg[i] = (uint8_t) (v >> 23);
0058   }
0059 }
0060 
0061 static void create_big_file(void)
0062 {
0063   int rv;
0064   int fd = open(&big[0], O_WRONLY | O_TRUNC | O_CREAT,
0065                 S_IRWXU | S_IRWXG | S_IRWXO);
0066   rtems_test_assert(fd >= 0);
0067 
0068   for (int i = 0; i < 100; ++i) {
0069     ssize_t n = write(fd, &keg[0], sizeof(keg));
0070     rtems_test_assert(n == (ssize_t) sizeof(keg));
0071   }
0072 
0073   rv = close(fd);
0074   rtems_test_assert(rv == 0);
0075 }
0076 
0077 static void remove_big_file(void)
0078 {
0079   int rv = unlink(&big[0]);
0080   rtems_test_assert(rv == 0);
0081 }
0082 
0083 typedef struct {
0084   rtems_jffs2_flash_control super;
0085   unsigned char area[FLASH_SIZE];
0086 } flash_control;
0087 
0088 static unsigned char *get_flash_chunk(rtems_jffs2_flash_control *super,
0089                                       uint32_t offset)
0090 {
0091   return &((flash_control *) super)->area[offset];
0092 }
0093 
0094 static int flash_read(
0095   rtems_jffs2_flash_control *super,
0096   uint32_t offset,
0097   unsigned char *buffer,
0098   size_t size_of_buffer
0099 )
0100 {
0101   unsigned char *chunk = get_flash_chunk(super, offset);
0102 
0103   memcpy(buffer, chunk, size_of_buffer);
0104 
0105   return 0;
0106 }
0107 
0108 static int flash_write(
0109   rtems_jffs2_flash_control *super,
0110   uint32_t offset,
0111   const unsigned char *buffer,
0112   size_t size_of_buffer
0113 )
0114 {
0115   unsigned char *chunk = get_flash_chunk(super, offset);
0116 
0117   for (size_t i = 0; i < size_of_buffer; ++i) {
0118     chunk[i] &= buffer[i];
0119   }
0120 
0121   return 0;
0122 }
0123 
0124 static int flash_erase(
0125   rtems_jffs2_flash_control *super,
0126   uint32_t offset
0127 )
0128 {
0129   unsigned char *chunk = get_flash_chunk(super, offset);
0130 
0131   memset(chunk, 0xff, BLOCK_SIZE);
0132 
0133   return 0;
0134 }
0135 
0136 static flash_control flash_instance = {
0137   .super = {
0138     .block_size = BLOCK_SIZE,
0139     .flash_size = FLASH_SIZE,
0140     .read = flash_read,
0141     .write = flash_write,
0142     .erase = flash_erase
0143   }
0144 };
0145 
0146 static rtems_jffs2_compressor_control compressor_instance = {
0147   .compress = rtems_jffs2_compressor_rtime_compress,
0148   .decompress = rtems_jffs2_compressor_rtime_decompress
0149 };
0150 
0151 static const rtems_jffs2_mount_data mount_data = {
0152   .flash_control = &flash_instance.super,
0153   .compressor_control = &compressor_instance
0154 };
0155 
0156 static void erase_all(void)
0157 {
0158   memset(&flash_instance.area[0], 0xff, FLASH_SIZE);
0159 }
0160 
0161 static void test_initialize_filesystem(void)
0162 {
0163   int rv = mount(
0164     NULL,
0165     BASE_FOR_TEST,
0166     RTEMS_FILESYSTEM_TYPE_JFFS2,
0167     RTEMS_FILESYSTEM_READ_WRITE,
0168     &mount_data
0169   );
0170   rtems_test_assert(rv == 0);
0171 }
0172 
0173 static void test_shutdown_filesystem(void)
0174 {
0175   int rv = unmount(BASE_FOR_TEST);
0176   rtems_test_assert(rv == 0);
0177 }
0178 
0179 static rtems_task Init(
0180     rtems_task_argument ignored)
0181 {
0182   int rv;
0183 
0184   TEST_BEGIN();
0185 
0186   erase_all();
0187 
0188   rv = mkdir(BASE_FOR_TEST, S_IRWXU | S_IRWXG | S_IRWXO);
0189   rtems_test_assert(rv == 0);
0190 
0191   puts( "Initializing JFFS2 filesystem" );
0192   test_initialize_filesystem();
0193 
0194   init_keg();
0195 
0196   /*
0197    * Ensure that jiffies != 0, to use most likely path in
0198    * jffs2_mark_node_obsolete(). Without this the failure only happens
0199    * intermittently.
0200    */
0201   while (rtems_clock_get_ticks_since_boot() == 0) {
0202     /* Wait */
0203   }
0204 
0205   /*
0206    * This must be done in 2 parts because the FS is only so large and all blocks
0207    * must be written to.
0208    */
0209   create_big_file();
0210   remove_big_file();
0211 
0212   create_big_file();
0213   remove_big_file();
0214 
0215   puts( "\n\nShutting down JFFS2 filesystem");
0216   test_shutdown_filesystem();
0217 
0218   puts( "Initializing JFFS2 filesystem again" );
0219   test_initialize_filesystem();
0220 
0221   puts( "\n\nShutting down JFFS2 filesystem again" );
0222   test_shutdown_filesystem();
0223 
0224   TEST_END();
0225   rtems_test_exit(0);
0226 }
0227 
0228 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0229 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0230 
0231 #define CONFIGURE_FILESYSTEM_JFFS2
0232 
0233 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 40
0234 
0235 #define CONFIGURE_MAXIMUM_TASKS 2
0236 
0237 #define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
0238 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
0239 
0240 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0241 
0242 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0243 
0244 #define CONFIGURE_INIT
0245 #include <rtems/confdefs.h>