[PATCH] erofs-utils: lib/diskbuf: replace bool locked with a real mutex for MT

Utkal Singh <[email protected]>
Newsgroups org.ozlabs.lists.linux-erofs
Message-ID <[email protected]>
erofs_diskbufstrm used a plain boolean 'locked' to track stream
reservation state, with an explicit comment marking it as a
placeholder: 'need a real lock for MT'.  A boolean provides no
atomicity or memory-ordering guarantees under concurrent access.

Replace 'bool locked' with 'erofs_mutex_t lock' using the existing
portable wrapper in include/erofs/lock.h.  Acquire the mutex in
erofs_diskbuf_reserve() and release it in erofs_diskbuf_commit(),
serialising concurrent access to each stream's tailoffset field.
Initialisation and destruction are wired into erofs_diskbuf_init()
and erofs_diskbuf_exit() respectively.

Also add erofs_mutex_destroy() to include/erofs/lock.h, which was
missing despite erofs_mutex_init() being present.

Signed-off-by: Utkal Singh <[email protected]>
---
 include/erofs/lock.h |  2 ++
 lib/diskbuf.c        | 10 ++++++----
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/erofs/lock.h b/include/erofs/lock.h
index c6e3093..ef4210d 100644
--- a/include/erofs/lock.h
+++ b/include/erofs/lock.h
@@ -15,6 +15,7 @@ static inline void erofs_mutex_init(erofs_mutex_t *lock)
 }
 #define erofs_mutex_lock	pthread_mutex_lock
 #define erofs_mutex_unlock	pthread_mutex_unlock
+#define erofs_mutex_destroy	pthread_mutex_destroy
 
 #define EROFS_DEFINE_MUTEX(lock)	\
 	erofs_mutex_t lock = PTHREAD_MUTEX_INITIALIZER
@@ -35,6 +36,7 @@ typedef struct {} erofs_mutex_t;
 static inline void erofs_mutex_init(erofs_mutex_t *lock) {}
 static inline void erofs_mutex_lock(erofs_mutex_t *lock) {}
 static inline void erofs_mutex_unlock(erofs_mutex_t *lock) {}
+static inline void erofs_mutex_destroy(erofs_mutex_t *lock) {}
 
 #define EROFS_DEFINE_MUTEX(lock)	\
 	erofs_mutex_t lock = {}
diff --git a/lib/diskbuf.c b/lib/diskbuf.c
index 0bf42da..7f4e6e1 100644
--- a/lib/diskbuf.c
+++ b/lib/diskbuf.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
 #include "erofs/diskbuf.h"
 #include "erofs/internal.h"
+#include "erofs/lock.h"
 #include "erofs/print.h"
 #include <stdio.h>
 #include <errno.h>
@@ -14,7 +15,7 @@ static struct erofs_diskbufstrm {
 	u64 tailoffset, devpos;
 	int fd;
 	unsigned int alignsize;
-	bool locked;
+	erofs_mutex_t lock;
 } *dbufstrm;
 
 int erofs_diskbuf_getfd(struct erofs_diskbuf *db, u64 *fpos)
@@ -42,7 +43,7 @@ int erofs_diskbuf_reserve(struct erofs_diskbuf *db, int sid, u64 *off)
 		*off = db->offset + strm->devpos;
 	db->sp = strm;
 	(void)erofs_atomic_inc_return(&strm->count);
-	strm->locked = true;	/* TODO: need a real lock for MT */
+	erofs_mutex_lock(&strm->lock);
 	return strm->fd;
 }
 
@@ -51,9 +52,9 @@ void erofs_diskbuf_commit(struct erofs_diskbuf *db, u64 len)
 	struct erofs_diskbufstrm *strm = db->sp;
 
 	DBG_BUGON(!strm);
-	DBG_BUGON(!strm->locked);
 	DBG_BUGON(strm->tailoffset != db->offset);
 	strm->tailoffset += len;
+	erofs_mutex_unlock(&strm->lock);
 }
 
 void erofs_diskbuf_close(struct erofs_diskbuf *db)
@@ -115,6 +116,7 @@ int erofs_diskbuf_init(unsigned int nstrms)
 setupone:
 		strm->tailoffset = 0;
 		erofs_atomic_set(&strm->count, 1);
+		erofs_mutex_init(&strm->lock);
 		if (fstat(strm->fd, &st))
 			return -errno;
 		strm->alignsize = max_t(u32, st.st_blksize, getpagesize());
@@ -131,7 +133,7 @@ void erofs_diskbuf_exit(void)
 
 	for (strm = dbufstrm; strm->fd >= 0; ++strm) {
 		DBG_BUGON(erofs_atomic_read(&strm->count) != 1);
-
+		erofs_mutex_destroy(&strm->lock);
 		close(strm->fd);
 		strm->fd = -1;
 	}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.