[PATCH 2/2] erofs-utils: lib: use atomic operations for `vi->flags`

Gao Xiang hsiangkao at linux.alibaba.com
Sun Apr 6 00:39:37 AEDT 2025


Since `vi->flags` can be accessed by multiple threads.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/atomic.h   | 5 +++++
 include/erofs/internal.h | 9 ++++++---
 lib/xattr.c              | 6 ++----
 lib/zmap.c               | 4 ++--
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/include/erofs/atomic.h b/include/erofs/atomic.h
index f28687e..142590b 100644
--- a/include/erofs/atomic.h
+++ b/include/erofs/atomic.h
@@ -22,6 +22,11 @@ __n;})
 	__atomic_store(ptr, &__n, __ATOMIC_RELAXED); \
 } while(0)
 
+#define erofs_atomic_set_bit(bit, ptr) do { \
+	typeof(*ptr) __n = (1 << bit);    \
+	__atomic_or_fetch(ptr, __n, __ATOMIC_ACQ_REL); \
+} while(0)
+
 #define erofs_atomic_test_and_set(ptr) \
 	__atomic_test_and_set(ptr, __ATOMIC_RELAXED)
 
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 2f71557..90bee07 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -176,8 +176,11 @@ EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
 EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
 EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER)
 
-#define EROFS_I_EA_INITED	(1 << 0)
-#define EROFS_I_Z_INITED	(1 << 1)
+#define EROFS_I_EA_INITED_BIT	0
+#define EROFS_I_Z_INITED_BIT	1
+
+#define EROFS_I_EA_INITED	(1 << EROFS_I_EA_INITED_BIT)
+#define EROFS_I_Z_INITED	(1 << EROFS_I_Z_INITED_BIT)
 
 struct erofs_diskbuf;
 
@@ -191,7 +194,7 @@ struct erofs_inode {
 
 	union {
 		/* (erofsfuse) runtime flags */
-		unsigned int flags;
+		erofs_atomic_t flags;
 
 		/* (mkfs.erofs) next pointer for directory dumping */
 		struct erofs_inode *next_dirwrite;
diff --git a/lib/xattr.c b/lib/xattr.c
index 976df14..68a96cc 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -1056,7 +1056,7 @@ static int init_inode_xattrs(struct erofs_inode *vi)
 	int ret = 0;
 
 	/* the most case is that xattrs of this inode are initialized. */
-	if (vi->flags & EROFS_I_EA_INITED)
+	if (erofs_atomic_read(&vi->flags) & EROFS_I_EA_INITED)
 		return ret;
 
 	/*
@@ -1117,9 +1117,7 @@ static int init_inode_xattrs(struct erofs_inode *vi)
 			le32_to_cpu(*(__le32 *)(it.kaddr + it.ofs));
 		it.ofs += sizeof(__le32);
 	}
-
-	vi->flags |= EROFS_I_EA_INITED;
-
+	erofs_atomic_set_bit(EROFS_I_EA_INITED_BIT, &vi->flags);
 	return ret;
 }
 
diff --git a/lib/zmap.c b/lib/zmap.c
index 70ff898..2a9baba 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -557,7 +557,7 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
 	struct erofs_sb_info *sbi = vi->sbi;
 	int err, headnr;
 
-	if (vi->flags & EROFS_I_Z_INITED)
+	if (erofs_atomic_read(&vi->flags) & EROFS_I_Z_INITED)
 		return 0;
 
 	pos = round_up(erofs_iloc(vi) + vi->inode_isize + vi->xattr_isize, 8);
@@ -624,7 +624,7 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
 			return err;
 	}
 out:
-	vi->flags |= EROFS_I_Z_INITED;
+	erofs_atomic_set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
 	return 0;
 }
 
-- 
2.43.5



More information about the Linux-erofs mailing list