mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
Added search for good cluster size
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@804 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
a88a6ecb67
commit
c6ad3e0d22
6 changed files with 541 additions and 49 deletions
|
@ -41,6 +41,7 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/fs.h>
|
||||
|
@ -51,6 +52,33 @@
|
|||
#include "fs_fat32.h"
|
||||
#include "fs_mkfatfs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NDX12 0
|
||||
#define NDX16 1
|
||||
#define NDX32 2
|
||||
|
||||
#define fatconfig12 fatconfig[NDX12]
|
||||
#define fatconfig16 fatconfig[NDX16]
|
||||
#define fatconfig32 fatconfig[NDX32]
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct fat_config_s
|
||||
{
|
||||
uint32 fc_navailsects; /* The number of available sectors */
|
||||
uint32 fc_nfatsects; /* The number of sectors in one FAT */
|
||||
uint32 fc_nclusters; /* The number of clusters in the filesystem */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -59,7 +87,7 @@
|
|||
* Name: mkfatfs_nfatsect12
|
||||
*
|
||||
* Description:
|
||||
* Calculate the number of sectors need for the fat in a FAT12 file system.
|
||||
* Calculate the number of sectors need for one fat in a FAT12 file system.
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
|
@ -72,12 +100,12 @@
|
|||
*
|
||||
* Return:
|
||||
* 0: That calculation would have overflowed
|
||||
* >0: The total size of the FAT in sectors.
|
||||
* >0: The size of one FAT in sectors.
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline uint32 mkfatfs_nfatsect12(FAR struct fat_format_s *fmt,
|
||||
FAR struct fat_var_s *var,
|
||||
uint32 navailsects)
|
||||
static inline uint32
|
||||
mkfatfs_nfatsect12(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
uint32 navailsects)
|
||||
{
|
||||
uint32 denom ;
|
||||
uint32 numer;
|
||||
|
@ -87,7 +115,7 @@ static inline uint32 mkfatfs_nfatsect12(FAR struct fat_format_s *fmt,
|
|||
* references (except for the first sector of each FAT which has two reserved
|
||||
* 12-bit values). And the total number of FAT sectors needed is:
|
||||
*
|
||||
* nfatsects = nfats * (1.5 * (ndataclust + 2) / sectorsize)
|
||||
* nfatsects = (1.5 * (ndataclust + 2) / sectorsize)
|
||||
*
|
||||
* where:
|
||||
*
|
||||
|
@ -96,8 +124,8 @@ static inline uint32 mkfatfs_nfatsect12(FAR struct fat_format_s *fmt,
|
|||
*
|
||||
* The solution to this set of linear equations is:
|
||||
*
|
||||
* nfatsects = nfats * (3 * navailsects + 6 * clustersize) /
|
||||
* (3 * nfats + 2 * sectorsize * clustersize)
|
||||
* nfatsects = (3 * navailsects + 6 * clustersize) /
|
||||
* (3 * nfats + 2 * sectorsize * clustersize)
|
||||
*
|
||||
* The numerator would overflow uint32 if:
|
||||
*
|
||||
|
@ -114,7 +142,7 @@ static inline uint32 mkfatfs_nfatsect12(FAR struct fat_format_s *fmt,
|
|||
+ (var->fv_sectorsize << (fmt->ff_clustshift + 1));
|
||||
numer = (navailsects << 1) + navailsects
|
||||
+ (1 << (fmt->ff_clustshift + 2)) + (1 << (fmt->ff_clustshift + 1));
|
||||
return fmt->ff_nfats * (numer + denom - 1) / denom;
|
||||
return (numer + denom - 1) / denom;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -126,7 +154,7 @@ static inline uint32 mkfatfs_nfatsect12(FAR struct fat_format_s *fmt,
|
|||
* Name: mkfatfs_nfatsect16
|
||||
*
|
||||
* Description:
|
||||
* Calculate the number of sectors need for the fat in a FAT16 file system.
|
||||
* Calculate the number of sectors need for one fat in a FAT16 file system.
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
|
@ -138,12 +166,12 @@ static inline uint32 mkfatfs_nfatsect12(FAR struct fat_format_s *fmt,
|
|||
* reserved sectors.
|
||||
*
|
||||
* Return:
|
||||
* The total size of the FAT in sectors.
|
||||
* The size of one FAT in sectors.
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline uint32 mkfatfs_nfatsect16(FAR struct fat_format_s *fmt,
|
||||
FAR struct fat_var_s *var,
|
||||
uint32 navailsects)
|
||||
static inline uint32
|
||||
mkfatfs_nfatsect16(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
uint32 navailsects)
|
||||
{
|
||||
uint32 denom;
|
||||
uint32 numer;
|
||||
|
@ -153,7 +181,7 @@ static inline uint32 mkfatfs_nfatsect16(FAR struct fat_format_s *fmt,
|
|||
* references (except for the first sector of each FAT which has two reserved
|
||||
* 16-bit values). And the total number of FAT sectors needed is:
|
||||
*
|
||||
* nfatsects = nfats * (2 * (ndataclust + 2) / sectorsize)
|
||||
* nfatsects = (2 * (ndataclust + 2) / sectorsize)
|
||||
*
|
||||
* where:
|
||||
*
|
||||
|
@ -162,8 +190,8 @@ static inline uint32 mkfatfs_nfatsect16(FAR struct fat_format_s *fmt,
|
|||
*
|
||||
* The solution to this set of linear equations is:
|
||||
*
|
||||
* nfatsects = nfats * (navailsects + 2 * clustersize) /
|
||||
* (nfats + sectorsize * clustersize / 2)
|
||||
* nfatsects = (navailsects + 2 * clustersize) /
|
||||
* (nfats + sectorsize * clustersize / 2)
|
||||
*
|
||||
* Overflow in the calculation of the numerator could occur if:
|
||||
*
|
||||
|
@ -180,14 +208,14 @@ static inline uint32 mkfatfs_nfatsect16(FAR struct fat_format_s *fmt,
|
|||
denom = fmt->ff_nfats + (var->fv_sectorsize << (fmt->ff_clustshift - 1));
|
||||
numer = navailsects + (1 << (fmt->ff_clustshift + 1));
|
||||
}
|
||||
return fmt->ff_nfats * (numer + denom - 1) / denom;
|
||||
return (numer + denom - 1) / denom;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_nfatsect32
|
||||
*
|
||||
* Description:
|
||||
* Calculate the number of sectors need for the fat in a FAT32 file system.
|
||||
* Calculate the number of sectors need for one fat in a FAT32 file system.
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
|
@ -199,12 +227,12 @@ static inline uint32 mkfatfs_nfatsect16(FAR struct fat_format_s *fmt,
|
|||
* reserved sectors.
|
||||
*
|
||||
* Return:
|
||||
* The total size of the FAT in sectors.
|
||||
* The size of one FAT in sectors.
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline uint32 mkfatfs_nfatsect32(FAR struct fat_format_s *fmt,
|
||||
FAR struct fat_var_s *var,
|
||||
uint32 navailsects)
|
||||
static inline uint32
|
||||
mkfatfs_nfatsect32(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
uint32 navailsects)
|
||||
{
|
||||
uint32 denom;
|
||||
uint32 numer;
|
||||
|
@ -214,7 +242,7 @@ static inline uint32 mkfatfs_nfatsect32(FAR struct fat_format_s *fmt,
|
|||
* references (except for the first sector of each FAT which has three reserved
|
||||
* 32-bit values). And the total number of FAT sectors needed is:
|
||||
*
|
||||
* nfatsects = nfats * (4 * (ndataclust + 3) / sectorsize)
|
||||
* nfatsects = (4 * (ndataclust + 3) / sectorsize)
|
||||
*
|
||||
* where:
|
||||
*
|
||||
|
@ -223,8 +251,8 @@ static inline uint32 mkfatfs_nfatsect32(FAR struct fat_format_s *fmt,
|
|||
*
|
||||
* The solution to this set of linear equations is:
|
||||
*
|
||||
* nfatsects = nfats * (navailsects + 3 * clustersize) /
|
||||
* (nfats + sectorsize * clustersize / 4)
|
||||
* nfatsects = (navailsects + 3 * clustersize) /
|
||||
* (nfats + sectorsize * clustersize / 4)
|
||||
*
|
||||
* Overflow in the calculation of the numerator could occur if:
|
||||
*
|
||||
|
@ -246,7 +274,471 @@ static inline uint32 mkfatfs_nfatsect32(FAR struct fat_format_s *fmt,
|
|||
denom = fmt->ff_nfats + (var->fv_sectorsize << (fmt->ff_clustshift - 2));
|
||||
numer = navailsects + (1 << (fmt->ff_clustshift + 1)) + (1 << fmt->ff_clustshift);
|
||||
}
|
||||
return fmt->ff_nfats * (numer + denom - 1) / denom;
|
||||
return (numer + denom - 1) / denom;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_clustersearchlimits
|
||||
*
|
||||
* Description:
|
||||
* Pick the starting and ending cluster size to use in the search for the
|
||||
* the optimal cluster size.
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
* var - Other format parameters that are not caller specifiable. (Most
|
||||
* set by mkfatfs_configfatfs()).
|
||||
*
|
||||
* Return:
|
||||
* Starting cluster size is set in fmt->ff_clustshift; Final cluster
|
||||
* size is the returned value.
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline ubyte
|
||||
mkfatfs_clustersearchlimits(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var)
|
||||
{
|
||||
ubyte mxclustshift;
|
||||
|
||||
/* Did the caller already pick the cluster size? If not, the clustshift value
|
||||
* will be 0xff
|
||||
*/
|
||||
|
||||
if (fmt->ff_clustshift == 0xff)
|
||||
{
|
||||
/* Pick a starting size based on the number of sectors on the device */
|
||||
|
||||
if (var->fv_nsectors < 2048)
|
||||
{
|
||||
/* 2k sectors, start wit 1 sector/cluster. */
|
||||
fmt->ff_clustshift = 0;
|
||||
}
|
||||
else if (var->fv_nsectors < 4096)
|
||||
{
|
||||
/* 4k sectors, start with 2 sector/cluster. */
|
||||
fmt->ff_clustshift = 1;
|
||||
}
|
||||
else if (var->fv_nsectors < 8192)
|
||||
{
|
||||
/* 8k sectors, start with 4 sector/cluster. */
|
||||
fmt->ff_clustshift = 2;
|
||||
}
|
||||
else if (var->fv_nsectors < 16384)
|
||||
{
|
||||
/* 16k sectors, start with 8 sector/cluster. */
|
||||
fmt->ff_clustshift = 3;
|
||||
}
|
||||
else if (var->fv_nsectors < 32768)
|
||||
{
|
||||
/* 32k sectors, start with 16 sector/cluster. */
|
||||
fmt->ff_clustshift = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, 32 sector/cluster. */
|
||||
fmt->ff_clustshift = 5;
|
||||
}
|
||||
|
||||
/* Wherever the search starts, it will end with the maximum of
|
||||
* 128 sectors per cluster
|
||||
*/
|
||||
|
||||
mxclustshift = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The caller has selected a cluster size. There will be no search!
|
||||
* Just set the maximum to the caller specificed value.
|
||||
*/
|
||||
|
||||
mxclustshift = fmt->ff_clustshift;
|
||||
}
|
||||
return mxclustshift;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_try12
|
||||
*
|
||||
* Description:
|
||||
* Try to define a FAT12 filesystem on the device using the candidate
|
||||
* sectors per cluster
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
* var - Other format parameters that are not caller specifiable. (Most
|
||||
* set by mkfatfs_configfatfs()).
|
||||
* fatconfig - FAT12-specific configuration
|
||||
*
|
||||
* Return:
|
||||
* Zero on success configuration of a FAT12 file system; negated errno
|
||||
* on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline int
|
||||
mkfatfs_tryfat12(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
FAR struct fat_config_s *config)
|
||||
{
|
||||
uint32 maxnclusters;
|
||||
|
||||
/* Calculate the number sectors in one FAT required to access all of the
|
||||
* available sectors.
|
||||
*/
|
||||
|
||||
config->fc_nfatsects = mkfatfs_nfatsect12(fmt, var, config->fc_navailsects);
|
||||
if (config->fc_nfatsects > 0)
|
||||
{
|
||||
/* Calculate the number of clusters available given the number of available
|
||||
* sectors and the number of those that will be used for FAT:
|
||||
*/
|
||||
|
||||
config->fc_nclusters =
|
||||
(config->fc_navailsects -
|
||||
fmt->ff_nfats * config->fc_nfatsects) >> fmt->ff_clustshift;
|
||||
|
||||
/* Calculate the maximum number of clusters that could be supported by a
|
||||
* FAT of this size.
|
||||
*
|
||||
* maxnclusters = nfatsects * sectorsize / 1.5 - 2
|
||||
*/
|
||||
|
||||
maxnclusters = (config->fc_nfatsects >> (var->fv_sectshift + 1)) / 3;
|
||||
if (maxnclusters > FAT_MAXCLUST12)
|
||||
{
|
||||
maxnclusters = FAT_MAXCLUST12;
|
||||
}
|
||||
fvdbg("nfatsects=%u nclusters=%u (max=%u)\n",
|
||||
config->fc_nfatsects, config->fc_nclusters, maxnclusters);
|
||||
|
||||
/* Check if this number of clusters would overflow the maximum for
|
||||
* FAT12 (remembering that two FAT cluster slots are reserved).
|
||||
*/
|
||||
|
||||
if (config->fc_nclusters > maxnclusters - 2)
|
||||
{
|
||||
fvdbg("Too many clusters for FAT12\n");
|
||||
return -ENFILE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_try16
|
||||
*
|
||||
* Description:
|
||||
* Try to define a FAT16 filesystem on the device using the candidate
|
||||
* sectors per cluster
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
* var - Other format parameters that are not caller specifiable. (Most
|
||||
* set by mkfatfs_configfatfs()).
|
||||
* fatconfig - FAT16-specific configuration
|
||||
*
|
||||
* Return:
|
||||
* Zero on success configuration of a FAT16 file system; negated errno
|
||||
* on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline int
|
||||
mkfatfs_tryfat16(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
FAR struct fat_config_s *config)
|
||||
{
|
||||
uint32 maxnclusters;
|
||||
|
||||
/* Calculate the number sectors in one FAT required to access all of the
|
||||
* available sectors.
|
||||
*/
|
||||
|
||||
config->fc_nfatsects = mkfatfs_nfatsect16(fmt, var, config->fc_navailsects);
|
||||
if (config->fc_nfatsects > 0)
|
||||
{
|
||||
/* Calculate the number of clusters available given the number of available
|
||||
* sectors and the number of those that will be used for FAT:
|
||||
*/
|
||||
|
||||
config->fc_nclusters =
|
||||
(config->fc_navailsects -
|
||||
fmt->ff_nfats * config->fc_nfatsects) >> fmt->ff_clustshift;
|
||||
|
||||
/* Calculate the maximum number of clusters that could be supported by a
|
||||
* FAT of this size.
|
||||
*
|
||||
* maxnclusters = nfatsects * sectorsize / 2 - 2
|
||||
*/
|
||||
|
||||
maxnclusters = config->fc_nfatsects << (var->fv_sectorsize - 1);
|
||||
if (maxnclusters > FAT_MAXCLUST16)
|
||||
{
|
||||
maxnclusters = FAT_MAXCLUST16;
|
||||
}
|
||||
fvdbg("nfatsects=%u nclusters=%u (min=%u max=%u)\n",
|
||||
config->fc_nfatsects, config->fc_nclusters, FAT_MINCLUST16, maxnclusters);
|
||||
|
||||
/* Check if this number of clusters would overflow the maximum for
|
||||
* FAT16 (remembering that two FAT cluster slots are reserved).
|
||||
* Check the lower limit as well. The FAT12 is distinguished from FAT16
|
||||
* by comparing the number of clusters on the device agains a known
|
||||
* threshold. If a small FAT16 file system were created, then it would
|
||||
* be confused as a FAT12 at mount time.
|
||||
*/
|
||||
|
||||
if ((config->fc_nclusters > maxnclusters - 2) ||
|
||||
(config->fc_nclusters < FAT_MINCLUST16))
|
||||
{
|
||||
fvdbg("Too few or too many clusters for FAT16\n");
|
||||
return -ENFILE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_try32
|
||||
*
|
||||
* Description:
|
||||
* Try to define a FAT32 filesystem on the device using the candidate
|
||||
* sectors per cluster
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
* var - Other format parameters that are not caller specifiable. (Most
|
||||
* set by mkfatfs_configfatfs()).
|
||||
* fatconfig - FAT32-specific configuration
|
||||
*
|
||||
* Return:
|
||||
* Zero on success configuration of a FAT32 file system; negated errno
|
||||
* on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline int
|
||||
mkfatfs_tryfat32(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
FAR struct fat_config_s *config)
|
||||
{
|
||||
uint32 maxnclusters;
|
||||
|
||||
/* Calculate the number sectors in one FAT required to access all of the
|
||||
* available sectors.
|
||||
*/
|
||||
|
||||
config->fc_nfatsects = mkfatfs_nfatsect32(fmt, var, config->fc_navailsects);
|
||||
if (config->fc_nfatsects > 0)
|
||||
{
|
||||
/* Calculate the number of clusters available given the number of available
|
||||
* sectors and the number of those that will be used for FAT:
|
||||
*/
|
||||
|
||||
config->fc_nclusters =
|
||||
(config->fc_navailsects -
|
||||
fmt->ff_nfats * config->fc_nfatsects) >> fmt->ff_clustshift;
|
||||
|
||||
/* Calculate the maximum number of clusters that could be supported by a
|
||||
* FAT of this size.
|
||||
*
|
||||
* maxnclusters = nfatsects * sectorsize / 4 - 2
|
||||
*/
|
||||
|
||||
maxnclusters = (config->fc_nfatsects >> (var->fv_sectshift - 2));
|
||||
if (maxnclusters > FAT_MAXCLUST32)
|
||||
{
|
||||
maxnclusters = FAT_MAXCLUST32;
|
||||
}
|
||||
fvdbg("nfatsects=%u nclusters=%u (max=%u)\n",
|
||||
config->fc_nfatsects, config->fc_nclusters, maxnclusters);
|
||||
|
||||
/* Check if this number of clusters would overflow the maximum for
|
||||
* FAT32 (remembering that two FAT cluster slots are reserved).
|
||||
*/
|
||||
|
||||
if ((config->fc_nclusters > maxnclusters - 3) ||
|
||||
(config->fc_nclusters < FAT_MINCLUST32 && fmt->ff_fattype != 32))
|
||||
{
|
||||
fvdbg("Too few or too many clusters for FAT32\n");
|
||||
return -ENFILE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_clustersearch
|
||||
*
|
||||
* Description:
|
||||
* Search to find the smallest (reasonable) cluster size for the FAT file
|
||||
* system.
|
||||
*
|
||||
* Input:
|
||||
* fmt - Caller specified format parameters
|
||||
* var - Other format parameters that are not caller specifiable. (Most
|
||||
* set by mkfatfs_configfatfs()).
|
||||
*
|
||||
* Return:
|
||||
* Zero on success; negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int
|
||||
mkfatfs_clustersearch(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var)
|
||||
{
|
||||
struct fat_config_s fatconfig[3];
|
||||
uint32 nrootdirsects = 0;
|
||||
ubyte mxclustshift;
|
||||
|
||||
memset(fatconfig, 0, 3*sizeof(struct fat_config_s));
|
||||
|
||||
/* Determine the number of sectors needed by the root directory.
|
||||
* This is a constant value, independent of cluster size for FAT12/16
|
||||
*/
|
||||
|
||||
if (var->fv_fattype != 32)
|
||||
{
|
||||
/* Calculate the number of sectors reqired to contain the selected
|
||||
* number of root directory entries.
|
||||
*/
|
||||
|
||||
nrootdirsects =
|
||||
((fmt->ff_rootdirentries << DIR_SHIFT) + var->fv_sectorsize - 1) >> var->fv_sectshift;
|
||||
|
||||
/* The number of data sectors available (includes the fat itself)
|
||||
* This value is a constant for FAT12/16, but not FAT32 because the
|
||||
* size of the root directory cluster changes
|
||||
*/
|
||||
|
||||
fatconfig12.fc_navailsects =
|
||||
fatconfig16.fc_navailsects =
|
||||
var->fv_nsectors - nrootdirsects - fmt->ff_rsvdseccount;
|
||||
}
|
||||
|
||||
/* Select an initial and terminal clustersize to use in the search (if these
|
||||
* values were not provided by the caller)
|
||||
*/
|
||||
|
||||
mxclustshift = mkfatfs_clustersearchlimits(fmt, var);
|
||||
|
||||
do
|
||||
{
|
||||
fvdbg("Configuring with %d sectors/cluster...\n", 1 << fmt->ff_clustshift);
|
||||
|
||||
/* Check if FAT12 has not been excluded */
|
||||
|
||||
fatconfig12.fc_nfatsects = 0;
|
||||
fatconfig12.fc_nclusters = 0;
|
||||
\
|
||||
if (var->fv_fattype == 0 || var->fv_fattype == 12)
|
||||
{
|
||||
/* Try to configure a FAT12 filesystem with this cluster size */
|
||||
|
||||
if (mkfatfs_tryfat12(fmt, var, &fatconfig12) != 0)
|
||||
{
|
||||
{
|
||||
fvdbg("Cannot format FAT12 at %u sectors/cluster\n", 1 << fmt->ff_clustshift);
|
||||
fatconfig12.fc_nfatsects = 0;
|
||||
fatconfig12.fc_nclusters = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if FAT16 has not been excluded */
|
||||
|
||||
fatconfig16.fc_nfatsects = 0;
|
||||
fatconfig16.fc_nclusters = 0;
|
||||
|
||||
if (var->fv_fattype == 0 || var->fv_fattype == 16)
|
||||
{
|
||||
/* Try to configure a FAT16 filesystem with this cluster size */
|
||||
|
||||
if (mkfatfs_tryfat16(fmt, var, &fatconfig16) != 0)
|
||||
{
|
||||
{
|
||||
fvdbg("Cannot format FAT16 at %u sectors/cluster\n", 1 << fmt->ff_clustshift);
|
||||
fatconfig16.fc_nfatsects = 0;
|
||||
fatconfig16.fc_nclusters = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if FAT32 has not been excluded */
|
||||
|
||||
fatconfig32.fc_nfatsects = 0;
|
||||
fatconfig32.fc_nclusters = 0;
|
||||
|
||||
if (var->fv_fattype == 0 || var->fv_fattype == 32)
|
||||
{
|
||||
/* The number of data sectors available (includes the fat itself)
|
||||
* This value is a constant with respect to cluster sizefor FAT12/16, but not FAT32
|
||||
* because the size of the root directory cluster changes with cluster size.
|
||||
*/
|
||||
|
||||
fatconfig32.fc_navailsects = var->fv_nsectors - (1 << fmt->ff_clustshift) - fmt->ff_rsvdseccount;
|
||||
|
||||
/* Try to configure a FAT32 filesystem with this cluster size */
|
||||
|
||||
if (mkfatfs_tryfat32(fmt, var, &fatconfig32) != 0)
|
||||
{
|
||||
{
|
||||
fvdbg("Cannot format FAT32 at %u sectors/cluster\n", 1 << fmt->ff_clustshift);
|
||||
fatconfig32.fc_nfatsects = 0;
|
||||
fatconfig32.fc_nclusters = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If any FAT was configured at this sector/cluster setting, then break out now */
|
||||
|
||||
if (fatconfig12.fc_nclusters || fatconfig16.fc_nclusters)
|
||||
{
|
||||
/* If both FAT12 and FAT16 ar possible, select the one with the largest
|
||||
* number of clusters (unless one has already been selected)
|
||||
*/
|
||||
|
||||
if (!var->fv_fattype)
|
||||
{
|
||||
if (fatconfig16.fc_nclusters > fatconfig12.fc_nclusters)
|
||||
{
|
||||
var->fv_fattype = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
var->fv_fattype = 12;
|
||||
}
|
||||
}
|
||||
fdbg("Selected FAT%d\n", var->fv_fattype);
|
||||
|
||||
/* Then return the appropriate inforamation about the selected
|
||||
* file system.
|
||||
*/
|
||||
|
||||
if (var->fv_fattype == 12)
|
||||
{
|
||||
var->fv_nclusters = fatconfig12.fc_nclusters;
|
||||
var->fv_nfatsects = fatconfig12.fc_nfatsects;
|
||||
}
|
||||
else
|
||||
{
|
||||
var->fv_nclusters = fatconfig16.fc_nclusters;
|
||||
var->fv_nfatsects = fatconfig16.fc_nfatsects;
|
||||
}
|
||||
var->fv_nrootdirsects = nrootdirsects;
|
||||
return OK;
|
||||
}
|
||||
else if (fatconfig32.fc_nclusters)
|
||||
{
|
||||
/* Select FAT32 if we have not already done so */
|
||||
|
||||
var->fv_fattype = 32;
|
||||
fdbg("Selected FAT%d\n", var->fv_fattype);
|
||||
|
||||
var->fv_nclusters = fatconfig32.fc_nclusters;
|
||||
var->fv_nfatsects = fatconfig32.fc_nfatsects;
|
||||
var->fv_nrootdirsects = 1 << fmt->ff_clustshift;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Otherwise, bump up the sectors/cluster for the next time around the loop. */
|
||||
|
||||
fmt->ff_clustshift++;
|
||||
}
|
||||
while (fmt->ff_clustshift <= mxclustshift);
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -482,7 +482,7 @@ struct fat_mountpt_s
|
|||
size_t fs_fsinfo; /* MBR: Sector number of FSINFO sector */
|
||||
size_t fs_currentsector; /* The sector number buffered in fs_buffer */
|
||||
uint32 fs_nclusters; /* Maximum number of data clusters */
|
||||
uint32 fs_fatsize; /* MBR: Count of sectors occupied by one fat */
|
||||
uint32 fs_nfatsects; /* MBR: Count of sectors occupied by one fat */
|
||||
uint32 fs_fattotsec; /* MBR: Total count of sectors on the volume */
|
||||
uint32 fs_fsifreecount; /* FSI: Last free cluster count on volume */
|
||||
uint32 fs_fsinextfree; /* FSI: Cluster number of 1st free cluster */
|
||||
|
|
|
@ -284,7 +284,7 @@ static int fat_checkfsinfo(struct fat_mountpt_s *fs)
|
|||
static int fat_checkbootrecord(struct fat_mountpt_s *fs)
|
||||
{
|
||||
uint32 ndatasectors;
|
||||
uint32 fatsize;
|
||||
uint32 ntotalfatsects;
|
||||
uint16 rootdirsectors = 0;
|
||||
boolean notfat32 = FALSE;
|
||||
|
||||
|
@ -320,17 +320,17 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
|
|||
|
||||
/* Determine the number of sectors in a FAT. */
|
||||
|
||||
fs->fs_fatsize = MBR_GETFATSZ16(fs->fs_buffer); /* Should be zero */
|
||||
if (fs->fs_fatsize)
|
||||
fs->fs_nfatsects = MBR_GETFATSZ16(fs->fs_buffer); /* Should be zero */
|
||||
if (fs->fs_nfatsects)
|
||||
{
|
||||
notfat32 = TRUE; /* Must be zero for FAT32 */
|
||||
}
|
||||
else
|
||||
{
|
||||
fs->fs_fatsize = MBR_GETFATSZ32(fs->fs_buffer);
|
||||
fs->fs_nfatsects = MBR_GETFATSZ32(fs->fs_buffer);
|
||||
}
|
||||
|
||||
if (!fs->fs_fatsize || fs->fs_fatsize >= fs->fs_hwnsectors)
|
||||
if (!fs->fs_nfatsects || fs->fs_nfatsects >= fs->fs_hwnsectors)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -363,11 +363,11 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
|
|||
/* Get the number of FATs. This is probably two but could have other values */
|
||||
|
||||
fs->fs_fatnumfats = MBR_GETNUMFATS(fs->fs_buffer);
|
||||
fatsize = fs->fs_fatnumfats * fs->fs_fatsize;
|
||||
ntotalfatsects = fs->fs_fatnumfats * fs->fs_nfatsects;
|
||||
|
||||
/* Get the total number of data sectors */
|
||||
|
||||
ndatasectors = fs->fs_fattotsec - fs->fs_fatresvdseccount - fatsize - rootdirsectors;
|
||||
ndatasectors = fs->fs_fattotsec - fs->fs_fatresvdseccount - ntotalfatsects - rootdirsectors;
|
||||
if (ndatasectors > fs->fs_hwnsectors)
|
||||
{
|
||||
return -ENODEV;
|
||||
|
@ -415,10 +415,10 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
|
|||
}
|
||||
else
|
||||
{
|
||||
fs->fs_rootbase = fs->fs_fatbase + fatsize;
|
||||
fs->fs_rootbase = fs->fs_fatbase + ntotalfatsects;
|
||||
}
|
||||
|
||||
fs->fs_database = fs->fs_fatbase + fatsize + fs->fs_rootentcnt / DIRSEC_NDIRS(fs);
|
||||
fs->fs_database = fs->fs_fatbase + ntotalfatsects + fs->fs_rootentcnt / DIRSEC_NDIRS(fs);
|
||||
fs->fs_fsifreecount = 0xffffffff;
|
||||
|
||||
return OK;
|
||||
|
@ -708,7 +708,7 @@ int fat_mount(struct fat_mountpt_s *fs, boolean writeable)
|
|||
fdbg("\t data sector: %d\n", fs->fs_database);
|
||||
fdbg("\t FSINFO sector: %d\n", fs->fs_fsinfo);
|
||||
fdbg("\t Num FATs: %d\n", fs->fs_fatnumfats);
|
||||
fdbg("\t FAT size: %d\n", fs->fs_fatsize);
|
||||
fdbg("\t FAT sectors: %d\n", fs->fs_nfatsects);
|
||||
fdbg("\t sectors/cluster: %d\n", fs->fs_fatsecperclus);
|
||||
fdbg("\t max clusters: %d\n", fs->fs_nclusters);
|
||||
fdbg("\tFSI free count %d\n", fs->fs_fsifreecount);
|
||||
|
@ -2115,14 +2115,14 @@ int fat_fscacheflush(struct fat_mountpt_s *fs)
|
|||
|
||||
/* Does the sector lie in the FAT region? */
|
||||
|
||||
if (fs->fs_currentsector < fs->fs_fatbase + fs->fs_fatsize)
|
||||
if (fs->fs_currentsector < fs->fs_fatbase + fs->fs_nfatsects)
|
||||
{
|
||||
/* Yes, then make the change in the FAT copy as well */
|
||||
int i;
|
||||
|
||||
for (i = fs->fs_fatnumfats; i >= 2; i--)
|
||||
{
|
||||
fs->fs_currentsector += fs->fs_fatsize;
|
||||
fs->fs_currentsector += fs->fs_nfatsects;
|
||||
ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_currentsector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
|
@ -99,7 +99,7 @@ struct fat_var_s
|
|||
ubyte fv_jump[3]; /* 3-byte boot jump instruction */
|
||||
ubyte fv_sectshift; /* Log2 of fv_sectorsize */
|
||||
ubyte fv_nrootdirsects; /* Number of root directory sectors */
|
||||
ubyte fv_fatsize; /* FAT size: 0 (not determined), 12, 16, or 32 */
|
||||
ubyte fv_fattype; /* FAT size: 0 (not determined), 12, 16, or 32 */
|
||||
uint16 fv_bootcodesize; /* Size of array at fv_bootcode */
|
||||
uint32 fv_createtime; /* Creation time */
|
||||
uint32 fv_sectorsize; /* Size of one hardware sector */
|
||||
|
|
|
@ -133,7 +133,7 @@ static inline void mkfatfs_initmbr(FAR struct fat_format_s *fmt,
|
|||
|
||||
/* Most of the rest of the sector depends on the FAT size */
|
||||
|
||||
if (fmt->ff_fatsize != 32)
|
||||
if (fmt->ff_fattype != 32)
|
||||
{
|
||||
/* 2@22: FAT12/16: Must be 0, see BS32_FATSZ32 */
|
||||
|
||||
|
@ -156,11 +156,11 @@ static inline void mkfatfs_initmbr(FAR struct fat_format_s *fmt,
|
|||
|
||||
/* 8@54: "FAT12 ", "FAT16 ", or "FAT " */
|
||||
|
||||
if (fmt->ff_fatsize == 12)
|
||||
if (fmt->ff_fattype == 12)
|
||||
{
|
||||
memcpy(&var->fv_sect[BS16_FILESYSTYPE], "FAT12 ", 8);
|
||||
}
|
||||
else /* if (fmt->ff_fatsize == 16) */
|
||||
else /* if (fmt->ff_fattype == 16) */
|
||||
{
|
||||
memcpy(&var->fv_sect[BS16_FILESYSTYPE], "FAT16 ", 8);
|
||||
}
|
||||
|
@ -338,7 +338,7 @@ static inline int mkfatfs_writembr(FAR struct fat_format_s *fmt,
|
|||
|
||||
/* Write FAT32-specific sectors */
|
||||
|
||||
if (ret >= 0 && fmt->ff_fatsize == 32)
|
||||
if (ret >= 0 && fmt->ff_fattype == 32)
|
||||
{
|
||||
/* Write the backup master boot record */
|
||||
|
||||
|
@ -405,7 +405,7 @@ static inline int mkfatfs_writefat(FAR struct fat_format_s *fmt,
|
|||
if (sectno == 0)
|
||||
{
|
||||
memset(var->fv_sect, 0, var->fv_sectorsize);
|
||||
switch(fmt->ff_fatsize)
|
||||
switch(fmt->ff_fattype)
|
||||
{
|
||||
case 12:
|
||||
/* Mark the first two full FAT entries -- 24 bits, 3 bytes total */
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
#define MKFATFS_DEFAULT_BBCHECK FALSE /* FALSE: No bad block check */
|
||||
#define MKFATFS_DEFAULT_NFATS 2 /* 2: Default number of FATs */
|
||||
#define MKFATFS_DEFAULT_FATSIZE 0xff /* 0: Autoselect FAT size */
|
||||
#define MKFATFS_DEFAULT_FATTYPE 0xff /* 0: Autoselect FAT size */
|
||||
#define MKFATFS_DEFAULT_CLUSTSIZE 0 /* 0: Autoselect cluster size */
|
||||
#define MKFATFS_DEFAULT_VOLUMELABEL { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
|
||||
#define MKFATFS_DEFAULT_BKUPBOOT 0 /* 0: Determine sector number of the backup boot sector */
|
||||
|
@ -63,7 +63,7 @@
|
|||
{ \
|
||||
MKFATFS_DEFAULT_BBCHECK, \
|
||||
MKFATFS_DEFAULT_NFAT, \
|
||||
MKFATFS_DEFAULT_FATSIZE, \
|
||||
MKFATFS_DEFAULT_FATTYPE, \
|
||||
MKFATFS_DEFAULT_CLUSTSIZE, \
|
||||
MKFATFS_DEFAULT_VOLUMELABEL, \
|
||||
MKFATFS_DEFAULT_BKUPBOOT, \
|
||||
|
@ -85,7 +85,7 @@
|
|||
struct fat_format_s
|
||||
{
|
||||
ubyte ff_nfats; /* Number of FATs */
|
||||
ubyte ff_fatsize; /* FAT size: 0 (autoselect), 12, 16, or 32 */
|
||||
ubyte ff_fattype; /* FAT size: 0 (autoselect), 12, 16, or 32 */
|
||||
ubyte ff_clustshift; /* Log2 of sectors per cluster: 0-5, 0xff (autoselect) */
|
||||
ubyte ff_volumelabel[11]; /* Volume label */
|
||||
uint16 ff_backupboot; /* Sector number of the backup boot sector (0=use default)*/
|
||||
|
|
Loading…
Reference in a new issue