From 26b7de0f3496a0300a817788d127e21ddcd82189 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Thu, 21 Dec 2023 11:51:13 +0200 Subject: [PATCH] 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 --- 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;