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 <fcntl.h>
0034 #include <rtems/dosfs.h>
0035 #include <rtems/sparse-disk.h>
0036 #include <rtems/blkdev.h>
0037 #include <bsp.h>
0038
0039 const char rtems_test_name[] = "FSDOSFSWRITE 1";
0040
0041 #define MAX_PATH_LENGTH 100
0042 #define SECTOR_SIZE 512
0043 #define FAT16_MAX_CLN 65525
0044 #define FAT16_DEFAULT_SECTORS_PER_CLUSTER 32
0045 #define SECTORS_PER_CLUSTER 2
0046
0047 static void format_and_mount( const char *dev_name, const char *mount_dir )
0048 {
0049 static const msdos_format_request_param_t rqdata = {
0050 .sectors_per_cluster = SECTORS_PER_CLUSTER,
0051 .quick_format = true
0052 };
0053
0054 int rv;
0055
0056
0057 rv = msdos_format( dev_name, &rqdata );
0058 rtems_test_assert( rv == 0 );
0059
0060 rv = mount( dev_name,
0061 mount_dir,
0062 RTEMS_FILESYSTEM_TYPE_DOSFS,
0063 RTEMS_FILESYSTEM_READ_WRITE,
0064 NULL );
0065 rtems_test_assert( rv == 0 );
0066 }
0067
0068 static void do_fsync( const char *file )
0069 {
0070 int rv;
0071 int fd;
0072
0073
0074 fd = open( file, O_RDONLY );
0075 rtems_test_assert( fd >= 0 );
0076
0077 rv = fsync( fd );
0078 rtems_test_assert( rv == 0 );
0079
0080 rv = close( fd );
0081 rtems_test_assert( rv == 0 );
0082 }
0083
0084 static void check_block_stats( const char *dev_name,
0085 const char *mount_dir,
0086 const rtems_blkdev_stats *expected_stats )
0087 {
0088 int fd;
0089 int rv;
0090 rtems_blkdev_stats actual_stats;
0091
0092
0093 do_fsync( mount_dir );
0094
0095 fd = open( dev_name, O_RDONLY );
0096 rtems_test_assert( fd >= 0 );
0097
0098 rv = ioctl( fd, RTEMS_BLKIO_GETDEVSTATS, &actual_stats );
0099 rtems_test_assert( rv == 0 );
0100 rtems_test_assert( memcmp( &actual_stats, expected_stats,
0101 sizeof( actual_stats ) ) == 0 );
0102
0103 rv = close( fd );
0104 rtems_test_assert( rv == 0 );
0105 }
0106
0107 static void reset_block_stats( const char *dev_name, const char *mount_dir )
0108 {
0109 int fd;
0110 int rv;
0111
0112
0113 do_fsync( mount_dir );
0114
0115 fd = open( dev_name, O_RDONLY );
0116 rtems_test_assert( fd >= 0 );
0117
0118 rv = ioctl( fd, RTEMS_BLKIO_PURGEDEV );
0119 rtems_test_assert( rv == 0 );
0120
0121 rv = ioctl( fd, RTEMS_BLKIO_RESETDEVSTATS );
0122 rtems_test_assert( rv == 0 );
0123
0124 rv = close( fd );
0125 rtems_test_assert( rv == 0 );
0126 }
0127
0128 static int create_file( const char *file_name )
0129 {
0130 mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0131
0132
0133 return creat( file_name, mode );
0134 }
0135
0136 static void test_normal_file_write(
0137 const char *dev_name,
0138 const char *mount_dir,
0139 const char *file_name )
0140 {
0141 static const rtems_blkdev_stats complete_existing_block_stats = {
0142 .read_hits = 0,
0143 .read_misses = 0,
0144 .read_ahead_transfers = 0,
0145 .read_ahead_peeks = 0,
0146 .read_blocks = 0,
0147 .read_errors = 0,
0148 .write_transfers = 1,
0149 .write_blocks = 1,
0150 .write_errors = 0
0151 };
0152 static const rtems_blkdev_stats complete_new_block_stats = {
0153 .read_hits = 3,
0154 .read_misses = 2,
0155 .read_ahead_transfers = 0,
0156 .read_ahead_peeks = 0,
0157 .read_blocks = 2,
0158 .read_errors = 0,
0159 .write_transfers = 1,
0160 .write_blocks = 3,
0161 .write_errors = 0
0162 };
0163 static const rtems_blkdev_stats partial_new_block_stats = {
0164 .read_hits = 3,
0165 .read_misses = 3,
0166 .read_ahead_transfers = 0,
0167 .read_ahead_peeks = 0,
0168 .read_blocks = 3,
0169 .read_errors = 0,
0170 .write_transfers = 1,
0171 .write_blocks = 3,
0172 .write_errors = 0
0173 };
0174
0175 int rv;
0176 int fd;
0177 ssize_t num_bytes;
0178 uint8_t cluster_buf[SECTOR_SIZE
0179 * SECTORS_PER_CLUSTER];
0180 uint32_t cluster_size = sizeof( cluster_buf );
0181 off_t off;
0182
0183
0184 memset( cluster_buf, 0xFE, cluster_size );
0185
0186 format_and_mount( dev_name, mount_dir );
0187
0188 fd = create_file( file_name );
0189 rtems_test_assert( fd >= 0 );
0190
0191 num_bytes = write( fd, cluster_buf, cluster_size );
0192 rtems_test_assert( (ssize_t) cluster_size == num_bytes );
0193
0194 off = lseek( fd, 0, SEEK_SET );
0195 rtems_test_assert( off == 0 );
0196
0197 reset_block_stats( dev_name, mount_dir );
0198
0199
0200 num_bytes = write( fd, cluster_buf, cluster_size );
0201 rtems_test_assert( (ssize_t) cluster_size == num_bytes );
0202
0203 check_block_stats( dev_name, mount_dir, &complete_existing_block_stats );
0204 reset_block_stats( dev_name, mount_dir );
0205
0206
0207 num_bytes = write( fd, cluster_buf, cluster_size );
0208 rtems_test_assert( (ssize_t) cluster_size == num_bytes );
0209
0210 check_block_stats( dev_name, mount_dir, &complete_new_block_stats );
0211 reset_block_stats( dev_name, mount_dir );
0212
0213
0214 num_bytes = write( fd, cluster_buf, 1 );
0215 rtems_test_assert( num_bytes == 1 );
0216
0217 check_block_stats( dev_name, mount_dir, &partial_new_block_stats );
0218
0219 rv = close( fd );
0220 rtems_test_assert( 0 == rv );
0221
0222 rv = unmount( mount_dir );
0223 rtems_test_assert( 0 == rv );
0224 }
0225
0226 static void test_fat12_root_directory_write( const char *dev_name,
0227 const char *mount_dir,
0228 const char *file_name )
0229 {
0230 static const rtems_blkdev_stats fat12_root_dir_stats = {
0231 .read_hits = 11,
0232 .read_misses = 2,
0233 .read_ahead_transfers = 0,
0234 .read_blocks = 2,
0235 .read_errors = 0,
0236 .write_transfers = 1,
0237 .write_blocks = 1,
0238 .write_errors = 0
0239 };
0240
0241 int fd;
0242 int rv;
0243
0244
0245 format_and_mount( dev_name, mount_dir );
0246
0247 reset_block_stats( dev_name, mount_dir );
0248
0249 fd = create_file( file_name );
0250 rtems_test_assert( fd >= 0 );
0251
0252 rv = close( fd );
0253 rtems_test_assert( rv == 0 );
0254
0255 check_block_stats( dev_name, mount_dir, &fat12_root_dir_stats );
0256
0257 rv = unmount( mount_dir );
0258 rtems_test_assert( rv == 0 );
0259 }
0260
0261 static void test( void )
0262 {
0263 static const char dev_name[] = "/dev/sda";
0264 static const char mount_dir[] = "/mnt";
0265 static const char file_name[] = "/mnt/file.txt";
0266
0267 rtems_status_code sc;
0268 int rv;
0269
0270 rv = mkdir( mount_dir, S_IRWXU | S_IRWXG | S_IRWXO );
0271 rtems_test_assert( 0 == rv );
0272
0273
0274 sc = rtems_sparse_disk_create_and_register(
0275 dev_name,
0276 SECTOR_SIZE,
0277 64,
0278 2880,
0279 0
0280 );
0281 rtems_test_assert( RTEMS_SUCCESSFUL == sc );
0282
0283 test_fat12_root_directory_write( dev_name, mount_dir, file_name );
0284
0285 test_normal_file_write( dev_name, mount_dir, file_name );
0286
0287 rv = unlink( dev_name );
0288 rtems_test_assert( rv == 0 );
0289 }
0290
0291 static void Init( rtems_task_argument arg )
0292 {
0293 TEST_BEGIN();
0294
0295 test();
0296
0297 TEST_END();
0298 rtems_test_exit( 0 );
0299 }
0300
0301 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0302 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0303 #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
0304
0305 #define CONFIGURE_FILESYSTEM_DOSFS
0306
0307
0308 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 8
0309
0310 #define CONFIGURE_UNLIMITED_OBJECTS
0311 #define CONFIGURE_UNIFIED_WORK_AREAS
0312
0313 #define CONFIGURE_INIT_TASK_STACK_SIZE ( 32 * 1024 )
0314
0315 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0316
0317 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0318
0319 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
0320
0321 #define CONFIGURE_BDBUF_BUFFER_MAX_SIZE ( 32 * 1024 )
0322
0323 #define CONFIGURE_INIT
0324
0325 #include <rtems/confdefs.h>