summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-11-13 17:24:17 +0000
committerMark Brown <broonie@kernel.org>2026-11-13 17:24:17 +0000
commit4a44b23273cc83292963ca76f30c0359ddaa4b71 (patch)
tree4a8c0c8be8cdd51b2dc63ca54035aaeacd6929e6 /include/linux
parenta4ccef42ec64a2d21c0e241e4d09d14d9800efa6 (diff)
parent7b8cd26b6aab8cf147165610d13964f79200a5a7 (diff)
downloadlinux-next-4a44b23273cc83292963ca76f30c0359ddaa4b71.tar.gz
linux-next-4a44b23273cc83292963ca76f30c0359ddaa4b71.zip
Merge branch 'for-next/kspp' of https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/seq_buf.h27
1 files changed, 21 insertions, 6 deletions
diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h
index f006f2654e4c..6b915c67d235 100644
--- a/include/linux/seq_buf.h
+++ b/include/linux/seq_buf.h
@@ -128,8 +128,9 @@ static inline unsigned int seq_buf_used(struct seq_buf *s)
/*
* NUL-terminate the buffer in @s: directly after the data when there is
- * room for it, otherwise in the last byte of the buffer. @s->size must not
- * be zero.
+ * room for it, otherwise in the last byte of the buffer, which marks @s as
+ * overflowed. Data that already ends in a NUL is left as is. @s->size must
+ * not be zero.
*
* Returns: the offset of the NUL.
*/
@@ -137,10 +138,20 @@ static inline size_t __seq_buf_terminate(struct seq_buf *s)
{
size_t end;
- if (seq_buf_buffer_left(s))
+ if (seq_buf_buffer_left(s)) {
+ if (s->len && !s->buffer[s->len - 1])
+ return s->len - 1;
end = s->len;
- else
+ } else {
end = s->size - 1;
+ if (!s->buffer[end])
+ return end;
+ /*
+ * The last byte of data will be overwritten by a NUL
+ * character, so mark the seq_buf as overflowed.
+ */
+ seq_buf_set_overflow(s);
+ }
s->buffer[end] = 0;
@@ -158,7 +169,9 @@ static inline size_t __seq_buf_terminate(struct seq_buf *s)
* the last byte of the buffer is zeroed, and the len will still
* point passed it. The same happens when the buffer is exactly
* full: the NUL takes the place of the last byte written, which is
- * lost, though seq_buf_used() still counts it.
+ * lost, so @s is marked as overflowed, though seq_buf_used() still
+ * counts that byte. When that byte is a NUL already, nothing is lost
+ * and @s is left as is.
*
* A zero-sized seq_buf has nowhere to put a NUL, so the empty string
* is returned instead of writing to @s->buffer. Any other seq_buf
@@ -189,7 +202,9 @@ static inline const char *seq_buf_str(struct seq_buf *s)
* without walking it. Unlike seq_buf_used(), this does not count the byte
* given up to the NUL when the buffer is full or has overflowed. When the
* buffer is exactly full, that byte is the last one written, and calling
- * either function loses it.
+ * either function loses it and marks @s as overflowed, unless it is a NUL
+ * itself. Data that ends in a NUL is already terminated, so its length
+ * does not count that NUL.
*
* A zero-sized seq_buf holds no string, so 0 is returned without writing
* to @s->buffer, matching what seq_buf_str() returns for one.