The branch main has been updated by mav:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=81dc00331d148fab19af24833521334e39f3692d

commit 81dc00331d148fab19af24833521334e39f3692d
Author:     Alexander Motin <m...@freebsd.org>
AuthorDate: 2021-12-11 04:18:52 +0000
Commit:     Alexander Motin <m...@freebsd.org>
CommitDate: 2021-12-11 04:35:53 +0000

    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.
---
 sys/kern/subr_msgbuf.c | 55 +++++++++++++++++++++++---------------------------
 sys/sys/msgbuf.h       |  7 +++++--
 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];
@@ -205,11 +206,6 @@ msgbuf_addstr(struct msgbuf *mbp, int pri, const char 
*str, int filter_cr)
        if (pri != -1)
                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
@@ -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;

Reply via email to