Re: [PATCH v2 01/15] ceph: add BLOG public headers

Xiubo Li <[email protected]> Tue, 14 Jul 2026 11:17:28 +0800
Newsgroups org.kernel.vger.ceph-devel
Message-ID <CAOJNxRJ9xqNRRumZdwAkQD=twTKkfn_8xwO+UKhXw4dVm=DADg@mail.gmail.com>
Hi Alex,

On Mon, 6 Jul 2026 at 22:38, Alex Markuze <[email protected]> wrote:
>
> Add the public header files for the binary logging (BLOG) subsystem:
>
>   blog.h          - core types: blog_logger, blog_log_entry,
>                     blog_tls_ctx, blog_source_info, blog_log_iter,
>                     blog_source_id_cache; core API prototypes
>   blog_ser.h      - type-safe serialization macros (blog_ser,
>                     blog_cnt) with compile-time type dispatch
>   blog_des.h      - deserialization prototypes
>   blog_batch.h    - per-CPU magazine batch allocator types
>   blog_pagefrag.h - page-fragment allocator types
>   blog_module.h   - per-module context types (blog_task_entry,
>                     blog_module_context) and the __BLOG_LOG_CTX
>                     macro that drives the per-callsite fast path
>

[......]

> +int blog_pagefrag_init_with_buffer(struct blog_pagefrag *pf, void *buffer, size_t size);
> +int blog_pagefrag_reserve(struct blog_pagefrag *pf, unsigned int n);
> +void blog_pagefrag_publish(struct blog_pagefrag *pf, u64 publish_head);
> +void blog_pagefrag_reset(struct blog_pagefrag *pf);
> +void *blog_pagefrag_get_ptr(struct blog_pagefrag *pf, u64 val);
> +
> +#endif /* _LINUX_CEPH_BLOG_PAGEFRAG_H */
> diff --git a/include/linux/ceph/blog_ser.h b/include/linux/ceph/blog_ser.h
> new file mode 100644
> index 000000000000..1d570388ff09
> --- /dev/null
> +++ b/include/linux/ceph/blog_ser.h
> @@ -0,0 +1,270 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Binary Logging Serialization
> + */
> +#ifndef _LINUX_CEPH_BLOG_SER_H
> +#define _LINUX_CEPH_BLOG_SER_H
> +
> +#include <linux/string.h>
> +#include <linux/kernel.h>

In kernel.h header file there is one comment about "it's highly
recommended NOT to include this header inside another header file,
especially under generic or architectural include/ directory."
I think you just need pr_err/pr_warn from linux/printk.h and round_up
from linux/math.h instead directly ?


> +
> +#define IS_CONST_STR_PTR(t) \
> +       __builtin_types_compatible_p(typeof(t), const char *)
> +
> +#define IS_STR_PTR(t) \
> +       __builtin_types_compatible_p(typeof(t), char *)
> +
> +#define IS_STR(t) \
> +       (__builtin_types_compatible_p(typeof(t), const char *) || \
> +       __builtin_types_compatible_p(typeof(t), char *))
> +

[......]

> +
> +#define IS_STR_ARRAY(t) \
> +       __builtin_types_compatible_p(typeof(t), char [])
> +
> +#define IS_DYNAMIC_CHAR_PTR(t) \
> +       (__builtin_classify_type((t)) == 14 && \
> +        __builtin_types_compatible_p(typeof(t), char *) && \
> +        !__builtin_constant_p((t)))
> +

It seems the above macro is dead code?


> +#define IS_STATIC_CHAR_ARRAY(t) \
> +       (__builtin_classify_type((t)) == 5 && \
> +        __builtin_types_compatible_p(typeof(t), char[]) && \
> +        __builtin_constant_p((t)))
> +
> +#define IS_DYNAMIC_CHAR_ARRAY(t) \
> +       (__builtin_classify_type((t)) == 5 && \
> +        __builtin_types_compatible_p(typeof(t), char[]) && \
> +        !__builtin_constant_p((t)))
> +

And also this one. Will them be used somewhere in the future?

Thanks
Xiubo Li

- Xiubo

