diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-09-06 10:12:06 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-09-06 10:20:46 +0200 |
commit | fae59c9b4248e5511d1ea469624aa9842fc289e1 (patch) | |
tree | 524139be7f6d630b168319acd777e94a724542b5 | |
parent | 731e68a39a7b8d662df74d75d780c1ad2c2f8729 (diff) |
dosfs: Support a cluster size of 64KiB
Close #3003.
-rw-r--r-- | cpukit/libfs/src/dosfs/fat.c | 8 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/fat.h | 6 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_format.c | 8 | ||||
-rw-r--r-- | testsuites/fstests/fsdosfsformat01/init.c | 28 |
4 files changed, 38 insertions, 12 deletions
diff --git a/cpukit/libfs/src/dosfs/fat.c b/cpukit/libfs/src/dosfs/fat.c index a0475d4610..8701a21d9a 100644 --- a/cpukit/libfs/src/dosfs/fat.c +++ b/cpukit/libfs/src/dosfs/fat.c @@ -566,16 +566,14 @@ fat_init_volume_info(fat_fs_info_t *fs_info, const char *device) for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0; i >>= 1, vol->spc_log2++); - /* - * "bytes per cluster" value greater than 32K is invalid - */ - if (vol->bps > (MS_BYTES_PER_CLUSTER_LIMIT >> vol->spc_log2)) + /* Sectors per cluster must be a power of two */ + if (vol->spc != UINT32_C(1) << vol->spc_log2) { close(vol->fd); rtems_set_errno_and_return_minus_one(EINVAL); } - vol->bpc = vol->bps << vol->spc_log2; + vol->bpc = ((uint32_t) vol->bps) << vol->spc_log2; for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0; i >>= 1, vol->bpc_log2++); diff --git a/cpukit/libfs/src/dosfs/fat.h b/cpukit/libfs/src/dosfs/fat.h index 1cbf9a7247..4839cb7613 100644 --- a/cpukit/libfs/src/dosfs/fat.h +++ b/cpukit/libfs/src/dosfs/fat.h @@ -274,7 +274,7 @@ extern "C" { #define FAT_TOTAL_FSINFO_SIZE 512 -#define MS_BYTES_PER_CLUSTER_LIMIT 0x8000 /* 32K */ +#define MS_BYTES_PER_CLUSTER_LIMIT 0x10000 /* 64K */ #define MS_BYTES_PER_CLUSTER_LIMIT_FAT12 0x1000 /* 4K */ #define FAT_BR_EXT_FLAGS_MIRROR 0x0080 @@ -300,10 +300,10 @@ typedef struct fat_vol_s uint8_t sec_mul; /* log2 of 512bts sectors number per sector */ uint8_t spc; /* sectors per cluster */ uint8_t spc_log2; /* log2 of spc */ - uint16_t bpc; /* bytes per cluster */ + uint32_t bpc; /* bytes per cluster */ uint8_t bpc_log2; /* log2 of bytes per cluster */ uint8_t sectors_per_block; /* sectors per bdbuf block */ - uint16_t bytes_per_block; /* number of bytes for the bduf block device handling */ + uint32_t bytes_per_block; /* number of bytes for the bduf block device handling */ uint8_t bytes_per_block_log2; /* log2 of bytes_per_block */ uint8_t fats; /* number of FATs */ uint8_t type; /* FAT type */ diff --git a/cpukit/libfs/src/dosfs/msdos_format.c b/cpukit/libfs/src/dosfs/msdos_format.c index 17e435d65a..e3ff94b925 100644 --- a/cpukit/libfs/src/dosfs/msdos_format.c +++ b/cpukit/libfs/src/dosfs/msdos_format.c @@ -316,7 +316,7 @@ static int msdos_format_eval_sectors_per_cluster uint32_t fatdata_sect_cnt; uint32_t fat_sectors_cnt; /* - * ensure, that maximum cluster size (32KByte) is not exceeded + * ensure, that maximum cluster size (64KiB) is not exceeded */ while (MS_BYTES_PER_CLUSTER_LIMIT / bytes_per_sector < sectors_per_cluster) { sectors_per_cluster /= 2; @@ -397,7 +397,7 @@ msdos_get_fat_type( const uint32_t bytes_per_sector, uint32_t ms_sectors_per_cluster_limit_FAT12 = ( MS_BYTES_PER_CLUSTER_LIMIT_FAT12 +1 ) / bytes_per_sector; uint32_t ms_sectors_per_cluster_limit_FAT16 = - ( MS_BYTES_PER_CLUSTER_LIMIT +1 ) / bytes_per_sector; + ( 0x8000 +1 ) / bytes_per_sector; uint8_t fattype = FAT_FAT32; if ( number_of_clusters < FAT_FAT12_MAX_CLN @@ -427,13 +427,13 @@ msdos_set_sectors_per_cluster_from_request( * check sectors per cluster. * must be power of 2 * must be smaller than or equal to 128 - * sectors_per_cluster*bytes_per_sector must not be bigger than 32K + * sectors_per_cluster*bytes_per_sector must not be bigger than 64K */ for ( onebit = 128; onebit >= 1; onebit = onebit >> 1 ) { if ( fmt_params->sectors_per_cluster >= onebit ) { fmt_params->sectors_per_cluster = onebit; if ( fmt_params->sectors_per_cluster - <= 32768L / fmt_params->bytes_per_sector ) { + <= MS_BYTES_PER_CLUSTER_LIMIT / fmt_params->bytes_per_sector ) { /* value is small enough so this value is ok */ onebit = 1; ret_val = 0; diff --git a/testsuites/fstests/fsdosfsformat01/init.c b/testsuites/fstests/fsdosfsformat01/init.c index f11ef056c3..b7df74883a 100644 --- a/testsuites/fstests/fsdosfsformat01/init.c +++ b/testsuites/fstests/fsdosfsformat01/init.c @@ -469,6 +469,34 @@ static void test( void ) rv = unlink( dev_name ); rtems_test_assert( rv == 0 ); + + /* FAT32 with cluster size of 64KiB */ + + sc = rtems_sparse_disk_create_and_register( + dev_name, + SECTOR_SIZE, + 1024, + 16777216, /* 8GiB */ + 0 + ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + memset( &rqdata, 0, sizeof( rqdata ) ); + rqdata.sectors_per_cluster = 128; + rqdata.quick_format = true; + rv = msdos_format( dev_name, &rqdata ); + rtems_test_assert( rv == 0 ); + + test_disk_params( + dev_name, + mount_dir, + SECTOR_SIZE, + SECTOR_SIZE * rqdata.sectors_per_cluster, + rqdata.sectors_per_cluster + ); + + rv = unlink( dev_name ); + rtems_test_assert( rv == 0 ); } static void Init( rtems_task_argument arg ) |