R0.15 patch 2

December 4, 2022

There is a potential issue when work FatFs concurrency with FF_FS_REENTRANT, FF_VOLUMES >= 2
and FF_FS_LOCK > 0.

This problem was reported via the user forum.
This commit is contained in:
Christopher Williams
2022-12-05 17:41:11 -07:00
parent 4f08f1a02d
commit 010b83715f
+6 -4
View File
@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------/ /*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem Module R0.15 w/patch1 / / FatFs - Generic FAT Filesystem Module R0.15 w/patch2 /
/-----------------------------------------------------------------------------/ /-----------------------------------------------------------------------------/
/ /
/ Copyright (C) 2022, ChaN, all right reserved. / Copyright (C) 2022, ChaN, all right reserved.
@@ -468,10 +468,11 @@ static WORD Fsid; /* Filesystem mount ID */
static BYTE CurrVol; /* Current drive set by f_chdrive() */ static BYTE CurrVol; /* Current drive set by f_chdrive() */
#endif #endif
#if FF_FS_LOCK != 0 #if FF_FS_LOCK
static FILESEM Files[FF_FS_LOCK]; /* Open object lock semaphores */ static FILESEM Files[FF_FS_LOCK]; /* Open object lock semaphores */
#if FF_FS_REENTRANT #if FF_FS_REENTRANT
static BYTE SysLock; /* System lock flag (0:no mutex, 1:unlocked, 2:locked) */ static volatile BYTE SysLock; /* System lock flag to protect Files[] (0:no mutex, 1:unlocked, 2:locked) */
static volatile BYTE SysLockVolume; /* Volume id who is locking Files[] */
#endif #endif
#endif #endif
@@ -905,6 +906,7 @@ static int lock_volume ( /* 1:Ok, 0:timeout */
if (rv && syslock) { /* System lock reqiered? */ if (rv && syslock) { /* System lock reqiered? */
rv = ff_mutex_take(FF_VOLUMES); /* Lock the system */ rv = ff_mutex_take(FF_VOLUMES); /* Lock the system */
if (rv) { if (rv) {
SysLockVolume = fs->ldrv;
SysLock = 2; /* System lock succeeded */ SysLock = 2; /* System lock succeeded */
} else { } else {
ff_mutex_give(fs->ldrv); /* Failed system lock */ ff_mutex_give(fs->ldrv); /* Failed system lock */
@@ -924,7 +926,7 @@ static void unlock_volume (
{ {
if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) { if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) {
#if FF_FS_LOCK #if FF_FS_LOCK
if (SysLock == 2) { /* Is the system locked? */ if (SysLock == 2 && SysLockVolume == fs->ldrv) { /* Unlock system if it has been locked by this task */
SysLock = 1; SysLock = 1;
ff_mutex_give(FF_VOLUMES); ff_mutex_give(FF_VOLUMES);
} }