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:
parent
4018cc186c
commit
fc55f25fff
@ -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,
|
||||
|
@ -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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user