aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man9/Makefile2
-rw-r--r--share/man/man9/sbuf.919
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c10
-rw-r--r--sys/compat/linux/linux_ioctl.c4
-rw-r--r--sys/kern/kern_sig.c2
-rw-r--r--sys/kern/subr_sbuf.c53
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/security/audit/audit_bsm_klib.c2
-rw-r--r--sys/sys/sbuf.h3
9 files changed, 51 insertions, 48 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 6abafe19e09f..194eba471376 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1025,10 +1025,10 @@ MLINKS+=sbuf.9 sbuf_bcat.9 \
sbuf.9 sbuf_data.9 \
sbuf.9 sbuf_delete.9 \
sbuf.9 sbuf_done.9 \
+ sbuf.9 sbuf_error.9 \
sbuf.9 sbuf_finish.9 \
sbuf.9 sbuf_len.9 \
sbuf.9 sbuf_new.9 \
- sbuf.9 sbuf_overflowed.9 \
sbuf.9 sbuf_printf.9 \
sbuf.9 sbuf_putc.9 \
sbuf.9 sbuf_set_drain.9 \
diff --git a/share/man/man9/sbuf.9 b/share/man/man9/sbuf.9
index 7389064544fa..0b6aa908d079 100644
--- a/share/man/man9/sbuf.9
+++ b/share/man/man9/sbuf.9
@@ -45,7 +45,7 @@
.Nm sbuf_putc ,
.Nm sbuf_set_drain ,
.Nm sbuf_trim ,
-.Nm sbuf_overflowed ,
+.Nm sbuf_error ,
.Nm sbuf_finish ,
.Nm sbuf_data ,
.Nm sbuf_len ,
@@ -88,7 +88,7 @@
.Ft int
.Fn sbuf_trim "struct sbuf *s"
.Ft int
-.Fn sbuf_overflowed "struct sbuf *s"
+.Fn sbuf_error "struct sbuf *s"
.Ft int
.Fn sbuf_finish "struct sbuf *s"
.Ft char *
@@ -332,10 +332,15 @@ function removes trailing whitespace from the
.Fa sbuf .
.Pp
The
-.Fn sbuf_overflowed
-function returns a non-zero value if the
+.Fn sbuf_error
+function returns any error value that the
+.Fa sbuf
+may have accumulated, either from the drain function, or ENOMEM if the
.Fa sbuf
overflowed.
+This function is generally not needed and instead the error code from
+.Fn sbuf_finish
+is the preferred way to discover whether an sbuf had an error.
.Pp
The
.Fn sbuf_finish
@@ -437,9 +442,9 @@ functions
all return \-1 if the buffer overflowed, and zero otherwise.
.Pp
The
-.Fn sbuf_overflowed
-function
-returns a non-zero value if the buffer overflowed, and zero otherwise.
+.Fn sbuf_error
+function returns a non-zero value if the buffer has an overflow or
+drain error, and zero otherwise.
.Pp
The
.Fn sbuf_data
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c
index 63ae13ac856a..cf2f90db69d0 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c
@@ -101,6 +101,7 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
char buf[1024];
struct sbuf sb;
struct timespec ts;
+ int error;
/*
* If we are doing a spa_tryimport(), ignore errors.
@@ -315,9 +316,9 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
}
mutex_exit(&spa->spa_errlist_lock);
- sbuf_finish(&sb);
+ error = sbuf_finish(&sb);
devctl_notify("ZFS", spa->spa_name, subclass, sbuf_data(&sb));
- if (sbuf_overflowed(&sb))
+ if (error != 0)
printf("ZFS WARNING: sbuf overflowed\n");
sbuf_delete(&sb);
#endif
@@ -331,6 +332,7 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *name)
char class[64];
struct sbuf sb;
struct timespec ts;
+ int error;
nanotime(&ts);
@@ -346,10 +348,10 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *name)
if (vd)
sbuf_printf(&sb, " %s=%ju", FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
vd->vdev_guid);
- sbuf_finish(&sb);
+ error = sbuf_finish(&sb);
ZFS_LOG(1, "%s", sbuf_data(&sb));
devctl_notify("ZFS", spa->spa_name, class, sbuf_data(&sb));
- if (sbuf_overflowed(&sb))
+ if (error != 0)
printf("ZFS WARNING: sbuf overflowed\n");
sbuf_delete(&sb);
#endif
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index b6de86a3c012..07a281e2926e 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -2220,7 +2220,7 @@ again:
addrs++;
}
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
if (addrs == 0) {
@@ -2228,7 +2228,7 @@ again:
sbuf_bcat(sb, &ifr, sizeof(ifr));
max_len += sizeof(ifr);
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
}
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index f54d59e59f2b..d315ff1a4016 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -3093,7 +3093,7 @@ expand_name(const char *name, uid_t uid, pid_t pid, struct thread *td,
sbuf_printf(&sb, GZ_SUFFIX);
}
#endif
- if (sbuf_overflowed(&sb)) {
+ if (sbuf_error(&sb) != 0) {
log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too "
"long\n", (long)pid, name, (u_long)uid);
nomem:
diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c
index 58964fb1d85e..4535337486ba 100644
--- a/sys/kern/subr_sbuf.c
+++ b/sys/kern/subr_sbuf.c
@@ -66,7 +66,6 @@ static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
#define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & SBUF_DYNSTRUCT)
#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
-#define SBUF_HASOVERFLOWED(s) ((s)->s_flags & SBUF_OVERFLOWED)
#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
#define SBUF_FREESPACE(s) ((s)->s_size - (s)->s_len - 1)
#define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND)
@@ -247,7 +246,6 @@ sbuf_clear(struct sbuf *s)
/* don't care if it's finished or not */
SBUF_CLEARFLAG(s, SBUF_FINISHED);
- SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
s->s_error = 0;
s->s_len = 0;
}
@@ -299,10 +297,10 @@ sbuf_drain(struct sbuf *s)
int len;
KASSERT(s->s_len > 0, ("Shouldn't drain empty sbuf %p", s));
+ KASSERT(s->s_error == 0, ("Called %s with error on %p", __func__, s));
len = s->s_drain_func(s->s_drain_arg, s->s_buf, s->s_len);
if (len < 0) {
s->s_error = -len;
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
return (s->s_error);
}
KASSERT(len > 0 && len <= s->s_len,
@@ -334,7 +332,7 @@ sbuf_put_byte(int c, struct sbuf *s)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return;
if (SBUF_FREESPACE(s) <= 0) {
/*
@@ -344,8 +342,8 @@ sbuf_put_byte(int c, struct sbuf *s)
if (s->s_drain_func != NULL)
(void)sbuf_drain(s);
else if (sbuf_extend(s, 1) < 0)
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
- if (SBUF_HASOVERFLOWED(s))
+ s->s_error = ENOMEM;
+ if (s->s_error != 0)
return;
}
s->s_buf[s->s_len++] = c;
@@ -375,11 +373,11 @@ sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
for (; str < end; str++) {
sbuf_put_byte(*str, s);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
}
return (0);
@@ -398,7 +396,7 @@ sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
KASSERT(s->s_drain_func == NULL,
("Nonsensical copyin to sbuf %p with a drain", s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
if (len == 0)
return (0);
@@ -439,12 +437,12 @@ sbuf_cat(struct sbuf *s, const char *str)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
while (*str != '\0') {
sbuf_put_byte(*str, s);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
}
return (0);
@@ -464,7 +462,7 @@ sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
KASSERT(s->s_drain_func == NULL,
("Nonsensical copyin to sbuf %p with a drain", s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
if (len == 0)
@@ -476,7 +474,7 @@ sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
}
switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
case ENAMETOOLONG:
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
+ s->s_error = ENOMEM;
/* fall through */
case 0:
s->s_len += done - 1;
@@ -518,7 +516,7 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
("%s called with a NULL format string", __func__));
(void)kvprintf(fmt, sbuf_putc_func, s, 10, ap);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (0);
}
@@ -535,7 +533,7 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
KASSERT(fmt != NULL,
("%s called with a NULL format string", __func__));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
/*
@@ -578,12 +576,12 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
len = SBUF_FREESPACE(s);
s->s_len += len;
if (!SBUF_HASROOM(s) && !SBUF_CANEXTEND(s))
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
+ s->s_error = ENOMEM;
KASSERT(s->s_len < s->s_size,
("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (0);
}
@@ -612,7 +610,7 @@ sbuf_putc(struct sbuf *s, int c)
{
sbuf_putc_func(c, s);
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (0);
}
@@ -629,7 +627,7 @@ sbuf_trim(struct sbuf *s)
KASSERT(s->s_drain_func == NULL,
("%s makes no sense on sbuf %p with drain", __func__, s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1]))
@@ -639,13 +637,13 @@ sbuf_trim(struct sbuf *s)
}
/*
- * Check if an sbuf overflowed
+ * Check if an sbuf has an error.
*/
int
-sbuf_overflowed(struct sbuf *s)
+sbuf_error(struct sbuf *s)
{
- return (SBUF_HASOVERFLOWED(s));
+ return (s->s_error);
}
/*
@@ -654,19 +652,18 @@ sbuf_overflowed(struct sbuf *s)
int
sbuf_finish(struct sbuf *s)
{
- int error = 0;
+ int error;
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
+ error = s->s_error;
if (s->s_drain_func != NULL) {
- error = s->s_error;
while (s->s_len > 0 && error == 0)
error = sbuf_drain(s);
- } else if (SBUF_HASOVERFLOWED(s))
- error = ENOMEM;
+ }
s->s_buf[s->s_len] = '\0';
- SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
+ s->s_error = 0;
SBUF_SETFLAG(s, SBUF_FINISHED);
#ifdef _KERNEL
return (error);
@@ -703,7 +700,7 @@ sbuf_len(struct sbuf *s)
KASSERT(s->s_drain_func == NULL,
("%s makes no sense on sbuf %p with drain", __func__, s));
- if (SBUF_HASOVERFLOWED(s))
+ if (s->s_error != 0)
return (-1);
return (s->s_len);
}
diff --git a/sys/net/if.c b/sys/net/if.c
index c387dbf498fe..bd54acf28c22 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2726,7 +2726,7 @@ again:
max_len += sa->sa_len;
}
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
IF_ADDR_UNLOCK(ifp);
@@ -2735,7 +2735,7 @@ again:
sbuf_bcat(sb, &ifr, sizeof(ifr));
max_len += sizeof(ifr);
- if (!sbuf_overflowed(sb))
+ if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
}
diff --git a/sys/security/audit/audit_bsm_klib.c b/sys/security/audit/audit_bsm_klib.c
index c8d40356cfe8..f26f86cabc94 100644
--- a/sys/security/audit/audit_bsm_klib.c
+++ b/sys/security/audit/audit_bsm_klib.c
@@ -548,7 +548,7 @@ audit_canon_path(struct thread *td, char *path, char *cpath)
* the supplied buffer being overflowed. Check to see if this is the
* case.
*/
- if (sbuf_overflowed(&sbf) != 0) {
+ if (sbuf_error(&sbf) != 0) {
cpath[0] = '\0';
return;
}
diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h
index be3d80c52406..eeb38140da52 100644
--- a/sys/sys/sbuf.h
+++ b/sys/sys/sbuf.h
@@ -51,7 +51,6 @@ struct sbuf {
#define SBUF_USRFLAGMSK 0x0000ffff /* mask of flags the user may specify */
#define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
#define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
-#define SBUF_OVERFLOWED 0x00040000 /* sbuf overflowed */
#define SBUF_DYNSTRUCT 0x00080000 /* sbuf must be freed */
int s_flags; /* flags */
};
@@ -76,7 +75,7 @@ int sbuf_vprintf(struct sbuf *, const char *, __va_list)
int sbuf_putc(struct sbuf *, int);
void sbuf_set_drain(struct sbuf *, sbuf_drain_func *, void *);
int sbuf_trim(struct sbuf *);
-int sbuf_overflowed(struct sbuf *);
+int sbuf_error(struct sbuf *);
int sbuf_finish(struct sbuf *);
char *sbuf_data(struct sbuf *);
int sbuf_len(struct sbuf *);