Add some helpers (relaxed semantics) in order to prepare for the
upcoming multi-threaded support.
For example, compressor may be initialized more than once in different
worker threads, resulting in noisy warnings.
This patch makes sure that each message will be printed only once by
adding `__warnonce` atomic booleans to each erofs_compressor_init().
Cc: Yifan Zhao <zhaoyifan@sjtu.edu.cn>
Signed-off-by: Yifan Zhao <zhaoyifan@sjtu.edu.cn>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20240315011019.610442-4-hsiangkao@linux.alibaba.com
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0 */
+/*
+ * Copyright (C) 2024 Alibaba Cloud
+ */
+#ifndef __EROFS_ATOMIC_H
+#define __EROFS_ATOMIC_H
+
+/*
+ * Just use GCC/clang built-in functions for now
+ * See: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
+ */
+typedef unsigned long erofs_atomic_t;
+typedef char erofs_atomic_bool_t;
+
+#define erofs_atomic_read(ptr) ({ \
+ typeof(*ptr) __n; \
+ __atomic_load(ptr, &__n, __ATOMIC_RELAXED); \
+__n;})
+
+#define erofs_atomic_set(ptr, n) do { \
+ typeof(*ptr) __n = (n); \
+ __atomic_store(ptr, &__n, __ATOMIC_RELAXED); \
+} while(0)
+
+#define erofs_atomic_test_and_set(ptr) \
+ __atomic_test_and_set(ptr, __ATOMIC_RELAXED)
+
+#endif
#include "erofs/print.h"
#include "erofs/config.h"
#include "compressor.h"
+#include "erofs/atomic.h"
void *kite_deflate_init(int level, unsigned int dict_size);
void kite_deflate_end(void *s);
static int compressor_deflate_init(struct erofs_compress *c)
{
+ static erofs_atomic_bool_t __warnonce;
+
if (c->private_data) {
kite_deflate_end(c->private_data);
c->private_data = NULL;
if (IS_ERR_VALUE(c->private_data))
return PTR_ERR(c->private_data);
- erofs_warn("EXPERIMENTAL DEFLATE algorithm in use. Use at your own risk!");
- erofs_warn("*Carefully* check filesystem data correctness to avoid corruption!");
- erofs_warn("Please send a report to <linux-erofs@lists.ozlabs.org> if something is wrong.");
+ if (!erofs_atomic_test_and_set(&__warnonce)) {
+ erofs_warn("EXPERIMENTAL DEFLATE algorithm in use. Use at your own risk!");
+ erofs_warn("*Carefully* check filesystem data correctness to avoid corruption!");
+ erofs_warn("Please send a report to <linux-erofs@lists.ozlabs.org> if something is wrong.");
+ }
return 0;
}
#include "erofs/config.h"
#include <libdeflate.h>
#include "compressor.h"
+#include "erofs/atomic.h"
static int libdeflate_compress_destsize(const struct erofs_compress *c,
const void *src, unsigned int *srcsize,
static int compressor_libdeflate_init(struct erofs_compress *c)
{
+ static erofs_atomic_bool_t __warnonce;
+
libdeflate_free_compressor(c->private_data);
c->private_data = libdeflate_alloc_compressor(c->compression_level);
if (!c->private_data)
return -ENOMEM;
- erofs_warn("EXPERIMENTAL libdeflate compressor in use. Use at your own risk!");
+ if (!erofs_atomic_test_and_set(&__warnonce))
+ erofs_warn("EXPERIMENTAL libdeflate compressor in use. Use at your own risk!");
return 0;
}
#include "erofs/config.h"
#include "erofs/print.h"
#include "erofs/internal.h"
+#include "erofs/atomic.h"
#include "compressor.h"
struct erofs_liblzma_context {
{
struct erofs_liblzma_context *ctx;
u32 preset;
+ static erofs_atomic_bool_t __warnonce;
ctx = malloc(sizeof(*ctx));
if (!ctx)
ctx->opt.dict_size = c->dict_size;
c->private_data = ctx;
- erofs_warn("It may take a longer time since MicroLZMA is still single-threaded for now.");
+ if (!erofs_atomic_test_and_set(&__warnonce))
+ erofs_warn("It may take a longer time since MicroLZMA is still single-threaded for now.");
return 0;
}