source: rtems/testsuites/fstests/fsdosfsformat01/init.c @ fae59c9

Last change on this file since fae59c9 was fae59c9, checked in by Sebastian Huber <sebastian.huber@…>, on Sep 6, 2017 at 8:12:06 AM

dosfs: Support a cluster size of 64KiB

Close #3003.

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