Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108954692
D8536.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D8536.id.diff
View Options
Index: head/share/man/man9/sbuf.9
===================================================================
--- head/share/man/man9/sbuf.9
+++ head/share/man/man9/sbuf.9
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 5, 2017
+.Dd August 17, 2017
.Dt SBUF 9
.Os
.Sh NAME
@@ -271,6 +271,14 @@
as resources allow, to hold additional data.
.It Dv SBUF_INCLUDENUL
This causes the final nulterm byte to be counted in the length of the data.
+.It Dv SBUF_DRAINTOEOR
+Treat top-level sections started with
+.Fn sbuf_start_section
+as a record boundary marker that will be used during drain operations to avoid
+records being split.
+If a record grows sufficiently large such that it fills the
+.Fa sbuf
+and therefore cannot be drained without being split, an error of EDEADLK is set.
.El
.Pp
Note that if
Index: head/sys/kern/subr_sbuf.c
===================================================================
--- head/sys/kern/subr_sbuf.c
+++ head/sys/kern/subr_sbuf.c
@@ -73,6 +73,8 @@
#define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND)
#define SBUF_ISSECTION(s) ((s)->s_flags & SBUF_INSECTION)
#define SBUF_NULINCLUDED(s) ((s)->s_flags & SBUF_INCLUDENUL)
+#define SBUF_ISDRAINTOEOR(s) ((s)->s_flags & SBUF_DRAINTOEOR)
+#define SBUF_DODRAINTOEOR(s) (SBUF_ISSECTION(s) && SBUF_ISDRAINTOEOR(s))
/*
* Set / clear flags
@@ -308,6 +310,7 @@
SBUF_CLEARFLAG(s, SBUF_FINISHED);
s->s_error = 0;
s->s_len = 0;
+ s->s_rec_off = 0;
s->s_sect_len = 0;
}
@@ -362,7 +365,10 @@
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 (SBUF_DODRAINTOEOR(s) && s->s_rec_off == 0)
+ return (s->s_error = EDEADLK);
+ len = s->s_drain_func(s->s_drain_arg, s->s_buf,
+ SBUF_DODRAINTOEOR(s) ? s->s_rec_off : s->s_len);
if (len < 0) {
s->s_error = -len;
return (s->s_error);
@@ -370,6 +376,7 @@
KASSERT(len > 0 && len <= s->s_len,
("Bad drain amount %d for sbuf %p", len, s));
s->s_len -= len;
+ s->s_rec_off -= len;
/*
* Fast path for the expected case where all the data was
* drained.
@@ -835,6 +842,7 @@
("s_sect_len != 0 when starting a section"));
if (old_lenp != NULL)
*old_lenp = -1;
+ s->s_rec_off = s->s_len;
SBUF_SETFLAG(s, SBUF_INSECTION);
} else {
KASSERT(old_lenp != NULL,
@@ -865,7 +873,7 @@
}
len = s->s_sect_len;
if (old_len == -1) {
- s->s_sect_len = 0;
+ s->s_rec_off = s->s_sect_len = 0;
SBUF_CLEARFLAG(s, SBUF_INSECTION);
} else {
s->s_sect_len += old_len;
Index: head/sys/sys/sbuf.h
===================================================================
--- head/sys/sys/sbuf.h
+++ head/sys/sys/sbuf.h
@@ -49,6 +49,7 @@
#define SBUF_FIXEDLEN 0x00000000 /* fixed length buffer (default) */
#define SBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */
#define SBUF_INCLUDENUL 0x00000002 /* nulterm byte is counted in len */
+#define SBUF_DRAINTOEOR 0x00000004 /* use section 0 as drain EOR marker */
#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() */
@@ -56,6 +57,7 @@
#define SBUF_INSECTION 0x00100000 /* set by sbuf_start_section() */
int s_flags; /* flags */
ssize_t s_sect_len; /* current length of section */
+ ssize_t s_rec_off; /* current record start offset */
};
#ifndef HD_COLUMN_MASK
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 30, 10:53 PM (4 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16347456
Default Alt Text
D8536.id.diff (3 KB)
Attached To
Mode
D8536: Implement simple record boundary tracking in sbuf(9)
Attached
Detach File
Event Timeline
Log In to Comment