Fix concurrency bugs in FAT_getAttr/FAT_setAttr. (#13)

A relatively rare concurrency bug existed in these methods due to them not
correctly holding the partition lock during calls to
_FAT_directory_entryFromPath. That method can trigger reads to the partition.
Due to the lock not being held, another thread could still trigger a concurrent
read, potentially corrupting the cache. The fix is simply to ensure the lock is
held around the calls.
This commit is contained in:
Alex "Chadderz" Chadwick 2018-04-20 12:23:50 +01:00 committed by Dave Murphy
parent e7b04a73a0
commit a711f2bef2

View File

@ -46,6 +46,7 @@
#include "lock.h" #include "lock.h"
bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) { bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) {
bool r;
PARTITION *partition = _FAT_partition_getPartitionFromPath(path); PARTITION *partition = _FAT_partition_getPartitionFromPath(path);
// Check Partition // Check Partition
@ -61,8 +62,11 @@ bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) {
} }
// Search for the file on the disc // Search for the file on the disc
return _FAT_directory_entryFromPath (partition, dirEntry, path, NULL); _FAT_lock(&partition->lock);
r = _FAT_directory_entryFromPath (partition, dirEntry, path, NULL);
_FAT_unlock(&partition->lock);
return r;
} }
int FAT_getAttr(const char *file) { int FAT_getAttr(const char *file) {
@ -92,16 +96,17 @@ int FAT_setAttr(const char *file, uint8_t attr) {
if (strchr (file, ':') != NULL) if (strchr (file, ':') != NULL)
return -1; return -1;
// Get DIR_ENTRY
if( !_FAT_directory_entryFromPath (partition, &dirEntry, file, NULL) )
return -1;
// Get Entry-End
entryEnd = dirEntry.dataEnd;
// Lock Partition // Lock Partition
_FAT_lock(&partition->lock); _FAT_lock(&partition->lock);
// Get DIR_ENTRY
if( !_FAT_directory_entryFromPath (partition, &dirEntry, file, NULL) ) {
_FAT_unlock(&partition->lock); // Unlock Partition
return -1;
}
// Get Entry-End
entryEnd = dirEntry.dataEnd;
// Write Data // Write Data
_FAT_cache_writePartialSector ( _FAT_cache_writePartialSector (