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 <[email protected]>
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 <[email protected]>
---
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;