Fix calculation of free clusters at mounting a fat partition

Previously the value of the FSInfo section was taken as granted.
As described in the white paper of FAT [1] this value is unreliable
and has to be computed at mount time.

    [1] https://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf
This commit is contained in:
GAEHWILER Reto 2021-05-21 09:00:22 +02:00 committed by Alan Carvalho de Assis
parent 4018cc186c
commit fc55f25fff
2 changed files with 44 additions and 20 deletions

View File

@ -1082,6 +1082,7 @@ EXTERN int fat_ffcacheinvalidate(struct fat_mountpt_s *fs,
/* FSINFO sector support */
EXTERN int fat_updatefsinfo(struct fat_mountpt_s *fs);
EXTERN int fat_computefreeclusters(struct fat_mountpt_s *fs);
EXTERN int fat_nfreeclusters(struct fat_mountpt_s *fs,
off_t *pfreeclusters);
EXTERN int fat_currentsector(struct fat_mountpt_s *fs,

View File

@ -626,7 +626,7 @@ int fat_mount(struct fat_mountpt_s *fs, bool writeable)
if (fs->fs_type == FSTYPE_FAT32)
{
ret = fat_checkfsinfo(fs);
ret = fat_computefreeclusters(fs);
if (ret != OK)
{
goto errout_with_buffer;
@ -1142,7 +1142,7 @@ int fat_removechain(struct fat_mountpt_s *fs, uint32_t cluster)
if (fs->fs_fsifreecount != 0xffffffff)
{
fs->fs_fsifreecount++;
fs->fs_fsidirty = 1;
fs->fs_fsidirty = true;
}
/* Then set up to remove the next cluster */
@ -1308,7 +1308,7 @@ int32_t fat_extendchain(struct fat_mountpt_s *fs, uint32_t cluster)
if (fs->fs_fsifreecount != 0xffffffff)
{
fs->fs_fsifreecount--;
fs->fs_fsidirty = 1;
fs->fs_fsidirty = true;
}
/* Return then number of the new cluster that was added to the chain */
@ -2019,30 +2019,23 @@ int fat_updatefsinfo(struct fat_mountpt_s *fs)
}
/****************************************************************************
* Name: fat_nfreeclusters
* Name: fat_computefreeclusters
*
* Description:
* Get the number of free clusters
* Compute the number of free clusters from scratch
*
****************************************************************************/
int fat_nfreeclusters(struct fat_mountpt_s *fs, off_t *pfreeclusters)
int fat_computefreeclusters(struct fat_mountpt_s *fs)
{
uint32_t nfreeclusters;
/* If number of the first free cluster is valid, then just return that
* value.
*/
if (fs->fs_fsifreecount <= fs->fs_nclusters - 2)
if (fat_checkfsinfo(fs) != OK)
{
*pfreeclusters = fs->fs_fsifreecount;
return OK;
return -ENODEV;
}
/* Otherwise, we will have to count the number of free clusters */
/* We have to count the number of free clusters */
nfreeclusters = 0;
uint32_t nfreeclusters = 0;
if (fs->fs_type == FSTYPE_FAT12)
{
off_t sector;
@ -2052,7 +2045,7 @@ int fat_nfreeclusters(struct fat_mountpt_s *fs, off_t *pfreeclusters)
for (sector = 2; sector < fs->fs_nclusters; sector++)
{
/* If the cluster is unassigned, then increment the count of free
* clusters.
* clusters
*/
if ((uint16_t)fat_getcluster(fs, sector) == 0)
@ -2076,7 +2069,7 @@ int fat_nfreeclusters(struct fat_mountpt_s *fs, off_t *pfreeclusters)
for (cluster = fs->fs_nclusters; cluster > 0; cluster--)
{
/* If we are starting a new sector, then read the new sector in
* fs_buffer.
* fs_buffer
*/
if (offset >= fs->fs_hwsectorsize)
@ -2126,10 +2119,40 @@ int fat_nfreeclusters(struct fat_mountpt_s *fs, off_t *pfreeclusters)
fs->fs_fsidirty = true;
}
*pfreeclusters = nfreeclusters;
return OK;
}
/****************************************************************************
* Name: fat_nfreeclusters
*
* Description:
* Get the number of free clusters
*
****************************************************************************/
int fat_nfreeclusters(struct fat_mountpt_s *fs, off_t *pfreeclusters)
{
/* If number of the first free cluster is valid, then just return that
* value.
*/
if (fs->fs_fsifreecount <= fs->fs_nclusters - 2)
{
*pfreeclusters = fs->fs_fsifreecount;
return OK;
}
/* Otherwise, we will have to compute the number of free clusters */
int ret = fat_computefreeclusters(fs);
if (ret == OK)
{
*pfreeclusters = fs->fs_fsifreecount;
}
return ret;
}
/****************************************************************************
* Name: fat_nfreeclusters
*