Subject: [PATCH 1/3] relayfs: introduce relay_subbuf_avail()

From: Jason Xing <[email-masked]>
Date: Sun, 31 May 2026 11:40:08 +0800

From: Jason Xing <[email-masked]>

Add relay_subbuf_avail() which ensures the sub-buffer has room and
returns the buffer pointer without advancing the offset.

Together with __relay_write(), it lets callers emit multi-part records
where the offset only moves after each chunk is copied, closing the
stale-read window.

Signed-off-by: Jason Xing <[email-masked]>
---
 include/linux/relay.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/linux/relay.h b/include/linux/relay.h
index 6772a7075840..270a028586bd 100644
--- a/include/linux/relay.h
+++ b/include/linux/relay.h
@@ -268,6 +268,30 @@ static inline void *relay_reserve(struct rchan *chan, size_t length)
 	return reserved;
 }
 
+/**
+ *	relay_subbuf_avail - ensure @length bytes fit in current sub-buffer
+ *	@chan: relay channel
+ *	@length: total number of bytes to check
+ *
+ *	Returns the per-cpu buffer if @length bytes fit, NULL otherwise.
+ *	Switches to the next sub-buffer if necessary but does NOT advance
+ *	the write offset.  Use __relay_write() to write into the returned
+ *	buffer.
+ *
+ *	Caller must prevent preemption and serialise against other writers.
+ */
+static inline struct rchan_buf *
+relay_subbuf_avail(struct rchan *chan, size_t length)
+{
+	struct rchan_buf *buf = *this_cpu_ptr(chan->buf);
+
+	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
+		if (!relay_switch_subbuf(buf, length))
+			return NULL;
+	}
+	return buf;
+}
+
 /**
  *	subbuf_start_reserve - reserve bytes at the start of a sub-buffer
  *	@buf: relay channel buffer
-- 
2.43.7