erofs-utils: use erofs_atomic_t for inode->i_count
authorGao Xiang <hsiangkao@linux.alibaba.com>
Mon, 22 Apr 2024 00:34:43 +0000 (08:34 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 24 Apr 2024 10:46:56 +0000 (18:46 +0800)
Since `inode->i_count` can be touched for more than one thread if
multi-threading is enabled.

Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20240422003450.19132-1-xiang@kernel.org
include/erofs/atomic.h
include/erofs/inode.h
include/erofs/internal.h
lib/inode.c

index 214cdb1f798240939238a884bdeac598333a5a7d..f28687eeb1f8f658cba6dc4404563be4e15aae0d 100644 (file)
@@ -25,4 +25,14 @@ __n;})
 #define erofs_atomic_test_and_set(ptr) \
        __atomic_test_and_set(ptr, __ATOMIC_RELAXED)
 
+#define erofs_atomic_add_return(ptr, i) \
+       __atomic_add_fetch(ptr, i, __ATOMIC_RELAXED)
+
+#define erofs_atomic_sub_return(ptr, i) \
+       __atomic_sub_fetch(ptr, i, __ATOMIC_RELAXED)
+
+#define erofs_atomic_inc_return(ptr) erofs_atomic_add_return(ptr, 1)
+
+#define erofs_atomic_dec_return(ptr) erofs_atomic_sub_return(ptr, 1)
+
 #endif
index d5a732ac8d8dfa0f4a264d33e8ef39300d6827ae..5d6bc981576148c964cb71333e1802f39c131b0a 100644 (file)
@@ -17,7 +17,7 @@ extern "C"
 
 static inline struct erofs_inode *erofs_igrab(struct erofs_inode *inode)
 {
-       ++inode->i_count;
+       (void)erofs_atomic_inc_return(&inode->i_count);
        return inode;
 }
 
index 4cd205933ad835f4e5bbd8027a7f99a084b5074a..f31e548bd1d6af152ed0f885d0cbffb4bd3e12a5 100644 (file)
@@ -25,6 +25,7 @@ typedef unsigned short umode_t;
 #ifdef HAVE_PTHREAD_H
 #include <pthread.h>
 #endif
+#include "atomic.h"
 
 #ifndef PATH_MAX
 #define PATH_MAX        4096    /* # chars in a path name including nul */
@@ -169,7 +170,7 @@ struct erofs_inode {
                /* (mkfs.erofs) next pointer for directory dumping */
                struct erofs_inode *next_dirwrite;
        };
-       unsigned int i_count;
+       erofs_atomic_t i_count;
        struct erofs_sb_info *sbi;
        struct erofs_inode *i_parent;
 
index 896a2574d471ad8d8aea35b0d74a1c4592a184ea..6e8e17f99cc5cf78b394c050f61842ad600f8f3f 100644 (file)
@@ -129,9 +129,10 @@ struct erofs_inode *erofs_iget_by_nid(erofs_nid_t nid)
 unsigned int erofs_iput(struct erofs_inode *inode)
 {
        struct erofs_dentry *d, *t;
+       unsigned long got = erofs_atomic_dec_return(&inode->i_count);
 
-       if (inode->i_count > 1)
-               return --inode->i_count;
+       if (got >= 1)
+               return got;
 
        list_for_each_entry_safe(d, t, &inode->i_subdirs, d_child)
                free(d);