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