Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102832053
D38946.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D38946.diff
View Options
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -70,11 +70,31 @@
#define NL_ARRAY_LEN(_a) (sizeof(_a) / sizeof((_a)[0]))
struct linear_buffer {
- char *base; /* Base allocated memory pointer */
- uint32_t offset; /* Currently used offset */
- uint32_t size; /* Total buffer size */
+ char *base; /* Base allocated memory pointer */
+ uint32_t offset; /* Currently used offset */
+ uint32_t size; /* Total buffer size */
+ struct linear_buffer *next; /* Buffer chaining */
};
+static inline struct linear_buffer *
+lb_init(uint32_t size)
+{
+ struct linear_buffer *lb = calloc(1, size);
+
+ if (lb != NULL) {
+ lb->base = (char *)(lb + 1);
+ lb->size = size - sizeof(*lb);
+ }
+
+ return (lb);
+}
+
+static inline void
+lb_free(struct linear_buffer *lb)
+{
+ free(lb);
+}
+
static inline char *
lb_allocz(struct linear_buffer *lb, int len)
{
@@ -101,7 +121,7 @@
size_t datalen;
uint32_t seq;
bool init_done;
- struct linear_buffer lb;
+ struct linear_buffer *lb;
};
#define SCRATCH_BUFFER_SIZE 1024
@@ -145,6 +165,45 @@
}
+static inline void *
+snl_allocz(struct snl_state *ss, int len)
+{
+ void *data = lb_allocz(ss->lb, len);
+
+ if (data == NULL) {
+ uint32_t size = ss->lb->size * 2;
+
+ while (size < len + sizeof(struct linear_buffer))
+ size *= 2;
+
+ struct linear_buffer *lb = lb_init(size);
+
+ if (lb != NULL) {
+ lb->next = ss->lb;
+ ss->lb = lb;
+ data = lb_allocz(ss->lb, len);
+ }
+ }
+
+ return (data);
+}
+
+static inline void
+snl_clear_lb(struct snl_state *ss)
+{
+ struct linear_buffer *lb = ss->lb;
+
+ lb_clear(lb);
+ lb = lb->next;
+ ss->lb->next = NULL;
+ /* Remove all linear bufs except the largest one */
+ while (lb != NULL) {
+ struct linear_buffer *lb_next = lb->next;
+ lb_free(lb);
+ lb = lb_next;
+ }
+}
+
static void
snl_free(struct snl_state *ss)
{
@@ -152,8 +211,10 @@
close(ss->fd);
if (ss->buf != NULL)
free(ss->buf);
- if (ss->lb.base != NULL)
- free(ss->lb.base);
+ if (ss->lb != NULL) {
+ snl_clear_lb(ss);
+ lb_free(ss->lb);
+ }
}
}
@@ -181,9 +242,8 @@
return (false);
}
- ss->lb.size = SCRATCH_BUFFER_SIZE;
- ss->lb.base = calloc(1, ss->lb.size);
- if (ss->lb.base == NULL) {
+ ss->lb = lb_init(SCRATCH_BUFFER_SIZE);
+ if (ss->lb == NULL) {
snl_free(ss);
return (false);
}
@@ -191,18 +251,6 @@
return (true);
}
-static inline void *
-snl_allocz(struct snl_state *ss, int len)
-{
- return (lb_allocz(&ss->lb, len));
-}
-
-static inline void
-snl_clear_lb(struct snl_state *ss)
-{
- lb_clear(&ss->lb);
-}
-
static inline bool
snl_send(struct snl_state *ss, void *data, int sz)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 18, 6:16 PM (21 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14702431
Default Alt Text
D38946.diff (2 KB)
Attached To
Mode
D38946: netlink: make snl(3) scratch buffer growable
Attached
Detach File
Event Timeline
Log In to Comment