The branch main has been updated by dumbbell:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=710167623d82664ab4276776aed502ab6f91d8ff

commit 710167623d82664ab4276776aed502ab6f91d8ff
Author:     Jean-Sébastien Pédron <[email protected]>
AuthorDate: 2025-08-11 17:51:59 +0000
Commit:     Jean-Sébastien Pédron <[email protected]>
CommitDate: 2026-01-24 19:16:14 +0000

    linuxkpi: Implement <linux/seq_buf.h>
    
    It is a wrapper above a `char *` to track the overall available space in
    the buffer as well as the used space. This wrapper does not manage
    memory allocation.
    
    The DRM generic code started to use this in Linux 6.10.
    
    Reviewed by:    bz
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D54488
---
 sys/compat/linuxkpi/common/include/linux/seq_buf.h | 73 ++++++++++++++++++++++
 sys/compat/linuxkpi/common/src/linux_seq_buf.c     | 64 +++++++++++++++++++
 sys/conf/files                                     |  2 +
 sys/modules/linuxkpi/Makefile                      |  1 +
 4 files changed, 140 insertions(+)

diff --git a/sys/compat/linuxkpi/common/include/linux/seq_buf.h 
b/sys/compat/linuxkpi/common/include/linux/seq_buf.h
new file mode 100644
index 000000000000..d6246a40e6f7
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/seq_buf.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ * Copyright (c) 2025-2026 Jean-Sébastien Pédron <[email protected]>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_SEQ_BUF_H_
+#define        _LINUXKPI_LINUX_SEQ_BUF_H_
+
+#include <linux/bug.h>
+#include <linux/minmax.h>
+#include <linux/seq_file.h>
+#include <linux/types.h>
+
+struct seq_buf {
+       char    *buffer;
+       size_t   size;
+       size_t   len;
+};
+
+#define DECLARE_SEQ_BUF(NAME, SIZE)                    \
+       struct seq_buf NAME = {                         \
+               .buffer = (char[SIZE]) { 0 },           \
+               .size = SIZE,                           \
+       }
+
+static inline void
+seq_buf_clear(struct seq_buf *s)
+{
+       s->len = 0;
+       if (s->size > 0)
+               s->buffer[0] = '\0';
+}
+
+static inline void
+seq_buf_set_overflow(struct seq_buf *s)
+{
+       s->len = s->size + 1;
+}
+
+static inline bool
+seq_buf_has_overflowed(struct seq_buf *s)
+{
+       return (s->len > s->size);
+}
+
+static inline bool
+seq_buf_buffer_left(struct seq_buf *s)
+{
+       if (seq_buf_has_overflowed(s))
+               return (0);
+
+       return (s->size - s->len);
+}
+
+#define        seq_buf_init(s, buf, size) linuxkpi_seq_buf_init((s), (buf), 
(size))
+void linuxkpi_seq_buf_init(struct seq_buf *s, char *buf, unsigned int size);
+
+#define        seq_buf_printf(s, f, ...) linuxkpi_seq_buf_printf((s), (f), 
__VA_ARGS__)
+int linuxkpi_seq_buf_printf(struct seq_buf *s, const char *fmt, ...) \
+    __printflike(2, 3);
+
+#define        seq_buf_vprintf(s, f, a) linuxkpi_seq_buf_vprintf((s), (f), (a))
+int linuxkpi_seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
+
+#define        seq_buf_str(s) linuxkpi_seq_buf_str((s))
+const char * linuxkpi_seq_buf_str(struct seq_buf *s);
+
+#endif
diff --git a/sys/compat/linuxkpi/common/src/linux_seq_buf.c 
b/sys/compat/linuxkpi/common/src/linux_seq_buf.c
new file mode 100644
index 000000000000..112c53044c22
--- /dev/null
+++ b/sys/compat/linuxkpi/common/src/linux_seq_buf.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ * Copyright (c) 2025-2026 Jean-Sébastien Pédron <[email protected]>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <linux/seq_buf.h>
+ 
+void
+linuxkpi_seq_buf_init(struct seq_buf *s, char *buf, unsigned int size)
+{
+       s->buffer = buf;
+       s->size = size;
+
+       seq_buf_clear(s);
+}
+ 
+int
+linuxkpi_seq_buf_printf(struct seq_buf *s, const char *fmt, ...)
+{
+       int ret;
+       va_list args;
+
+       va_start(args, fmt);
+       ret = seq_buf_vprintf(s, fmt, args);
+       va_end(args);
+
+       return (ret);
+}
+ 
+int
+linuxkpi_seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args)
+{
+       int ret;
+
+       if (!seq_buf_has_overflowed(s)) {
+               ret = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, 
args);
+               if (s->len + ret < s->size) {
+                       s->len += ret;
+                       return (0);
+               }
+       }
+
+       seq_buf_set_overflow(s);
+       return (-1);
+}
+
+const char *
+linuxkpi_seq_buf_str(struct seq_buf *s)
+{
+       if (s->size == 0)
+               return ("");
+
+       if (seq_buf_buffer_left(s))
+               s->buffer[s->len] = '\0';
+       else
+               s->buffer[s->size - 1] = '\0';
+
+       return (s->buffer);
+}
diff --git a/sys/conf/files b/sys/conf/files
index a6a76dec433a..5f8c9379ddf3 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4700,6 +4700,8 @@ compat/linuxkpi/common/src/linux_rcu.c            
optional compat_linuxkpi \
        compile-with "${LINUXKPI_C} -I$S/contrib/ck/include"
 compat/linuxkpi/common/src/linux_schedule.c    optional compat_linuxkpi \
        compile-with "${LINUXKPI_C}"
+compat/linuxkpi/common/src/linux_seq_buf.c     optional compat_linuxkpi \
+       compile-with "${LINUXKPI_C}"
 compat/linuxkpi/common/src/linux_shmemfs.c     optional compat_linuxkpi \
        compile-with "${LINUXKPI_C}"
 compat/linuxkpi/common/src/linux_shrinker.c    optional compat_linuxkpi \
diff --git a/sys/modules/linuxkpi/Makefile b/sys/modules/linuxkpi/Makefile
index c465c76a7626..77d73f19075a 100644
--- a/sys/modules/linuxkpi/Makefile
+++ b/sys/modules/linuxkpi/Makefile
@@ -24,6 +24,7 @@ SRCS= linux_compat.c \
        linux_radix.c \
        linux_rcu.c \
        linux_schedule.c \
+       linux_seq_buf.c \
        linux_seq_file.c \
        linux_shmemfs.c \
        linux_shrinker.c \

Reply via email to