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

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


The following commit(s) were added to refs/heads/master by this push:
     new 26b7de0f34 fs/fat: Fix number of data clusters usable for fat driver
26b7de0f34 is described below

commit 26b7de0f3496a0300a817788d127e21ddcd82189
Author: Jukka Laitinen <juk...@ssrc.tii.ae>
AuthorDate: Thu Dec 21 11:51:13 2023 +0200

    fs/fat: Fix number of data clusters usable for fat driver
    
    Fix the issue where fat driver is not using the last two clusters in
    the file system.
    
    The fat parameter fs->fs_nclusters is the maximum number of data clusters;
    this doesn't include the two in the beginning. Many checks in the fat driver
    treat the fs->fs_nclusters-1 as being the last accessible cluster, which is 
not
    right, the last accessible one is actually this number + 2 when the cluster
    count includes the two first ones.
    
    Normally this is not an issue when writes are being done through the same
    driver, the last two clusters are just never used. But if the filesystem is
    modified by external driver, for example with a populated fat created with 
PC,
    or modifying the FS via USB-MSC, this leads to the fat driver not being 
able to
    read anything that uses the last two clusters.
    
    Signed-off-by: Jukka Laitinen <juk...@ssrc.tii.ae>
---
 fs/fat/fs_fat32.c     |  6 +++---
 fs/fat/fs_fat32util.c | 24 ++++++++++++------------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/fs/fat/fs_fat32.c b/fs/fat/fs_fat32.c
