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) 2012 embedded brains GmbH & Co. KG
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 "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 /* Maximum number of characters per path */
0042 #define SECTOR_SIZE 512 /* sector size (bytes) */
0043 #define FAT16_MAX_CLN 65525 /* maximum + 1 number of clusters for FAT16 */
0044 #define FAT16_DEFAULT_SECTORS_PER_CLUSTER 32 /* Default number of sectors per cluster for FAT16 */
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   /* Write a complete cluster into an existing file space */
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   /* Write a complete cluster into a new file space */
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   /* Write a new partial cluster into a new file space */
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   /* A 1.44 MB disk */
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 /* 1 device file for blkstats + 1 file for writing + 1 mount_dir + stdin + stdout + stderr + device file when mounted */
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>