9
0
Fork 0

Fix a stray write into the FAT

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3958 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-09-16 14:07:17 +00:00
parent bf6eea145f
commit f23910b3c4
4 changed files with 27 additions and 17 deletions

View File

@ -2076,7 +2076,7 @@
* sched/clock_gettime.c: Correct an error in the tv_nsec calculation
that happens only config CONFIG_RTC is enabled.
* arch/arm/src/stm32/stm32_i2c.c: Correct some bugs related to waiting
to the I2C STOP condition to be cleared.
for the I2C STOP condition to be cleared.
6.10 2011-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
@ -2089,3 +2089,7 @@
* fs/fat/fs_fat32.c: Fix a critical bug in the write logic: It a tiny write
cross a sector boundary, then two sector writes will occur. The first part
in the first sector may be written to the wrong sector number.
* fs/fat/fs_fat32util.c: Fix a stray write into the FAT (always sector 964 on
FAT32). This bug will cause some lost chains. I'm sure this bug could
corrupt files but at present, the only thing I have seen is that before
fixing this bug, the Windows chkdsk utility would report these lost chains.

View File

@ -728,8 +728,8 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
nsectors = ff->ff_sectorsincluster;
}
/* We are not sure of the state of the file buffer so
* the safest thing to do is write back any dirty, cached sector
/* We are not sure of the state of the sector cache so the
* safest thing to do is write back any dirty, cached sector
* and invalidate the current cache content.
*/

View File

@ -2505,7 +2505,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
for (i = fs->fs_fatsecperclus; i; i--)
{
ret = fat_hwwrite(fs, fs->fs_buffer, sector, 1);
if ( ret < 0)
if (ret < 0)
{
return ret;
}

View File

@ -882,6 +882,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t clusterno, off_t nextclust
value = (uint8_t)nextcluster;
}
fs->fs_buffer[fatindex] = value;
/* With FAT12, the second byte of the cluster number may lie in
@ -904,6 +905,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t clusterno, off_t nextclust
if (fat_fscacheread(fs, fatsector) < 0)
{
/* Read error */
break;
}
}
@ -924,6 +926,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t clusterno, off_t nextclust
value = (fs->fs_buffer[fatindex] & 0xf0) | ((nextcluster >> 8) & 0x0f);
}
fs->fs_buffer[fatindex] = value;
}
break;
@ -937,6 +940,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t clusterno, off_t nextclust
if (fat_fscacheread(fs, fatsector) < 0)
{
/* Read error */
break;
}
FAT_PUTFAT16(fs->fs_buffer, fatindex, nextcluster & 0xffff);
@ -952,6 +956,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t clusterno, off_t nextclust
if (fat_fscacheread(fs, fatsector) < 0)
{
/* Read error */
break;
}
FAT_PUTFAT32(fs->fs_buffer, fatindex, nextcluster & 0x0fffffff);
@ -964,7 +969,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t clusterno, off_t nextclust
/* Mark the modified sector as "dirty" and return success */
fs->fs_dirty = 1;
fs->fs_dirty = true;
return OK;
}
@ -1067,8 +1072,8 @@ int32_t fat_extendchain(struct fat_mountpt_s *fs, uint32_t cluster)
}
else if (startsector < 2)
{
/* Oops.. this cluster does not exist. */
return 0;
}
else if (startsector < fs->fs_nclusters)
@ -1351,37 +1356,38 @@ int fat_fscacheflush(struct fat_mountpt_s *fs)
*/
if (fs->fs_dirty)
{
{
/* Write the dirty sector */
ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_currentsector, 1);
if (ret < 0)
{
{
return ret;
}
}
/* Does the sector lie in the FAT region? */
if (fs->fs_currentsector < fs->fs_fatbase + fs->fs_nfatsects)
{
if (fs->fs_currentsector >= fs->fs_fatbase &&
fs->fs_currentsector < fs->fs_fatbase + fs->fs_nfatsects)
{
/* Yes, then make the change in the FAT copy as well */
int i;
for (i = fs->fs_fatnumfats; i >= 2; i--)
{
{
fs->fs_currentsector += fs->fs_nfatsects;
ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_currentsector, 1);
if (ret < 0)
{
{
return ret;
}
}
}
}
}
}
/* No longer dirty */
fs->fs_dirty = false;
}
}
return OK;
}