index f5c53715c9..1edb7167ed 100644
--- a/fs/fat/fs_fat32.c
+++ b/fs/fat/fs_fat32.c
@@ -583,7 +583,7 @@ static ssize_t fat_read(FAR struct file *filep, FAR char 
*buffer,
           /* Find the next cluster in the FAT. */
 
           cluster = fat_getcluster(fs, ff->ff_currentcluster);
-          if (cluster < 2 || cluster >= fs->fs_nclusters)
+          if (cluster < 2 || cluster >= fs->fs_nclusters + 2)
             {
               ret = -EINVAL; /* Not the right error */
               goto errout_with_lock;
@@ -835,7 +835,7 @@ static ssize_t fat_write(FAR struct file *filep, FAR const 
char *buffer,
               ret = cluster;
               goto errout_with_lock;
             }
-          else if (cluster < 2 || cluster >= fs->fs_nclusters)
+          else if (cluster < 2 || cluster >= fs->fs_nclusters + 2)
             {
               ret = -ENOSPC;
               goto errout_with_lock;
@@ -1213,7 +1213,7 @@ static off_t fat_seek(FAR struct file *filep, off_t 
offset, int whence)
               break;
             }
 
-          if (cluster >= fs->fs_nclusters)
+          if (cluster >= fs->fs_nclusters + 2)
             {
               ret = -ENOSPC;
               goto errout_with_lock;
diff --git a/fs/fat/fs_fat32util.c b/fs/fat/fs_fat32util.c
index a4a01d2f79..a1b8c2d7fb 100644
--- a/fs/fat/fs_fat32util.c
+++ b/fs/fat/fs_fat32util.c
@@ -782,7 +782,7 @@ int fat_hwwrite(struct fat_mountpt_s *fs, uint8_t *buffer, 
off_t sector,
 off_t fat_cluster2sector(FAR struct fat_mountpt_s *fs,  uint32_t cluster)
 {
   cluster -= 2;
-  if (cluster >= fs->fs_nclusters - 2)
+  if (cluster >= fs->fs_nclusters)
     {
       return -EINVAL;
     }
@@ -805,7 +805,7 @@ off_t fat_getcluster(struct fat_mountpt_s *fs, uint32_t 
clusterno)
 {
   /* Verify that the cluster number is within range */
 
-  if (clusterno >= 2 && clusterno < fs->fs_nclusters)
+  if (clusterno >= 2 && clusterno < fs->fs_nclusters + 2)
     {
       /* Okay.. Read the next cluster from the FAT.  The way we will do
        * this depends on the type of FAT filesystem we are dealing with.
@@ -945,7 +945,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t 
clusterno,
    * cluster.
    */
 
-  if (clusterno == 0 || (clusterno >= 2 && clusterno < fs->fs_nclusters))
+  if (clusterno == 0 || (clusterno >= 2 && clusterno < fs->fs_nclusters + 2))
     {
       /* Okay.. Write the next cluster into the FAT.  The way we will do
        * this depends on the type of FAT filesystem we are dealing with.
@@ -1113,7 +1113,7 @@ int fat_removechain(struct fat_mountpt_s *fs, uint32_t 
cluster)
 
   /* Loop while there are clusters in the chain */
 
-  while (cluster >= 2 && cluster < fs->fs_nclusters)
+  while (cluster >= 2 && cluster < fs->fs_nclusters + 2)
     {
       /* Get the next cluster after the current one */
 
@@ -1177,7 +1177,7 @@ int32_t fat_extendchain(struct fat_mountpt_s *fs, 
uint32_t cluster)
        */
 
       startcluster = fs->fs_fsinextfree;
-      if (startcluster == 0 || startcluster >= fs->fs_nclusters)
+      if (startcluster == 0 || startcluster >= fs->fs_nclusters + 2)
         {
           /* But it is bad.. we have to start at the beginning */
 
@@ -1203,7 +1203,7 @@ int32_t fat_extendchain(struct fat_mountpt_s *fs, 
uint32_t cluster)
 
           return 0;
         }
-      else if (startsector < fs->fs_nclusters)
+      else if (startsector < fs->fs_nclusters + 2)
         {
           /* It is already followed by next cluster */
 
@@ -1226,7 +1226,7 @@ int32_t fat_extendchain(struct fat_mountpt_s *fs, 
uint32_t cluster)
       /* Examine the next cluster in the FAT */
 
       newcluster++;
-      if (newcluster >= fs->fs_nclusters)
+      if (newcluster >= fs->fs_nclusters + 2)
         {
           /* If we hit the end of the available clusters, then
            * wrap back to the beginning because we might have
@@ -1385,7 +1385,7 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct 
fs_fatdir_s *dir)
 
               /* Check if a valid cluster was obtained. */
 
-              if (cluster < 2 || cluster >= fs->fs_nclusters)
+              if (cluster < 2 || cluster >= fs->fs_nclusters + 2)
                 {
                   /* No, we have probably reached the end of the cluster
                    * list.
@@ -1529,7 +1529,7 @@ int fat_dirshrink(struct fat_mountpt_s *fs, FAR uint8_t 
*direntry,
   clustersize = fs->fs_fatsecperclus * fs->fs_hwsectorsize;
   remaining   = length;
 
-  while (cluster >= 2 && cluster < fs->fs_nclusters)
+  while (cluster >= 2 && cluster < fs->fs_nclusters + 2)
     {
       /* Will there be data in the next cluster after the shrinkage? */
 
@@ -1654,7 +1654,7 @@ int fat_dirextend(FAR struct fat_mountpt_s *fs, FAR 
struct fat_file_s *ff,
             {
               return (int)cluster;
             }
-          else if (cluster < 2 || cluster >= fs->fs_nclusters)
+          else if (cluster < 2 || cluster >= fs->fs_nclusters + 2)
             {
               return -ENOSPC;
             }
@@ -2033,7 +2033,7 @@ int fat_computefreeclusters(struct fat_mountpt_s *fs)
 
       /* Examine every cluster in the fat */
 
-      for (sector = 2; sector < fs->fs_nclusters; sector++)
+      for (sector = 2; sector < fs->fs_nclusters + 2; sector++)
         {
           /* If the cluster is unassigned, then increment the count of free
            * clusters
@@ -2127,7 +2127,7 @@ int fat_nfreeclusters(struct fat_mountpt_s *fs, 
fsblkcnt_t *pfreeclusters)
    * value.
    */
 
-  if (fs->fs_fsifreecount <= fs->fs_nclusters - 2)
+  if (fs->fs_fsifreecount <= fs->fs_nclusters)
     {
       *pfreeclusters = fs->fs_fsifreecount;
       return OK;

Reply via email to