[PATCH] erofs-utils: lib: fix data race on __erofs_is_progressmsg
Utkal Singh
singhutkal015 at gmail.com
Mon Mar 30 00:23:06 AEDT 2026
erofs_msg() and erofs_update_progressinfo() both access the static
variable __erofs_is_progressmsg without any synchronization. Since
mkfs already runs multiple worker threads via erofs_alloc_workqueue()
(e.g. in z_erofs_mt_compress()), and those threads call erofs_err()
and erofs_info() which invoke erofs_msg(), this is a real data race
on the current codebase.
Fix this by protecting all accesses to __erofs_is_progressmsg with a
static pthread_mutex_t. The mutex is statically initialized so no
init/destroy changes are needed. Also restructure the
erofs_update_progressinfo() I/O path to eliminate the early return
inside the lock, ensuring pthread_mutex_unlock() is always reached.
Signed-off-by: Utkal Singh <singhutkal015 at gmail.com>
---
lib/config.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/lib/config.c b/lib/config.c
index ab7eb01..7f58159 100644
--- a/lib/config.c
+++ b/lib/config.c
@@ -100,6 +100,7 @@ int erofs_selabel_open(const char *file_contexts)
#endif
static bool __erofs_is_progressmsg;
+static pthread_mutex_t erofs_msg_lock = PTHREAD_MUTEX_INITIALIZER;
char *erofs_trim_for_progressinfo(const char *str, int placeholder)
{
@@ -141,6 +142,7 @@ void erofs_msg(int dbglv, const char *fmt, ...)
va_list ap;
FILE *f = dbglv >= EROFS_ERR ? stderr : stdout;
+ pthread_mutex_lock(&erofs_msg_lock);
if (__erofs_is_progressmsg) {
fputc('\n', stdout);
__erofs_is_progressmsg = false;
@@ -148,6 +150,7 @@ void erofs_msg(int dbglv, const char *fmt, ...)
va_start(ap, fmt);
vfprintf(f, fmt, ap);
va_end(ap);
+ pthread_mutex_unlock(&erofs_msg_lock);
}
void erofs_update_progressinfo(const char *fmt, ...)
@@ -162,14 +165,16 @@ void erofs_update_progressinfo(const char *fmt, ...)
vsprintf(msg, fmt, ap);
va_end(ap);
+ pthread_mutex_lock(&erofs_msg_lock);
if (erofs_stdout_tty) {
printf("\r\033[K%s", msg);
__erofs_is_progressmsg = true;
fflush(stdout);
- return;
+ } else {
+ fputs(msg, stdout);
+ fputc('\n', stdout);
}
- fputs(msg, stdout);
- fputc('\n', stdout);
+ pthread_mutex_unlock(&erofs_msg_lock);
}
unsigned int erofs_get_available_processors(void)
--
2.43.0
More information about the Linux-erofs
mailing list