diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-08-09 15:55:42 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-08-09 15:55:42 +0000 |
commit | 739c683a81fd750eced6aec2ea30cc1c68701a68 (patch) | |
tree | b22e15749465387681ba2d7694207260b93fc760 /nuttx/fs | |
parent | cd84f3dbe66739cf803208b163bda227e2fcff64 (diff) | |
download | px4-nuttx-739c683a81fd750eced6aec2ea30cc1c68701a68.tar.gz px4-nuttx-739c683a81fd750eced6aec2ea30cc1c68701a68.tar.bz2 px4-nuttx-739c683a81fd750eced6aec2ea30cc1c68701a68.zip |
Add FAT size calculation
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@803 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs')
-rw-r--r-- | nuttx/fs/fat/fs_configfat.c | 185 | ||||
-rw-r--r-- | nuttx/fs/fat/fs_mkfatfs.h | 3 | ||||
-rw-r--r-- | nuttx/fs/fat/fs_writefat.c | 4 |
3 files changed, 188 insertions, 4 deletions
diff --git a/nuttx/fs/fat/fs_configfat.c b/nuttx/fs/fat/fs_configfat.c index 2974e9f02..13feeaf91 100644 --- a/nuttx/fs/fat/fs_configfat.c +++ b/nuttx/fs/fat/fs_configfat.c @@ -56,15 +56,198 @@ ****************************************************************************/ /**************************************************************************** - * Name: + * Name: mkfatfs_nfatsect12 * * Description: + * Calculate the number of sectors need for the fat in a FAT12 file system. * * Input: + * fmt - Caller specified format parameters + * var - Other format parameters that are not caller specifiable. (Most + * set by mkfatfs_configfatfs()). + * navailsects - The number of sectors available for both FAT and data. + * This is a precalculated value equal to the total number of sectors + * minus the number of root directory sectors and minus the number of + * reserved sectors. * * Return: + * 0: That calculation would have overflowed + * >0: The total size of the FAT in sectors. * ****************************************************************************/ +static inline uint32 mkfatfs_nfatsect12(FAR struct fat_format_s *fmt, + FAR struct fat_var_s *var, + uint32 navailsects) +{ + uint32 denom ; + uint32 numer; + + /* For FAT12, the cluster number is held in a 12-bit number or 1.5 bytes per + * cluster reference. So each FAT sector will hold sectorsize/1.5 cluster + * 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) + * + * where: + * + * ndataclust = ndatasect / clustsize + * nvailsects = nfatsects + ndatasect + * + * The solution to this set of linear equations is: + * + * nfatsects = nfats * (3 * navailsects + 6 * clustersize) / + * (3 * nfats + 2 * sectorsize * clustersize) + * + * The numerator would overflow uint32 if: + * + * 3 * navailsects + 6 * clustersize > 0xffffffff + * + * Or + * + * navailsects > 0x55555555 - 2 * clustersize + */ + + if (navailsects <= (0x55555555 - (1 << (fmt->ff_clustshift + 1)))) + { + denom = (fmt->ff_nfats << 1) + fmt->ff_nfats + + (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; + } + else + { + return 0; + } +} + +/**************************************************************************** + * Name: mkfatfs_nfatsect16 + * + * Description: + * Calculate the number of sectors need for the fat in a FAT16 file system. + * + * Input: + * fmt - Caller specified format parameters + * var - Other format parameters that are not caller specifiable. (Most + * set by mkfatfs_configfatfs()). + * navailsects - The number of sectors available for both FAT and data. + * This is a precalculated value equal to the total number of sectors + * minus the number of root directory sectors and minus the number of + * reserved sectors. + * + * Return: + * The total size of the FAT in sectors. + * + ****************************************************************************/ +static inline uint32 mkfatfs_nfatsect16(FAR struct fat_format_s *fmt, + FAR struct fat_var_s *var, + uint32 navailsects) +{ + uint32 denom; + uint32 numer; + + /* For FAT16, the cluster number is held in a 16-bit number or 2 bytes per + * cluster reference. So each FAT sector will hold sectorsize/2 cluster + * 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) + * + * where: + * + * ndataclust = ndatasect / clustsize + * nvailsects = nfatsects + ndatasect + * + * The solution to this set of linear equations is: + * + * nfatsects = nfats * (navailsects + 2 * clustersize) / + * (nfats + sectorsize * clustersize / 2) + * + * Overflow in the calculation of the numerator could occur if: + * + * navailsects > 0xffffffff - 2 * clustersize + */ + + if (fmt->ff_clustshift == 0) + { + denom = fmt->ff_nfats + (var->fv_sectorsize >> 1); + numer = navailsects + 2; + } + else + { + 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; +} + +/**************************************************************************** + * Name: mkfatfs_nfatsect32 + * + * Description: + * Calculate the number of sectors need for the fat in a FAT32 file system. + * + * Input: + * fmt - Caller specified format parameters + * var - Other format parameters that are not caller specifiable. (Most + * set by mkfatfs_configfatfs()). + * navailsects - The number of sectors available for both FAT and data. + * This is a precalculated value equal to the total number of sectors + * minus the number of root directory sectors and minus the number of + * reserved sectors. + * + * Return: + * The total size of the FAT in sectors. + * + ****************************************************************************/ +static inline uint32 mkfatfs_nfatsect32(FAR struct fat_format_s *fmt, + FAR struct fat_var_s *var, + uint32 navailsects) +{ + uint32 denom; + uint32 numer; + + /* For FAT32, the cluster number is held in a 32-bit number or 4 bytes per + * cluster reference. So each FAT sector will hold sectorsize/4 cluster + * 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) + * + * where: + * + * ndataclust = ndatasect / clustsize + * nvailsects = nfatsects + ndatasect + * + * The solution to this set of linear equations is: + * + * nfatsects = nfats * (navailsects + 3 * clustersize) / + * (nfats + sectorsize * clustersize / 4) + * + * Overflow in the calculation of the numerator could occur if: + * + * navailsects > 0xffffffff - 3 * clustersize + */ + + if (fmt->ff_clustshift == 0) + { + denom = fmt->ff_nfats + (var->fv_sectorsize >> 2); + numer = navailsects + 3; + } + else if (fmt->ff_clustshift == 1) + { + denom = fmt->ff_nfats + (var->fv_sectorsize >> 1); + numer = navailsects + 6; + } + else + { + 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; +} /**************************************************************************** * Global Functions diff --git a/nuttx/fs/fat/fs_mkfatfs.h b/nuttx/fs/fat/fs_mkfatfs.h index c8f22d815..b14916756 100644 --- a/nuttx/fs/fat/fs_mkfatfs.h +++ b/nuttx/fs/fat/fs_mkfatfs.h @@ -99,12 +99,13 @@ 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 */ uint16 fv_bootcodesize; /* Size of array at fv_bootcode */ uint32 fv_createtime; /* Creation time */ uint32 fv_sectorsize; /* Size of one hardware sector */ uint32 fv_nsectors; /* Number of sectors */ uint32 fv_nfatsects; /* Number of sectors in each FAT */ - uint32 fv_clustcount; /* Number of clusters */ + uint32 fv_nclusters; /* Number of clusters */ ubyte *fv_sect; /* Allocated working sector buffer */ const ubyte *fv_bootcode; /* Points to boot code to put into MBR */ }; diff --git a/nuttx/fs/fat/fs_writefat.c b/nuttx/fs/fat/fs_writefat.c index 287e4f0f8..2270869ff 100644 --- a/nuttx/fs/fat/fs_writefat.c +++ b/nuttx/fs/fat/fs_writefat.c @@ -88,7 +88,7 @@ static inline void mkfatfs_initmbr(FAR struct fat_format_s *fmt, /* 1@13: Sectors per allocation unit: 2**n, n=0..7 */ - MBR_PUTSECPERCLUS(var->fv_sect, fmt->ff_clustsize); + MBR_PUTSECPERCLUS(var->fv_sect, (1 << fmt->ff_clustshift)); /* 2@14: Reserved sector count: Usually 32 */ @@ -250,7 +250,7 @@ static inline void mkfatfs_initfsinfo(FAR struct fat_format_s *fmt, /* 4@488: Last free cluster count on volume */ - FSI_PUTFREECOUNT(var->fv_sect, var->fv_clustcount - 1); + FSI_PUTFREECOUNT(var->fv_sect, var->fv_nclusters - 1); /* 4@492: Cluster number of 1st free cluster */ |