forked from Imagelibrary/rtems
dosfs: Delete fattype parameter for msdos_format()
Delete fattype parameter of msdos_format_request_param_t because the FAT type is determined by cluster and disk size. Estimate FAT type and re-evaluate FAT type after exact parameter determination.
This commit is contained in:
committed by
Sebastian Huber
parent
5b8d935ab3
commit
a0bc1dcbe8
@@ -26,11 +26,6 @@ extern "C" {
|
||||
int rtems_dosfs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry,
|
||||
const void *data);
|
||||
|
||||
#define MSDOS_FMT_FATANY 0
|
||||
#define MSDOS_FMT_FAT12 1
|
||||
#define MSDOS_FMT_FAT16 2
|
||||
#define MSDOS_FMT_FAT32 3
|
||||
|
||||
#define MSDOS_FMT_INFO_LEVEL_NONE (0)
|
||||
#define MSDOS_FMT_INFO_LEVEL_INFO (1)
|
||||
#define MSDOS_FMT_INFO_LEVEL_DETAIL (2)
|
||||
@@ -46,7 +41,6 @@ typedef struct {
|
||||
uint32_t sectors_per_cluster; /* request value: sectors per cluster */
|
||||
uint32_t fat_num; /* request value: number of FATs on disk */
|
||||
uint32_t files_per_root_dir; /* request value: file entries in root */
|
||||
uint8_t fattype; /* request value: MSDOS_FMT_FAT12/16/32 */
|
||||
uint8_t media; /* media code. default: 0xF8 */
|
||||
bool quick_format; /* true: do not clear out data sectors */
|
||||
bool skip_alignment; /* do not align FAT, data cluster, and */
|
||||
|
||||
@@ -300,7 +300,8 @@ static int msdos_format_eval_sectors_per_cluster
|
||||
uint32_t sectors_per_cluster, /* sectors per cluster (requested) */
|
||||
const bool skip_alignment, /* true for no cluster alignment */
|
||||
uint32_t *sectors_per_cluster_adj, /* ret: sec per cluster (granted) */
|
||||
uint32_t *sectors_per_fat_ptr /* ret: sectors needed for one FAT */
|
||||
uint32_t *sectors_per_fat_ptr, /* ret: sectors needed for one FAT */
|
||||
uint32_t *data_cluster_cnt
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
@@ -313,7 +314,6 @@ static int msdos_format_eval_sectors_per_cluster
|
||||
uint32_t fatdata_cluster_cnt;
|
||||
uint32_t fat_capacity;
|
||||
uint32_t sectors_per_fat;
|
||||
uint32_t data_cluster_cnt;
|
||||
uint32_t fatdata_sect_cnt;
|
||||
uint32_t fat_sectors_cnt;
|
||||
/*
|
||||
@@ -357,15 +357,15 @@ static int msdos_format_eval_sectors_per_cluster
|
||||
sectors_per_cluster,
|
||||
skip_alignment);
|
||||
|
||||
data_cluster_cnt = (fatdata_cluster_cnt -
|
||||
*data_cluster_cnt = (fatdata_cluster_cnt -
|
||||
((fat_sectors_cnt
|
||||
+ (sectors_per_cluster - 1))
|
||||
/ sectors_per_cluster));
|
||||
/*
|
||||
* data cluster count too big? Then make clusters bigger
|
||||
*/
|
||||
if (((fattype == FAT_FAT12) && (data_cluster_cnt > FAT_FAT12_MAX_CLN)) ||
|
||||
((fattype == FAT_FAT16) && (data_cluster_cnt > FAT_FAT16_MAX_CLN))) {
|
||||
if (((fattype == FAT_FAT12) && (*data_cluster_cnt > FAT_FAT12_MAX_CLN)) ||
|
||||
((fattype == FAT_FAT16) && (*data_cluster_cnt > FAT_FAT16_MAX_CLN))) {
|
||||
sectors_per_cluster *= 2;
|
||||
}
|
||||
else {
|
||||
@@ -421,6 +421,9 @@ static int msdos_format_determine_fmt_params
|
||||
uint32_t onebit;
|
||||
uint32_t sectors_per_cluster_adj = 0;
|
||||
uint64_t total_size = 0;
|
||||
uint32_t data_clusters_cnt;
|
||||
uint8_t iteration_cnt = 0;
|
||||
uint8_t fat_type = UINT8_MAX;
|
||||
|
||||
memset(fmt_params,0,sizeof(*fmt_params));
|
||||
|
||||
@@ -498,153 +501,173 @@ static int msdos_format_determine_fmt_params
|
||||
*/
|
||||
if (ret_val == 0) {
|
||||
fmt_params->sectors_per_cluster = 1;
|
||||
if ((rqdata != NULL) &&
|
||||
(rqdata->fattype == MSDOS_FMT_FAT12)) {
|
||||
/*
|
||||
* limiting values for disk size, fat type, sectors per cluster
|
||||
* NOTE: maximum sect_per_clust is arbitrarily choosen with values that
|
||||
* are a compromise concerning capacity and efficency
|
||||
*/
|
||||
uint32_t fat12_sect_per_clust = 8;
|
||||
uint32_t fat16_sect_per_clust = 32;
|
||||
|
||||
if (rqdata != NULL && rqdata->sectors_per_cluster != 0) {
|
||||
fat12_sect_per_clust = rqdata->sectors_per_cluster;
|
||||
fat16_sect_per_clust = rqdata->sectors_per_cluster;
|
||||
}
|
||||
|
||||
if (fmt_params->totl_sector_cnt < FAT_FAT12_MAX_CLN * fat12_sect_per_clust) {
|
||||
fmt_params->fattype = FAT_FAT12;
|
||||
/* start trying with small clusters */
|
||||
fmt_params->sectors_per_cluster = 2;
|
||||
}
|
||||
else if ((rqdata != NULL) &&
|
||||
(rqdata->fattype == MSDOS_FMT_FAT16)) {
|
||||
else if (fmt_params->totl_sector_cnt < FAT_FAT16_MAX_CLN * fat16_sect_per_clust) {
|
||||
fmt_params->fattype = FAT_FAT16;
|
||||
/* start trying with small clusters */
|
||||
fmt_params->sectors_per_cluster = 2;
|
||||
}
|
||||
else if ((rqdata != NULL) &&
|
||||
(rqdata->fattype == MSDOS_FMT_FAT32)) {
|
||||
else {
|
||||
#define ONE_GB (1024L * 1024L * 1024L)
|
||||
uint32_t gigs = (total_size + ONE_GB) / ONE_GB;
|
||||
int b;
|
||||
fmt_params->fattype = FAT_FAT32;
|
||||
/* scale with the size of disk... */
|
||||
for (b = 31; b > 0; b--)
|
||||
if ((gigs & (1 << b)) != 0)
|
||||
break;
|
||||
fmt_params->sectors_per_cluster = 1 << b;
|
||||
}
|
||||
else if ((rqdata != NULL) &&
|
||||
(rqdata->fattype != MSDOS_FMT_FATANY)) {
|
||||
ret_val = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
else {
|
||||
|
||||
while (ret_val == 0 && fmt_params->fattype != fat_type) {
|
||||
/*
|
||||
* limiting values for disk size, fat type, sectors per cluster
|
||||
* NOTE: maximum sect_per_clust is arbitrarily choosen with values that
|
||||
* are a compromise concerning capacity and efficency
|
||||
* try to use user requested cluster size
|
||||
*/
|
||||
uint32_t fat12_sect_per_clust = 8;
|
||||
uint32_t fat16_sect_per_clust = 32;
|
||||
|
||||
if (rqdata != NULL && rqdata->sectors_per_cluster != 0) {
|
||||
fat12_sect_per_clust = rqdata->sectors_per_cluster;
|
||||
fat16_sect_per_clust = rqdata->sectors_per_cluster;
|
||||
if (rqdata != NULL && rqdata->sectors_per_cluster > 0) {
|
||||
fmt_params->sectors_per_cluster = rqdata->sectors_per_cluster;
|
||||
}
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
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) {
|
||||
/* value is small enough so this value is ok */
|
||||
onebit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fmt_params->totl_sector_cnt
|
||||
< FAT_FAT12_MAX_CLN * fat12_sect_per_clust) {
|
||||
fmt_params->fattype = FAT_FAT12;
|
||||
/* start trying with small clusters */
|
||||
fmt_params->sectors_per_cluster = 2;
|
||||
/*
|
||||
* Skip aligning structures or d align them
|
||||
*/
|
||||
if (ret_val == 0 && rqdata != NULL)
|
||||
{
|
||||
fmt_params->skip_alignment = rqdata->skip_alignment;
|
||||
if (fmt_params->skip_alignment)
|
||||
fmt_params->sectors_per_cluster = 1;
|
||||
}
|
||||
else if (fmt_params->totl_sector_cnt
|
||||
< FAT_FAT16_MAX_CLN * fat16_sect_per_clust) {
|
||||
fmt_params->fattype = FAT_FAT16;
|
||||
/* start trying with small clusters */
|
||||
fmt_params->sectors_per_cluster = 2;
|
||||
|
||||
if (ret_val == 0) {
|
||||
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
|
||||
"sectors per cluster: %d\n", fmt_params->sectors_per_cluster);
|
||||
|
||||
if (fmt_params->fattype == FAT_FAT32) {
|
||||
/* recommended: for FAT32, always set reserved sector count to 32 */
|
||||
fmt_params->rsvd_sector_cnt = 32;
|
||||
/* for FAT32, always set files per root directory 0 */
|
||||
fmt_params->files_per_root_dir = 0;
|
||||
/* location of copy of MBR */
|
||||
fmt_params->mbr_copy_sec = 6;
|
||||
/* location of fsinfo sector */
|
||||
fmt_params->fsinfo_sec = 1;
|
||||
|
||||
}
|
||||
else {
|
||||
/* recommended: for FAT12/FAT16, always set reserved sector count to 1 */
|
||||
fmt_params->rsvd_sector_cnt = 1;
|
||||
/* recommended: for FAT16, set files per root directory to 512 */
|
||||
/* for FAT12/FAT16, set files per root directory */
|
||||
/* must fill up an even count of sectors */
|
||||
if ((rqdata != NULL) &&
|
||||
(rqdata->files_per_root_dir > 0)) {
|
||||
fmt_params->files_per_root_dir = rqdata->files_per_root_dir;
|
||||
}
|
||||
else {
|
||||
if (fmt_params->fattype == FAT_FAT16) {
|
||||
fmt_params->files_per_root_dir = 512;
|
||||
}
|
||||
else {
|
||||
fmt_params->files_per_root_dir = 64;
|
||||
}
|
||||
}
|
||||
fmt_params->files_per_root_dir = (fmt_params->files_per_root_dir +
|
||||
(2*fmt_params->bytes_per_sector/
|
||||
FAT_DIRENTRY_SIZE-1));
|
||||
fmt_params->files_per_root_dir -= (fmt_params->files_per_root_dir %
|
||||
(2*fmt_params->bytes_per_sector
|
||||
/FAT_DIRENTRY_SIZE));
|
||||
|
||||
}
|
||||
fmt_params->root_dir_sectors =
|
||||
(((fmt_params->files_per_root_dir * FAT_DIRENTRY_SIZE)
|
||||
+ fmt_params->bytes_per_sector - 1)
|
||||
/ fmt_params->bytes_per_sector);
|
||||
}
|
||||
else {
|
||||
#define ONE_GB (1024L * 1024L * 1024L)
|
||||
uint32_t gigs = (total_size + ONE_GB) / ONE_GB;
|
||||
int b;
|
||||
fmt_params->fattype = FAT_FAT32;
|
||||
/* scale with the size of disk... */
|
||||
for (b = 31; b > 0; b--)
|
||||
if ((gigs & (1 << b)) != 0)
|
||||
break;
|
||||
fmt_params->sectors_per_cluster = 1 << b;
|
||||
if (ret_val == 0) {
|
||||
/*
|
||||
* check values to get legal arrangement of FAT type and cluster count
|
||||
*/
|
||||
|
||||
ret_val = msdos_format_eval_sectors_per_cluster(fmt_params->fattype,
|
||||
fmt_params->bytes_per_sector,
|
||||
fmt_params->totl_sector_cnt,
|
||||
fmt_params->rsvd_sector_cnt,
|
||||
fmt_params->root_dir_sectors,
|
||||
fmt_params->fat_num,
|
||||
fmt_params->sectors_per_cluster,
|
||||
fmt_params->skip_alignment,
|
||||
§ors_per_cluster_adj,
|
||||
&fmt_params->sectors_per_fat,
|
||||
&data_clusters_cnt);
|
||||
fmt_params->sectors_per_cluster = sectors_per_cluster_adj;
|
||||
fat_type = fmt_params->fattype;
|
||||
if (data_clusters_cnt < FAT_FAT12_MAX_CLN ) {
|
||||
fmt_params->fattype = FAT_FAT12;
|
||||
if (fat_type != fmt_params->fattype) {
|
||||
/* start trying with small clusters */
|
||||
fmt_params->sectors_per_cluster = 2;
|
||||
}
|
||||
}
|
||||
else if (data_clusters_cnt < FAT_FAT16_MAX_CLN) {
|
||||
fmt_params->fattype = FAT_FAT16;
|
||||
if (fat_type != fmt_params->fattype) {
|
||||
/* start trying with small clusters */
|
||||
fmt_params->sectors_per_cluster = 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fmt_params->fattype = FAT_FAT32;
|
||||
if (fat_type != fmt_params->fattype) {
|
||||
#define ONE_GB (1024L * 1024L * 1024L)
|
||||
uint32_t gigs = (total_size + ONE_GB) / ONE_GB;
|
||||
int b;
|
||||
/* scale with the size of disk... */
|
||||
for (b = 31; b > 0; b--)
|
||||
if ((gigs & (1 << b)) != 0)
|
||||
break;
|
||||
fmt_params->sectors_per_cluster = 1 << b;
|
||||
}
|
||||
}
|
||||
if (fat_type != fmt_params->fattype && 1 < iteration_cnt) {
|
||||
--fmt_params->totl_sector_cnt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
++iteration_cnt;
|
||||
}
|
||||
/*
|
||||
* try to use user requested cluster size
|
||||
*/
|
||||
if ((rqdata != NULL) &&
|
||||
(rqdata->sectors_per_cluster > 0)) {
|
||||
fmt_params->sectors_per_cluster =
|
||||
rqdata->sectors_per_cluster;
|
||||
}
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
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) {
|
||||
/* value is small enough so this value is ok */
|
||||
onebit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret_val == 0 && rqdata != NULL) {
|
||||
fmt_params->skip_alignment = rqdata->skip_alignment;
|
||||
}
|
||||
|
||||
if (ret_val == 0) {
|
||||
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
|
||||
"sectors per cluster: %d\n", fmt_params->sectors_per_cluster);
|
||||
|
||||
if (fmt_params->fattype == FAT_FAT32) {
|
||||
/* recommended: for FAT32, always set reserved sector count to 32 */
|
||||
fmt_params->rsvd_sector_cnt = 32;
|
||||
/* for FAT32, always set files per root directory 0 */
|
||||
fmt_params->files_per_root_dir = 0;
|
||||
/* location of copy of MBR */
|
||||
fmt_params->mbr_copy_sec = 6;
|
||||
/* location of fsinfo sector */
|
||||
fmt_params->fsinfo_sec = 1;
|
||||
|
||||
}
|
||||
else {
|
||||
/* recommended: for FAT12/FAT16, always set reserved sector count to 1 */
|
||||
fmt_params->rsvd_sector_cnt = 1;
|
||||
/* recommended: for FAT16, set files per root directory to 512 */
|
||||
/* for FAT12/FAT16, set files per root directory */
|
||||
/* must fill up an even count of sectors */
|
||||
if ((rqdata != NULL) &&
|
||||
(rqdata->files_per_root_dir > 0)) {
|
||||
fmt_params->files_per_root_dir = rqdata->files_per_root_dir;
|
||||
}
|
||||
else {
|
||||
if (fmt_params->fattype == FAT_FAT16) {
|
||||
fmt_params->files_per_root_dir = 512;
|
||||
}
|
||||
else {
|
||||
fmt_params->files_per_root_dir = 64;
|
||||
}
|
||||
}
|
||||
fmt_params->files_per_root_dir = (fmt_params->files_per_root_dir +
|
||||
(2*fmt_params->bytes_per_sector/
|
||||
FAT_DIRENTRY_SIZE-1));
|
||||
fmt_params->files_per_root_dir -= (fmt_params->files_per_root_dir %
|
||||
(2*fmt_params->bytes_per_sector
|
||||
/FAT_DIRENTRY_SIZE));
|
||||
}
|
||||
fmt_params->root_dir_sectors =
|
||||
(((fmt_params->files_per_root_dir * FAT_DIRENTRY_SIZE)
|
||||
+ fmt_params->bytes_per_sector - 1)
|
||||
/ fmt_params->bytes_per_sector);
|
||||
}
|
||||
if (ret_val == 0) {
|
||||
/*
|
||||
* check values to get legal arrangement of FAT type and cluster count
|
||||
*/
|
||||
|
||||
ret_val = msdos_format_eval_sectors_per_cluster
|
||||
(fmt_params->fattype,
|
||||
fmt_params->bytes_per_sector,
|
||||
fmt_params->totl_sector_cnt,
|
||||
fmt_params->rsvd_sector_cnt,
|
||||
fmt_params->root_dir_sectors,
|
||||
fmt_params->fat_num,
|
||||
fmt_params->sectors_per_cluster,
|
||||
fmt_params->skip_alignment,
|
||||
§ors_per_cluster_adj,
|
||||
&(fmt_params->sectors_per_fat));
|
||||
fmt_params->sectors_per_cluster = sectors_per_cluster_adj;
|
||||
}
|
||||
|
||||
if (0 == ret_val)
|
||||
@@ -780,6 +803,7 @@ static int msdos_format_determine_fmt_params
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
|
||||
@@ -33,7 +33,6 @@ static int rtems_shell_main_msdos_format(
|
||||
.sectors_per_cluster = 0,
|
||||
.fat_num = 0,
|
||||
.files_per_root_dir = 0,
|
||||
.fattype = MSDOS_FMT_FATANY,
|
||||
.media = 0,
|
||||
.quick_format = TRUE,
|
||||
.skip_alignment = 0,
|
||||
@@ -92,27 +91,6 @@ static int rtems_shell_main_msdos_format(
|
||||
rqdata.files_per_root_dir = (uint32_t) tmp;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
arg++;
|
||||
if (arg == argc) {
|
||||
fprintf (stderr, "error: no FAT type.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp (argv[arg], "any") == 0)
|
||||
rqdata.fattype = MSDOS_FMT_FATANY;
|
||||
else if (strcmp (argv[arg], "12") == 0)
|
||||
rqdata.fattype = MSDOS_FMT_FAT12;
|
||||
else if (strcmp (argv[arg], "16") == 0)
|
||||
rqdata.fattype = MSDOS_FMT_FAT16;
|
||||
else if (strcmp (argv[arg], "32") == 0)
|
||||
rqdata.fattype = MSDOS_FMT_FAT32;
|
||||
else {
|
||||
fprintf (stderr, "error: invalid type, can any, 12, 16, or 32\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
rqdata.info_level++;
|
||||
break;
|
||||
@@ -146,7 +124,6 @@ static int rtems_shell_main_msdos_format(
|
||||
printf (" %-20s: %" PRIu32 "\n", "sectors per cluster", rqdata.sectors_per_cluster);
|
||||
printf (" %-20s: %" PRIu32 "\n", "fats", rqdata.fat_num);
|
||||
printf (" %-20s: %" PRIu32 "\n", "files per root dir", rqdata.files_per_root_dir);
|
||||
printf (" %-20s: %i\n", "fat type", rqdata.fattype);
|
||||
printf (" %-20s: %d\n", "media", rqdata.media);
|
||||
printf (" %-20s: %d\n", "quick_format", rqdata.quick_format);
|
||||
printf (" %-20s: %s\n", "skip_alignment", (0 == rqdata.skip_alignment) ? "false" : "true");
|
||||
@@ -162,7 +139,7 @@ static int rtems_shell_main_msdos_format(
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OPTIONS "[-V label] [-s sectors/cluster] [-r size] [-t any/12/16/32] [-v]"
|
||||
#define OPTIONS "[-V label] [-s sectors/cluster] [-r size] [-v]"
|
||||
|
||||
rtems_shell_cmd_t rtems_shell_MSDOSFMT_Command = {
|
||||
"mkdos", /* name */
|
||||
|
||||
@@ -31,7 +31,6 @@ msdos_format_request_param_t rqdata = {
|
||||
sectors_per_cluster: 0,
|
||||
fat_num: 0,
|
||||
files_per_root_dir: 0,
|
||||
fattype: MSDOS_FMT_FATANY,
|
||||
media: 0,
|
||||
quick_format: FALSE,
|
||||
skip_alignment: 0,
|
||||
|
||||
Reference in New Issue
Block a user