> +#define char_ptr(str) __suppress_cast_warning(char *, (str))
> +
> +#ifndef _BLOG_SER_HELPERS_DEFINED
> +#define _BLOG_SER_HELPERS_DEFINED
> +
> +union null_str_u {
> +       char str[8];
> +       unsigned long force_align;
> +};
> +
> +static const union null_str_u null_str = {
> +       .str = "(NULL) \0"
> +};
> +
> +static inline size_t write_null_str(char *dst)
> +{
> +       *(union null_str_u *)dst = null_str;
> +       static_assert(sizeof(null_str.str) == sizeof(unsigned long),
> +                    "null_str.str size must match unsigned long for proper alignment");
> +       return __builtin_strlen(null_str.str);
> +}
> +
> +static inline size_t strscpy_n(char *dst, const char *src)
> +{
> +       size_t count = 0;
> +
> +       while (count < STR_MAX_SIZE - 1) {
> +               dst[count] = src[count];
> +               if (src[count] == '\0')
> +                       goto out;
> +               count++;
> +       }
> +
> +       dst[count] = '\0';
> +       pr_warn("blog_ser: string truncated, exceeded max size %d\n", STR_MAX_SIZE);
> +out:
> +       return count + 1;
> +}
> +
> +static inline ssize_t __strscpy(char *dst, const char *src)
> +{
> +       if (src != NULL)
> +               return strscpy_n(dst, src);
> +       return write_null_str(dst);
> +}
> +
> +static inline void *strscpy_n_update(char *dst, const char *src, const char *file, int line)
> +{
> +       ssize_t ret = __strscpy(dst, src);
> +
> +       if (unlikely(ret <= 0 || ret >= STR_MAX_SIZE)) {
> +               pr_err("blog_ser: string handling error ret=%zd at %s:%d :: dst='%s' src='%s'\n",
> +                      ret, file, line, dst, src ? src : "(null)");
> +               if (ret >= STR_MAX_SIZE) {
> +                       dst[STR_MAX_SIZE - 1] = '\0';
> +                       ret = STR_MAX_SIZE;
> +               } else {
> +                       dst[0] = '\0';
> +                       ret = 1;
> +               }
> +       }
> +       return dst + round_up(ret, 4);
> +}
> +
> +#endif /* _BLOG_SER_HELPERS_DEFINED */
> +
> +#define __blog_ser_type(__buffer, __t)                          \
> +       (__builtin_choose_expr(IS_STATIC_CHAR_ARRAY((__t)),               \
> +               ((__buffer) = (void *)strscpy_n_update((__buffer),            \
> +                                               char_ptr(__t),                             \
> +                                               kbasename(__FILE__),                      \
> +                                               __LINE__)),                               \
> +       __builtin_choose_expr(IS_STR((__t)),               \
> +               ((__buffer) = (void *)strscpy_n_update((__buffer),            \
> +                                               char_ptr(__t),                             \
> +                                               kbasename(__FILE__),                      \
> +                                               __LINE__)),                               \
> +       __builtin_choose_expr(IS_STR_ARRAY((__t)),               \
> +                ((__buffer) = (void *)strscpy_n_update((__buffer),        \
> +                                               char_ptr(__t),                       \
> +                                               kbasename(__FILE__),                \
> +                                               __LINE__)),                          \
> +       __builtin_choose_expr(sizeof((__t)) == 1,                         \
> +               (*(u32 *)(__buffer) = __suppress_cast_warning(u32, (__t)), \
> +                (__buffer) = (void *)((char *)(__buffer) + 4)),            \
> +       __builtin_choose_expr(sizeof((__t)) == 2,                         \
> +               (*(u32 *)(__buffer) = __suppress_cast_warning(u32, (__t)), \
> +                (__buffer) = (void *)((char *)(__buffer) + 4)),            \
> +       __builtin_choose_expr(sizeof((__t)) == 4,                         \
> +               (*(u32 *)(__buffer) = __suppress_cast_warning(u32, (__t)), \
> +                (__buffer) = (void *)((char *)(__buffer) + 4)),            \
> +       __builtin_choose_expr(sizeof((__t)) == 8,                         \
> +               (*(u64 *)(__buffer) = __suppress_cast_warning(u64, (__t)), \
> +                (__buffer) = (void *)((char *)(__buffer) + 8)),            \
> +               (pr_err("UNSUPPORTED_TYPE: %s:%d: unsupported type size %zu\n",       \
> +                       kbasename(__FILE__), __LINE__, sizeof(__t)))              \
> +       ))))))))
> +
> +/* Serialization macros */
> +#define ___blog_ser0(__buffer)
> +#define ___blog_ser1(__buffer, __t)           (__blog_ser_type(__buffer, __t))
> +#define ___blog_ser2(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser1(__buffer, __args))
> +#define ___blog_ser3(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser2(__buffer, __args))
> +#define ___blog_ser4(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser3(__buffer, __args))
> +#define ___blog_ser5(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser4(__buffer, __args))
> +#define ___blog_ser6(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser5(__buffer, __args))
> +#define ___blog_ser7(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser6(__buffer, __args))
> +#define ___blog_ser8(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser7(__buffer, __args))
> +#define ___blog_ser9(__buffer, __t, __args...)    \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser8(__buffer, __args))
> +#define ___blog_ser10(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser9(__buffer, __args))
> +#define ___blog_ser11(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser10(__buffer, __args))
> +#define ___blog_ser12(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser11(__buffer, __args))
> +#define ___blog_ser13(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser12(__buffer, __args))
> +#define ___blog_ser14(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser13(__buffer, __args))
> +#define ___blog_ser15(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser14(__buffer, __args))
> +#define ___blog_ser16(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser15(__buffer, __args))
> +#define ___blog_ser17(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser16(__buffer, __args))
> +#define ___blog_ser18(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser17(__buffer, __args))
> +#define ___blog_ser19(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser18(__buffer, __args))
> +#define ___blog_ser20(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser19(__buffer, __args))
> +#define ___blog_ser21(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser20(__buffer, __args))
> +#define ___blog_ser22(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser21(__buffer, __args))
> +#define ___blog_ser23(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser22(__buffer, __args))
> +#define ___blog_ser24(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser23(__buffer, __args))
> +#define ___blog_ser25(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser24(__buffer, __args))
> +#define ___blog_ser26(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser25(__buffer, __args))
> +#define ___blog_ser27(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser26(__buffer, __args))
> +#define ___blog_ser28(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser27(__buffer, __args))
> +#define ___blog_ser29(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser28(__buffer, __args))
> +#define ___blog_ser30(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser29(__buffer, __args))
> +#define ___blog_ser31(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser30(__buffer, __args))
> +#define ___blog_ser32(__buffer, __t, __args...)   \
> +       (__blog_ser_type(__buffer, __t), ___blog_ser31(__buffer, __args))
> +#define ___blog_ser(__buffer, ...)   \
> +       ___blog_apply(___blog_ser, blog_narg(__VA_ARGS__))(__buffer, ##__VA_ARGS__)
> +#define blog_ser(...)  ___blog_ser(__VA_ARGS__)
> +
> +#endif /* _LINUX_CEPH_BLOG_SER_H */
> --
> 2.34.1
>