source: rtems/testsuites/fstests/fsdosfsformat01/init.c @ 465b0865

4.115
Last change on this file since 465b0865 was 465b0865, checked in by Ralf Kirchner <ralf.kirchner@…>, on 12/12/12 at 16:42:24

dosfs: Bugfix for disks of for example 100MB size

  • Property mode set to 100644
File size: 14.5 KB
Line 
1/*
2 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file_name may be
11 * found in the file_name LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include "tmacros.h"
20
21#include <fcntl.h>
22#include <inttypes.h>
23#include <sys/statvfs.h>
24#include <rtems/libio.h>
25#include <rtems/blkdev.h>
26#include <rtems/dosfs.h>
27#include <rtems/sparse-disk.h>
28
29#include <bsp.h>
30
31#define MAX_PATH_LENGTH 100 /* Maximum number of characters per path */
32#define SECTOR_SIZE 512 /* sector size (bytes) */
33#define FAT12_MAX_CLN 4085 /* maximum + 1 number of clusters for FAT12 */
34#define FAT16_MAX_CLN 65525 /* maximum + 1 number of clusters for FAT16 */
35#define FAT12_DEFAULT_SECTORS_PER_CLUSTER 8 /* Default number of sectors per cluster for FAT12 */
36#define FAT16_DEFAULT_SECTORS_PER_CLUSTER 32 /* Default number of sectors per cluster for FAT16 */
37
38static void test_disk_params(
39  const char     *dev_name,
40  const char     *mount_dir,
41  const blksize_t sector_size,
42  const blksize_t cluster_size,
43  const blkcnt_t  sectors_per_cluster )
44{
45  int          rv;
46  int          fildes;
47  struct stat  stat_buff;
48  char         file_name[MAX_PATH_LENGTH + 1];
49  ssize_t      num_bytes;
50  unsigned int value = (unsigned int) -1;
51
52
53  snprintf( file_name, MAX_PATH_LENGTH, "%s/file1.txt", mount_dir );
54  memset( &stat_buff, 0, sizeof( stat_buff ) );
55
56  rv = mount( dev_name,
57              mount_dir,
58              RTEMS_FILESYSTEM_TYPE_DOSFS,
59              RTEMS_FILESYSTEM_READ_WRITE,
60              NULL );
61  rtems_test_assert( 0 == rv );
62
63  fildes = open( file_name,
64                 O_RDWR | O_CREAT | O_TRUNC,
65                 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
66  rtems_test_assert( -1 != fildes );
67
68  num_bytes = write( fildes, &value, sizeof( value ) );
69  rtems_test_assert( sizeof( value ) == num_bytes );
70
71  rv = fstat( fildes, &stat_buff );
72  rtems_test_assert( 0 == rv );
73  rtems_test_assert( S_ISREG( stat_buff.st_mode ) );
74  rtems_test_assert( sizeof( value ) == stat_buff.st_size );
75  rtems_test_assert( cluster_size == stat_buff.st_blksize );
76  rtems_test_assert( sectors_per_cluster
77                     == ( stat_buff.st_blocks * sector_size / 512 ) );
78  rtems_test_assert( ( ( ( stat_buff.st_size + cluster_size
79                           - 1 ) / cluster_size ) * cluster_size / 512 )
80                     == stat_buff.st_blocks );
81  rv = close( fildes );
82  rtems_test_assert( 0 == rv );
83
84  rv = unmount( mount_dir );
85  rtems_test_assert( 0 == rv );
86}
87
88static void test_create_file(
89  const char *mount_dir,
90  uint32_t    file_idx,
91  bool        expect_ok )
92{
93  char file_name[MAX_PATH_LENGTH + 1];
94  int  fd;
95
96
97  snprintf( file_name,
98            MAX_PATH_LENGTH,
99            "%s/file%" PRIu32 ".txt",
100            mount_dir,
101            file_idx );
102  fd = open( file_name,
103             O_RDWR | O_CREAT | O_TRUNC,
104             S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
105
106  if ( expect_ok ) {
107    int rv;
108
109    rtems_test_assert( fd >= 0 );
110
111    rv = close( fd );
112    rtems_test_assert( rv == 0 );
113  } else {
114    rtems_test_assert( fd == -1 );
115  }
116}
117
118static void test_file_creation(
119  const char    *dev_name,
120  const char    *mount_dir,
121  const uint32_t number_of_files )
122{
123  int      rv;
124  uint32_t file_idx;
125  char     file_name[MAX_PATH_LENGTH + 1];
126
127
128  rv = mount( dev_name,
129              mount_dir,
130              RTEMS_FILESYSTEM_TYPE_DOSFS,
131              RTEMS_FILESYSTEM_READ_WRITE,
132              NULL );
133  rtems_test_assert( 0 == rv );
134
135  for ( file_idx = 0; file_idx < number_of_files; ++file_idx ) {
136    test_create_file( mount_dir, file_idx, true );
137  }
138
139  test_create_file( mount_dir, file_idx, false );
140
141  for ( file_idx = 0; file_idx < number_of_files; ++file_idx ) {
142    snprintf( file_name,
143              MAX_PATH_LENGTH,
144              "%s/file%" PRIu32 ".txt",
145              mount_dir,
146              file_idx );
147    rv = unlink( file_name );
148    rtems_test_assert( 0 == rv );
149  }
150
151  rv = unmount( mount_dir );
152  rtems_test_assert( 0 == rv );
153}
154
155static void test( void )
156{
157  rtems_status_code            sc;
158  int                          rv;
159  const char                   dev_name[]  = "/dev/rda";
160  const char                   mount_dir[] = "/mnt";
161  msdos_format_request_param_t rqdata;
162  rtems_blkdev_bnum            media_block_count;
163
164  memset( &rqdata, 0, sizeof( rqdata ) );
165
166  sc = rtems_disk_io_initialize();
167  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
168
169  rv = mkdir( mount_dir, S_IRWXU | S_IRWXG | S_IRWXO );
170  rtems_test_assert( 0 == rv );
171
172  /* FAT12 */
173  /* For 1.44 MB disks */
174  sc = rtems_sparse_disk_create_and_register(
175    dev_name,
176    SECTOR_SIZE,
177    64,
178    2880,
179    0
180    );
181  rtems_test_assert( RTEMS_SUCCESSFUL == sc );
182
183  /* Optimized for disk space */
184  rqdata.OEMName             = NULL;
185  rqdata.VolLabel            = NULL;
186  rqdata.sectors_per_cluster = 1;
187  rqdata.fat_num             = 1;
188  rqdata.files_per_root_dir  = 32;
189  rqdata.media               = 0; /* Media code. 0 == Default */
190  rqdata.quick_format        = true;
191  rqdata.skip_alignment      = true;
192  rv                         = msdos_format( dev_name, &rqdata );
193  rtems_test_assert( rv == 0 );
194  test_disk_params( dev_name, mount_dir, SECTOR_SIZE, SECTOR_SIZE, 1 );
195  test_file_creation( dev_name, mount_dir, rqdata.files_per_root_dir );
196
197  /* Try formatting with invalid values */
198  rqdata.OEMName             = NULL;
199  rqdata.VolLabel            = NULL;
200  rqdata.sectors_per_cluster = 1;
201  rqdata.fat_num             = 7; /* Invalid number of fats */
202  rqdata.files_per_root_dir  = 32;
203  rqdata.media               = 0; /* Media code. 0 == Default */
204  rqdata.quick_format        = true;
205  rqdata.skip_alignment      = true;
206  rv                         = msdos_format( dev_name, &rqdata );
207  rtems_test_assert( rv != 0 );
208
209  rqdata.OEMName             = NULL;
210  rqdata.VolLabel            = NULL;
211  rqdata.sectors_per_cluster = 1;
212  rqdata.fat_num             = 1;
213  rqdata.files_per_root_dir  = 32;
214  rqdata.media               = 0x11; /* Invalid media code */
215  rqdata.quick_format        = true;
216  rqdata.skip_alignment      = true;
217  rv                         = msdos_format( dev_name, &rqdata );
218  rtems_test_assert( rv != 0 );
219
220  /* Optimized for read/write speed */
221  rqdata.OEMName             = NULL;
222  rqdata.VolLabel            = NULL;
223  rqdata.sectors_per_cluster = 8;
224  rqdata.fat_num             = 0;
225  rqdata.files_per_root_dir  = 0;
226  rqdata.media               = 0; /* Media code. 0 == Default */
227  rqdata.quick_format        = true;
228  rqdata.skip_alignment      = false;
229  rv                         = msdos_format( dev_name, &rqdata );
230  rtems_test_assert( rv == 0 );
231  test_disk_params( dev_name,
232                    mount_dir,
233                    SECTOR_SIZE,
234                    SECTOR_SIZE * rqdata.sectors_per_cluster,
235                    rqdata.sectors_per_cluster );
236
237  /* The same disk formatted with FAT16 because sectors per cluster is too high
238   * for FAT12 */
239  rqdata.OEMName             = NULL;
240  rqdata.VolLabel            = NULL;
241  rqdata.sectors_per_cluster = 16;
242  rqdata.fat_num             = 1;
243  rqdata.files_per_root_dir  = 32;
244  rqdata.media               = 0; /* Media code. 0 == Default */
245  rqdata.quick_format        = true;
246  rqdata.skip_alignment      = false;
247  rv                         = msdos_format( dev_name, &rqdata );
248  rtems_test_assert( rv == 0 );
249  test_disk_params( dev_name,
250                    mount_dir,
251                    SECTOR_SIZE,
252                    SECTOR_SIZE * rqdata.sectors_per_cluster,
253                    rqdata.sectors_per_cluster );
254
255  rv = unlink( dev_name );
256  rtems_test_assert( rv == 0 );
257
258  /* Largest FAT12 disk */
259  sc = rtems_sparse_disk_create_and_register(
260    dev_name,
261    SECTOR_SIZE,
262    64,
263    ( FAT12_MAX_CLN * FAT12_DEFAULT_SECTORS_PER_CLUSTER ) - 1L,
264    0
265    );
266  rtems_test_assert( RTEMS_SUCCESSFUL == sc );
267
268  /* Default parameters (corresponds to optimization for read/write speed) */
269  rv = msdos_format( dev_name, NULL );
270  rtems_test_assert( rv == 0 );
271  test_disk_params( dev_name,
272                    mount_dir,
273                    SECTOR_SIZE,
274                    SECTOR_SIZE * FAT12_DEFAULT_SECTORS_PER_CLUSTER,
275                    FAT12_DEFAULT_SECTORS_PER_CLUSTER );
276
277  rv = unlink( dev_name );
278  rtems_test_assert( rv == 0 );
279
280  /* FAT16 */
281  sc = rtems_sparse_disk_create_and_register(
282    dev_name,
283    SECTOR_SIZE,
284    1024,
285    ( FAT12_MAX_CLN * FAT12_DEFAULT_SECTORS_PER_CLUSTER ) + 1L,
286    0
287    );
288  rtems_test_assert( RTEMS_SUCCESSFUL == sc );
289
290  /* Optimized for disk space */
291  rqdata.OEMName             = NULL;
292  rqdata.VolLabel            = NULL;
293  rqdata.sectors_per_cluster = 1;
294  rqdata.fat_num             = 1;
295  rqdata.files_per_root_dir  = 32;
296  rqdata.media               = 0; /* Media code. 0 == Default */
297  rqdata.quick_format        = true;
298  rqdata.skip_alignment      = true;
299  rv                         = msdos_format( dev_name, &rqdata );
300  rtems_test_assert( rv == 0 );
301  test_disk_params( dev_name,
302                    mount_dir,
303                    SECTOR_SIZE,
304                    rqdata.sectors_per_cluster * SECTOR_SIZE,
305                    rqdata.sectors_per_cluster );
306
307  rv = unlink( dev_name );
308  rtems_test_assert( rv == 0 );
309
310  sc = rtems_sparse_disk_create_and_register(
311    dev_name,
312    SECTOR_SIZE,
313    1024,
314    ( FAT16_MAX_CLN * FAT16_DEFAULT_SECTORS_PER_CLUSTER ) - 1L,
315    0
316    );
317  rtems_test_assert( RTEMS_SUCCESSFUL == sc );
318
319  /* Optimized for read/write speed */
320  rqdata.OEMName             = NULL;
321  rqdata.VolLabel            = NULL;
322  rqdata.sectors_per_cluster = 64;
323  rqdata.fat_num             = 0;
324  rqdata.files_per_root_dir  = 0;
325  rqdata.media               = 0; /* Media code. 0 == Default */
326  rqdata.quick_format        = true;
327  rqdata.skip_alignment      = false;
328  rv                         = msdos_format( dev_name, &rqdata );
329  rtems_test_assert( rv == 0 );
330  test_disk_params( dev_name,
331                    mount_dir,
332                    SECTOR_SIZE,
333                    SECTOR_SIZE * rqdata.sectors_per_cluster,
334                    rqdata.sectors_per_cluster );
335
336  /* Default parameters (corresponds to optimization for read/write speed) */
337  rv = msdos_format( dev_name, NULL );
338  rtems_test_assert( rv == 0 );
339  test_disk_params( dev_name,
340                    mount_dir,
341                    SECTOR_SIZE,
342                    SECTOR_SIZE * FAT16_DEFAULT_SECTORS_PER_CLUSTER,
343                    FAT16_DEFAULT_SECTORS_PER_CLUSTER );
344
345  rv = unlink( dev_name );
346  rtems_test_assert( rv == 0 );
347
348  sc = rtems_sparse_disk_create_and_register(
349    dev_name,
350    SECTOR_SIZE,
351    1024,
352    ( FAT16_MAX_CLN + 10 ) * 64,
353    0
354    );
355  rtems_test_assert( RTEMS_SUCCESSFUL == sc );
356
357  rqdata.OEMName             = NULL;
358  rqdata.VolLabel            = NULL;
359  rqdata.sectors_per_cluster = 64;
360  rqdata.fat_num             = 0;
361  rqdata.files_per_root_dir  = 0;
362  rqdata.media               = 0; /* Media code. 0 == Default */
363  rqdata.quick_format        = true;
364  rqdata.skip_alignment      = false;
365  rv                         = msdos_format( dev_name, &rqdata );
366  rtems_test_assert( rv == 0 );
367  test_disk_params( dev_name,
368                    mount_dir,
369                    SECTOR_SIZE,
370                    SECTOR_SIZE * rqdata.sectors_per_cluster,
371                    rqdata.sectors_per_cluster );
372  rv = unlink( dev_name );
373  rtems_test_assert( rv == 0 );
374
375  /* Format some disks from 1MB up to 128GB */
376  rqdata.OEMName             = NULL;
377  rqdata.VolLabel            = NULL;
378  rqdata.sectors_per_cluster = 64;
379  rqdata.fat_num             = 0;
380  rqdata.files_per_root_dir  = 0;
381  rqdata.media               = 0;
382  rqdata.quick_format        = true;
383  rqdata.skip_alignment      = false;
384  for (
385    media_block_count = 1 * 1024 * ( 1024 / SECTOR_SIZE );
386    media_block_count <= 128 * 1024 * 1024 * ( 1024 / SECTOR_SIZE );
387    media_block_count *= 2
388  ) {
389    sc = rtems_sparse_disk_create_and_register(
390      dev_name,
391      SECTOR_SIZE,
392      64,
393      media_block_count,
394      0
395    );
396    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
397
398    rv = msdos_format( dev_name, &rqdata );
399    rtems_test_assert( rv == 0 );
400
401    test_disk_params(
402      dev_name,
403      mount_dir,
404      SECTOR_SIZE,
405      SECTOR_SIZE * rqdata.sectors_per_cluster,
406      rqdata.sectors_per_cluster
407    );
408
409    rv = unlink( dev_name );
410    rtems_test_assert( rv == 0 );
411  }
412
413  /* FAT32 */
414
415  sc = rtems_sparse_disk_create_and_register(
416    dev_name,
417    SECTOR_SIZE,
418    1024,
419    ( FAT16_MAX_CLN * FAT16_DEFAULT_SECTORS_PER_CLUSTER ) + 41L,
420    0
421    );
422  rtems_test_assert( RTEMS_SUCCESSFUL == sc );
423
424  /* Default parameters */
425  rv = msdos_format( dev_name, NULL );
426  rtems_test_assert( rv == 0 );
427  test_disk_params( dev_name, mount_dir, SECTOR_SIZE, SECTOR_SIZE, 1 );
428  rv = unlink( dev_name );
429  rtems_test_assert( rv == 0 );
430
431  sc = rtems_sparse_disk_create_and_register(
432    dev_name,
433    SECTOR_SIZE,
434    1024,
435    ( FAT16_MAX_CLN + 20 ) * 64L,
436    0
437    );
438  rtems_test_assert( RTEMS_SUCCESSFUL == sc );
439
440  /* Optimized for read/write speed */
441  rqdata.OEMName             = NULL;
442  rqdata.VolLabel            = NULL;
443  rqdata.sectors_per_cluster = 64;
444  rqdata.fat_num             = 0;
445  rqdata.files_per_root_dir  = 0;
446  rqdata.media               = 0; /* Media code. 0 == Default */
447  rqdata.quick_format        = true;
448  rqdata.skip_alignment      = false;
449  rv                         = msdos_format( dev_name, &rqdata );
450  rtems_test_assert( rv == 0 );
451  test_disk_params( dev_name,
452                    mount_dir,
453                    SECTOR_SIZE,
454                    SECTOR_SIZE * rqdata.sectors_per_cluster,
455                    rqdata.sectors_per_cluster );
456
457  rv = unlink( dev_name );
458  rtems_test_assert( rv == 0 );
459}
460
461static void Init( rtems_task_argument arg )
462{
463  puts( "\n\n*** TEST FSDOSFSFORMAT 1 ***" );
464
465  test();
466
467  puts( "*** END OF TEST FSDOSFSFORMAT 1 ***" );
468
469  rtems_test_exit( 0 );
470}
471
472#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
473#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
474#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
475
476/* one active file + stdin + stdout + stderr + device file when mounted */
477#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 5
478
479#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
480
481#define CONFIGURE_FILESYSTEM_DOSFS
482
483#define CONFIGURE_MAXIMUM_TASKS 1
484#define CONFIGURE_MAXIMUM_SEMAPHORES 1
485
486#define CONFIGURE_INIT_TASK_STACK_SIZE ( 32 * 1024 )
487
488#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
489
490#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE ( 32 * 1024 )
491
492#define CONFIGURE_INIT
493
494#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.