1*f82c7503SGordon Ross /*
2*f82c7503SGordon Ross * This file and its contents are supplied under the terms of the
3*f82c7503SGordon Ross * Common Development and Distribution License ("CDDL"), version 1.0.
4*f82c7503SGordon Ross * You may only use this file in accordance with the terms of version
5*f82c7503SGordon Ross * 1.0 of the CDDL.
6*f82c7503SGordon Ross *
7*f82c7503SGordon Ross * A full copy of the text of the CDDL should have accompanied this
8*f82c7503SGordon Ross * source. A copy of the CDDL is also available via the Internet at
9*f82c7503SGordon Ross * http://www.illumos.org/license/CDDL.
10*f82c7503SGordon Ross */
11*f82c7503SGordon Ross
12*f82c7503SGordon Ross /*
13*f82c7503SGordon Ross * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
14*f82c7503SGordon Ross */
15*f82c7503SGordon Ross
16*f82c7503SGordon Ross /*
17*f82c7503SGordon Ross * Some minimal streams mblk_t management functions needed by
18*f82c7503SGordon Ross * ksocket_sendmblk: esballoca(), freemsg(), ...
19*f82c7503SGordon Ross */
20*f82c7503SGordon Ross
21*f82c7503SGordon Ross #include <sys/types.h>
22*f82c7503SGordon Ross #include <sys/systm.h>
23*f82c7503SGordon Ross #include <sys/cred.h>
24*f82c7503SGordon Ross #include <sys/errno.h>
25*f82c7503SGordon Ross #include <sys/socket.h>
26*f82c7503SGordon Ross #include <sys/ksocket.h>
27*f82c7503SGordon Ross #include <sys/stream.h>
28*f82c7503SGordon Ross #include <sys/strsubr.h>
29*f82c7503SGordon Ross #include <sys/strsun.h>
30*f82c7503SGordon Ross #include <sys/debug.h>
31*f82c7503SGordon Ross #include <sys/kmem.h>
32*f82c7503SGordon Ross #include <limits.h>
33*f82c7503SGordon Ross #include <unistd.h>
34*f82c7503SGordon Ross #include <errno.h>
35*f82c7503SGordon Ross #include <umem.h>
36*f82c7503SGordon Ross
37*f82c7503SGordon Ross static void
lastfree(mblk_t * mp,dblk_t * db)38*f82c7503SGordon Ross lastfree(mblk_t *mp, dblk_t *db)
39*f82c7503SGordon Ross {
40*f82c7503SGordon Ross frtn_t *frp = db->db_frtnp;
41*f82c7503SGordon Ross
42*f82c7503SGordon Ross ASSERT(db->db_mblk == mp);
43*f82c7503SGordon Ross ASSERT(mp->b_datap == db);
44*f82c7503SGordon Ross
45*f82c7503SGordon Ross ASSERT(frp != NULL);
46*f82c7503SGordon Ross frp->free_func(frp->free_arg);
47*f82c7503SGordon Ross
48*f82c7503SGordon Ross kmem_free(mp, sizeof (*mp));
49*f82c7503SGordon Ross kmem_free(db, sizeof (*db));
50*f82c7503SGordon Ross }
51*f82c7503SGordon Ross
52*f82c7503SGordon Ross
53*f82c7503SGordon Ross mblk_t *
esballoca(unsigned char * base,size_t size,uint_t pri,frtn_t * frp)54*f82c7503SGordon Ross esballoca(unsigned char *base, size_t size, uint_t pri, frtn_t *frp)
55*f82c7503SGordon Ross {
56*f82c7503SGordon Ross dblk_t *db;
57*f82c7503SGordon Ross mblk_t *mp;
58*f82c7503SGordon Ross
59*f82c7503SGordon Ross db = kmem_zalloc(sizeof (*db), KM_SLEEP);
60*f82c7503SGordon Ross mp = kmem_zalloc(sizeof (*mp), KM_SLEEP);
61*f82c7503SGordon Ross
62*f82c7503SGordon Ross mp->b_datap = db;
63*f82c7503SGordon Ross db->db_mblk = mp;
64*f82c7503SGordon Ross
65*f82c7503SGordon Ross db->db_base = base;
66*f82c7503SGordon Ross db->db_lim = base + size;
67*f82c7503SGordon Ross db->db_free = db->db_lastfree = lastfree;
68*f82c7503SGordon Ross db->db_frtnp = frp;
69*f82c7503SGordon Ross
70*f82c7503SGordon Ross /*
71*f82c7503SGordon Ross * streams.c uses these weird macro:
72*f82c7503SGordon Ross * DBLK_RTFU_WORD(dbp) = db_rtfu
73*f82c7503SGordon Ross * where db_rtfu = DBLK_RTFU(1, M_DATA, 0, 0)
74*f82c7503SGordon Ross * Probably only care about db_ref
75*f82c7503SGordon Ross */
76*f82c7503SGordon Ross db->db_ref = 1;
77*f82c7503SGordon Ross
78*f82c7503SGordon Ross mp->b_next = mp->b_prev = mp->b_cont = NULL;
79*f82c7503SGordon Ross mp->b_rptr = mp->b_wptr = base;
80*f82c7503SGordon Ross mp->b_queue = NULL;
81*f82c7503SGordon Ross
82*f82c7503SGordon Ross return (mp);
83*f82c7503SGordon Ross }
84*f82c7503SGordon Ross
85*f82c7503SGordon Ross /*
86*f82c7503SGordon Ross * Same as esballoca() but sleeps waiting for memory.
87*f82c7503SGordon Ross * (in here, both sleep)
88*f82c7503SGordon Ross */
89*f82c7503SGordon Ross mblk_t *
esballoca_wait(unsigned char * base,size_t size,uint_t pri,frtn_t * frp)90*f82c7503SGordon Ross esballoca_wait(unsigned char *base, size_t size, uint_t pri, frtn_t *frp)
91*f82c7503SGordon Ross {
92*f82c7503SGordon Ross return (esballoca(base, size, pri, frp));
93*f82c7503SGordon Ross }
94*f82c7503SGordon Ross
95*f82c7503SGordon Ross void
freemsg(mblk_t * mp)96*f82c7503SGordon Ross freemsg(mblk_t *mp)
97*f82c7503SGordon Ross {
98*f82c7503SGordon Ross mblk_t *mp_cont;
99*f82c7503SGordon Ross dblk_t *db;
100*f82c7503SGordon Ross
101*f82c7503SGordon Ross while (mp) {
102*f82c7503SGordon Ross db = mp->b_datap;
103*f82c7503SGordon Ross mp_cont = mp->b_cont;
104*f82c7503SGordon Ross
105*f82c7503SGordon Ross ASSERT(db->db_ref > 0);
106*f82c7503SGordon Ross ASSERT(mp->b_next == NULL && mp->b_prev == NULL);
107*f82c7503SGordon Ross
108*f82c7503SGordon Ross db->db_free(mp, db);
109*f82c7503SGordon Ross mp = mp_cont;
110*f82c7503SGordon Ross }
111*f82c7503SGordon Ross }
112