aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2021-12-11 04:18:52 +0000
committerAlexander Motin <mav@FreeBSD.org>2021-12-11 04:35:53 +0000
commit81dc00331d148fab19af24833521334e39f3692d (patch)
treecc24ea768eb3f92b79647f51a8400b64ca3a7435 /sys
parent7a382e744b0b0ba9b51dc34bfa0cd1515f744f25 (diff)
downloadsrc-81dc00331d148fab19af24833521334e39f3692d.tar.gz
src-81dc00331d148fab19af24833521334e39f3692d.zip
Make msgbuf_peekbytes() not return leading zeroes.
Introduce new MSGBUF_WRAP flag, indicating that buffer has wrapped at least once and does not keep zeroes from the last msgbuf_clear(). It allows msgbuf_peekbytes() to return only real data, not requiring every consumer to trim the leading zeroes after doing pointless copy. The most visible effect is that kern.msgbuf sysctl now always returns proper zero-terminated string, not only after the first buffer wrap. MFC after: 1 week Sponsored by: iXsystems, Inc.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_msgbuf.c55
-rw-r--r--sys/sys/msgbuf.h7
2 files changed, 30 insertions, 32 deletions
diff --git a/sys/kern/subr_msgbuf.c b/sys/kern/subr_msgbuf.c
index 8af013d52a2d..b41e78dd886e 100644
--- a/sys/kern/subr_msgbuf.c
+++ b/sys/kern/subr_msgbuf.c
@@ -69,10 +69,10 @@ msgbuf_init(struct msgbuf *mbp, void *ptr, int size)
mbp->msg_ptr = ptr;
mbp->msg_size = size;
mbp->msg_seqmod = SEQMOD(size);
- msgbuf_clear(mbp);
- mbp->msg_magic = MSG_MAGIC;
mbp->msg_lastpri = -1;
mbp->msg_flags = 0;
+ msgbuf_clear(mbp);
+ mbp->msg_magic = MSG_MAGIC;
bzero(&mbp->msg_lock, sizeof(mbp->msg_lock));
mtx_init(&mbp->msg_lock, "msgbuf", NULL, MTX_SPIN);
}
@@ -123,6 +123,7 @@ msgbuf_clear(struct msgbuf *mbp)
mbp->msg_wseq = 0;
mbp->msg_rseq = 0;
mbp->msg_cksum = 0;
+ mbp->msg_flags &= ~MSGBUF_WRAP;
}
/*
@@ -145,18 +146,17 @@ msgbuf_getcount(struct msgbuf *mbp)
*
* The caller should hold the message buffer spinlock.
*/
-
static void
-msgbuf_do_addchar(struct msgbuf * const mbp, u_int * const seq, const int c)
+msgbuf_do_addchar(struct msgbuf * const mbp, const int c)
{
u_int pos;
/* Make sure we properly wrap the sequence number. */
- pos = MSGBUF_SEQ_TO_POS(mbp, *seq);
+ pos = MSGBUF_SEQ_TO_POS(mbp, mbp->msg_wseq);
mbp->msg_cksum += (u_int)(u_char)c -
(u_int)(u_char)mbp->msg_ptr[pos];
mbp->msg_ptr[pos] = c;
- *seq = MSGBUF_SEQNORM(mbp, *seq + 1);
+ mbp->msg_wseq = MSGBUF_SEQADD(mbp, mbp->msg_wseq, 1);
}
/*
@@ -167,7 +167,9 @@ msgbuf_addchar(struct msgbuf *mbp, int c)
{
mtx_lock_spin(&mbp->msg_lock);
- msgbuf_do_addchar(mbp, &mbp->msg_wseq, c);
+ msgbuf_do_addchar(mbp, c);
+ if (mbp->msg_wseq >= mbp->msg_size)
+ mbp->msg_flags |= MSGBUF_WRAP;
mtx_unlock_spin(&mbp->msg_lock);
}
@@ -183,7 +185,6 @@ msgbuf_addchar(struct msgbuf *mbp, int c)
void
msgbuf_addstr(struct msgbuf *mbp, int pri, const char *str, int filter_cr)
{
- u_int seq;
size_t len, prefix_len;
char prefix[MAXPRIBUF];
char buf[32];
@@ -206,11 +207,6 @@ msgbuf_addstr(struct msgbuf *mbp, int pri, const char *str, int filter_cr)
prefix_len = sprintf(prefix, "<%d>", pri);
/*
- * Starting write sequence number.
- */
- seq = mbp->msg_wseq;
-
- /*
* Whenever there is a change in priority, we have to insert a
* newline, and a priority prefix if the priority is not -1. Here
* we detect whether there was a priority change, and whether we
@@ -218,7 +214,7 @@ msgbuf_addstr(struct msgbuf *mbp, int pri, const char *str, int filter_cr)
* insert a newline before this string.
*/
if (mbp->msg_lastpri != pri && (mbp->msg_flags & MSGBUF_NEEDNL) != 0) {
- msgbuf_do_addchar(mbp, &seq, '\n');
+ msgbuf_do_addchar(mbp, '\n');
mbp->msg_flags &= ~MSGBUF_NEEDNL;
}
@@ -233,7 +229,7 @@ msgbuf_addstr(struct msgbuf *mbp, int pri, const char *str, int filter_cr)
int j;
for (j = 0; j < prefix_len; j++)
- msgbuf_do_addchar(mbp, &seq, prefix[j]);
+ msgbuf_do_addchar(mbp, prefix[j]);
}
if (msgbuf_show_timestamp && needtime == 1 &&
@@ -241,7 +237,7 @@ msgbuf_addstr(struct msgbuf *mbp, int pri, const char *str, int filter_cr)
snprintf(buf, sizeof(buf), "[%jd] ",
(intmax_t)time_uptime);
for (j = 0; buf[j] != '\0'; j++)
- msgbuf_do_addchar(mbp, &seq, buf[j]);
+ msgbuf_do_addchar(mbp, buf[j]);
needtime = 0;
}
@@ -265,14 +261,10 @@ msgbuf_addstr(struct msgbuf *mbp, int pri, const char *str, int filter_cr)
else
mbp->msg_flags |= MSGBUF_NEEDNL;
- msgbuf_do_addchar(mbp, &seq, str[i]);
+ msgbuf_do_addchar(mbp, str[i]);
}
- /*
- * Update the write sequence number for the actual number of
- * characters we put in the message buffer. (Depends on whether
- * carriage returns are filtered.)
- */
- mbp->msg_wseq = seq;
+ if (mbp->msg_wseq >= mbp->msg_size)
+ mbp->msg_flags |= MSGBUF_WRAP;
/*
* Set the last priority.
@@ -302,9 +294,9 @@ msgbuf_getchar(struct msgbuf *mbp)
return (-1);
}
if (len > mbp->msg_size)
- mbp->msg_rseq = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size);
+ mbp->msg_rseq = MSGBUF_SEQSUB(mbp, wseq, mbp->msg_size);
c = (u_char)mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, mbp->msg_rseq)];
- mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq + 1);
+ mbp->msg_rseq = MSGBUF_SEQADD(mbp, mbp->msg_rseq, 1);
mtx_unlock_spin(&mbp->msg_lock);
@@ -329,7 +321,7 @@ msgbuf_getbytes(struct msgbuf *mbp, char *buf, int buflen)
return (0);
}
if (len > mbp->msg_size) {
- mbp->msg_rseq = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size);
+ mbp->msg_rseq = MSGBUF_SEQSUB(mbp, wseq, mbp->msg_size);
len = mbp->msg_size;
}
pos = MSGBUF_SEQ_TO_POS(mbp, mbp->msg_rseq);
@@ -337,7 +329,7 @@ msgbuf_getbytes(struct msgbuf *mbp, char *buf, int buflen)
len = min(len, (u_int)buflen);
bcopy(&mbp->msg_ptr[pos], buf, len);
- mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq + len);
+ mbp->msg_rseq = MSGBUF_SEQADD(mbp, mbp->msg_rseq, len);
mtx_unlock_spin(&mbp->msg_lock);
@@ -363,7 +355,10 @@ msgbuf_peekbytes(struct msgbuf *mbp, char *buf, int buflen, u_int *seqp)
if (buf == NULL) {
/* Just initialise *seqp. */
- *seqp = MSGBUF_SEQNORM(mbp, mbp->msg_wseq - mbp->msg_size);
+ if (mbp->msg_flags & MSGBUF_WRAP)
+ *seqp = MSGBUF_SEQSUB(mbp, mbp->msg_wseq, mbp->msg_size);
+ else
+ *seqp = 0;
mtx_unlock_spin(&mbp->msg_lock);
return (0);
}
@@ -375,14 +370,14 @@ msgbuf_peekbytes(struct msgbuf *mbp, char *buf, int buflen, u_int *seqp)
return (0);
}
if (len > mbp->msg_size) {
- *seqp = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size);
+ *seqp = MSGBUF_SEQSUB(mbp, wseq, mbp->msg_size);
len = mbp->msg_size;
}
pos = MSGBUF_SEQ_TO_POS(mbp, *seqp);
len = min(len, mbp->msg_size - pos);
len = min(len, (u_int)buflen);
bcopy(&mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, *seqp)], buf, len);
- *seqp = MSGBUF_SEQNORM(mbp, *seqp + len);
+ *seqp = MSGBUF_SEQADD(mbp, *seqp, len);
mtx_unlock_spin(&mbp->msg_lock);
diff --git a/sys/sys/msgbuf.h b/sys/sys/msgbuf.h
index 27aba1a8e0ed..6768b862faf7 100644
--- a/sys/sys/msgbuf.h
+++ b/sys/sys/msgbuf.h
@@ -50,6 +50,7 @@ struct msgbuf {
int msg_lastpri; /* saved priority value */
u_int msg_flags;
#define MSGBUF_NEEDNL 0x01 /* set when newline needed */
+#define MSGBUF_WRAP 0x02 /* buffer has wrapped around */
struct mtx msg_lock; /* mutex to protect the buffer */
};
@@ -57,8 +58,10 @@ struct msgbuf {
#define MSGBUF_SEQNORM(mbp, seq) (((seq) + (mbp)->msg_seqmod) % \
(mbp)->msg_seqmod)
#define MSGBUF_SEQ_TO_POS(mbp, seq) ((seq) % (mbp)->msg_size)
-/* Subtract sequence numbers. Note that only positive values result. */
-#define MSGBUF_SEQSUB(mbp, seq1, seq2) (MSGBUF_SEQNORM((mbp), (seq1) - (seq2)))
+/* Add/subtract normalized sequence numbers. Normalized values result. */
+#define MSGBUF_SEQADD(mbp, seq1, seq2) (((seq1) + (seq2)) % (mbp)->msg_seqmod)
+#define MSGBUF_SEQSUB(mbp, seq1, seq2) ((seq1) >= (seq2) ? (seq1) - (seq2) : \
+ (seq1) + (mbp)->msg_seqmod - (seq2))
#ifdef _KERNEL
extern int msgbufsize;