You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2021/05/21 12:56:00 UTC

[incubator-nuttx] branch master updated: Fix calculation of free clusters at mounting a fat partition

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new fc55f25  Fix calculation of free clusters at mounting a fat partition
fc55f25 is described below

commit fc55f25fff646c1cd40b84b8301eb1cd43a89904
Author: GAEHWILER Reto <re...@hexagon.com>
AuthorDate: Fri May 21 09:00:22 2021 +0200

    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
---
 fs/fat/fs_fat32.h     |  1 +
 fs/fat/fs_fat32util.c | 63 +++++++++++++++++++++++++++++++++++----------------
 2 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/fs/fat/fs_fat32.h b/fs/fat/fs_fat32.h
index 5858aed..70e958e 100644
--- a/fs/fat/fs_fat32.h
+++ b/fs/fat/fs_fat32.h
@@ -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,
diff --git a/fs/fat/fs_fat32util.c b/fs/fat/fs_fat32util.c
index 8bd967c..0fdfeaa 100644
--- a/fs/fat/fs_fat32util.c
+++ b/fs/fat/fs_fat32util.c
@@ -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,7 +2119,6 @@ int fat_nfreeclusters(struct fat_mountpt_s *fs, off_t *pfreeclusters)
       fs->fs_fsidirty = true;
     }
 
-  *pfreeclusters = nfreeclusters;
   return OK;
 }
 
@@ -2134,6 +2126,37 @@ int fat_nfreeclusters(struct fat_mountpt_s *fs, off_t *pfreeclusters)
  * 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
+ *
+ * Description:
  *   Given the file position, set the correct current sector to access.
  *
  ****************************************************************************/