1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 22eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw #include <sys/types.h> 27da6c28aaSamw #include <sys/sunddi.h> 28da6c28aaSamw #include <sys/kmem.h> 29da6c28aaSamw #include <sys/sysmacros.h> 30*bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h> 31da6c28aaSamw #include <smbsrv/alloc.h> 32da6c28aaSamw 33da6c28aaSamw #define MEM_HDR_SIZE 8 34*bbf6f00cSJordan Brown static uint32_t smb_memsize(void *); 35da6c28aaSamw 36da6c28aaSamw void * 37*bbf6f00cSJordan Brown smb_malloc(uint32_t size) 38da6c28aaSamw { 39*bbf6f00cSJordan Brown uint32_t *hdr; 40da6c28aaSamw uint8_t *p; 41da6c28aaSamw 42da6c28aaSamw size += MEM_HDR_SIZE; 43*bbf6f00cSJordan Brown hdr = kmem_zalloc(size, KM_SLEEP); 44*bbf6f00cSJordan Brown *hdr = size; 45*bbf6f00cSJordan Brown 46*bbf6f00cSJordan Brown p = (uint8_t *)hdr; 47da6c28aaSamw p += MEM_HDR_SIZE; 48da6c28aaSamw return (p); 49da6c28aaSamw } 50da6c28aaSamw 51da6c28aaSamw char * 52*bbf6f00cSJordan Brown smb_strdup(const char *ptr) 53da6c28aaSamw { 54da6c28aaSamw char *p; 55da6c28aaSamw size_t size; 56da6c28aaSamw 57da6c28aaSamw size = strlen(ptr) + 1; 58*bbf6f00cSJordan Brown p = smb_malloc(size); 59da6c28aaSamw (void) memcpy(p, ptr, size); 60da6c28aaSamw return (p); 61da6c28aaSamw } 62da6c28aaSamw 63da6c28aaSamw static uint32_t 64*bbf6f00cSJordan Brown smb_memsize(void *ptr) 65da6c28aaSamw { 66da6c28aaSamw uint32_t *p; 67da6c28aaSamw 68da6c28aaSamw /*LINTED E_BAD_PTR_CAST_ALIGN*/ 69da6c28aaSamw p = (uint32_t *)((uint8_t *)ptr - MEM_HDR_SIZE); 70da6c28aaSamw 71da6c28aaSamw return (*p); 72da6c28aaSamw } 73da6c28aaSamw 74da6c28aaSamw void * 75*bbf6f00cSJordan Brown smb_realloc(void *ptr, uint32_t size) 76da6c28aaSamw { 77da6c28aaSamw void *new_ptr; 78eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States uint32_t current_size; 79eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 80da6c28aaSamw 81da6c28aaSamw if (ptr == NULL) 82*bbf6f00cSJordan Brown return (smb_malloc(size)); 83da6c28aaSamw 84da6c28aaSamw if (size == 0) { 85*bbf6f00cSJordan Brown smb_mfree(ptr); 86da6c28aaSamw return (NULL); 87da6c28aaSamw } 88da6c28aaSamw 89*bbf6f00cSJordan Brown current_size = smb_memsize(ptr) - MEM_HDR_SIZE; 90eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States if (size <= current_size) 91eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States return (ptr); 92eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 93*bbf6f00cSJordan Brown new_ptr = smb_malloc(size); 94eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States (void) memcpy(new_ptr, ptr, current_size); 95*bbf6f00cSJordan Brown smb_mfree(ptr); 96da6c28aaSamw 97da6c28aaSamw return (new_ptr); 98da6c28aaSamw } 99da6c28aaSamw 100da6c28aaSamw void 101*bbf6f00cSJordan Brown smb_mfree(void *ptr) 102da6c28aaSamw { 103da6c28aaSamw uint8_t *p; 104da6c28aaSamw 105*bbf6f00cSJordan Brown if (ptr == NULL) 106da6c28aaSamw return; 107da6c28aaSamw 108da6c28aaSamw p = (uint8_t *)ptr - MEM_HDR_SIZE; 109da6c28aaSamw /*LINTED E_BAD_PTR_CAST_ALIGN*/ 110da6c28aaSamw kmem_free(p, *(uint32_t *)p); 111da6c28aaSamw } 112*bbf6f00cSJordan Brown 113*bbf6f00cSJordan Brown /* 114*bbf6f00cSJordan Brown * Initialize the list for request-specific temporary storage. 115*bbf6f00cSJordan Brown */ 116*bbf6f00cSJordan Brown void 117*bbf6f00cSJordan Brown smb_srm_init(smb_request_t *sr) 118*bbf6f00cSJordan Brown { 119*bbf6f00cSJordan Brown list_create(&sr->sr_storage, sizeof (smb_srm_t), 120*bbf6f00cSJordan Brown offsetof(smb_srm_t, srm_lnd)); 121*bbf6f00cSJordan Brown } 122*bbf6f00cSJordan Brown 123*bbf6f00cSJordan Brown /* 124*bbf6f00cSJordan Brown * Free everything on the request-specific temporary storage list 125*bbf6f00cSJordan Brown * and destroy the list. 126*bbf6f00cSJordan Brown */ 127*bbf6f00cSJordan Brown void 128*bbf6f00cSJordan Brown smb_srm_fini(smb_request_t *sr) 129*bbf6f00cSJordan Brown { 130*bbf6f00cSJordan Brown smb_srm_t *srm; 131*bbf6f00cSJordan Brown 132*bbf6f00cSJordan Brown while ((srm = list_head(&sr->sr_storage)) != NULL) { 133*bbf6f00cSJordan Brown list_remove(&sr->sr_storage, srm); 134*bbf6f00cSJordan Brown smb_mfree(srm); 135*bbf6f00cSJordan Brown } 136*bbf6f00cSJordan Brown 137*bbf6f00cSJordan Brown list_destroy(&sr->sr_storage); 138*bbf6f00cSJordan Brown } 139*bbf6f00cSJordan Brown 140*bbf6f00cSJordan Brown /* 141*bbf6f00cSJordan Brown * Allocate memory and associate it with the specified request. 142*bbf6f00cSJordan Brown * Memory allocated here can only be used for the duration of 143*bbf6f00cSJordan Brown * this request; it will be freed automatically on completion 144*bbf6f00cSJordan Brown * of the request 145*bbf6f00cSJordan Brown */ 146*bbf6f00cSJordan Brown void * 147*bbf6f00cSJordan Brown smb_srm_alloc(smb_request_t *sr, size_t size) 148*bbf6f00cSJordan Brown { 149*bbf6f00cSJordan Brown smb_srm_t *srm; 150*bbf6f00cSJordan Brown 151*bbf6f00cSJordan Brown size += sizeof (smb_srm_t); 152*bbf6f00cSJordan Brown srm = smb_malloc(size); 153*bbf6f00cSJordan Brown srm->srm_size = size; 154*bbf6f00cSJordan Brown srm->srm_sr = sr; 155*bbf6f00cSJordan Brown list_insert_tail(&sr->sr_storage, srm); 156*bbf6f00cSJordan Brown 157*bbf6f00cSJordan Brown /* 158*bbf6f00cSJordan Brown * The memory allocated for use be the caller is 159*bbf6f00cSJordan Brown * immediately after our storage context area. 160*bbf6f00cSJordan Brown */ 161*bbf6f00cSJordan Brown return (void *)(srm + 1); 162*bbf6f00cSJordan Brown } 163*bbf6f00cSJordan Brown 164*bbf6f00cSJordan Brown /* 165*bbf6f00cSJordan Brown * Allocate or resize memory previously allocated for the specified 166*bbf6f00cSJordan Brown * request. 167*bbf6f00cSJordan Brown */ 168*bbf6f00cSJordan Brown void * 169*bbf6f00cSJordan Brown smb_srm_realloc(smb_request_t *sr, void *p, size_t size) 170*bbf6f00cSJordan Brown { 171*bbf6f00cSJordan Brown smb_srm_t *old_srm = (smb_srm_t *)p; 172*bbf6f00cSJordan Brown smb_srm_t *new_srm; 173*bbf6f00cSJordan Brown 174*bbf6f00cSJordan Brown if (old_srm == NULL) 175*bbf6f00cSJordan Brown return (smb_srm_alloc(sr, size)); 176*bbf6f00cSJordan Brown 177*bbf6f00cSJordan Brown old_srm--; 178*bbf6f00cSJordan Brown list_remove(&sr->sr_storage, old_srm); 179*bbf6f00cSJordan Brown 180*bbf6f00cSJordan Brown size += sizeof (smb_srm_t); 181*bbf6f00cSJordan Brown new_srm = smb_realloc(old_srm, size); 182*bbf6f00cSJordan Brown new_srm->srm_size = smb_memsize(new_srm); 183*bbf6f00cSJordan Brown new_srm->srm_sr = sr; 184*bbf6f00cSJordan Brown list_insert_tail(&sr->sr_storage, new_srm); 185*bbf6f00cSJordan Brown 186*bbf6f00cSJordan Brown /* 187*bbf6f00cSJordan Brown * The memory allocated for use be the caller is 188*bbf6f00cSJordan Brown * immediately after our storage context area. 189*bbf6f00cSJordan Brown */ 190*bbf6f00cSJordan Brown return (void *)(new_srm + 1); 191*bbf6f00cSJordan Brown } 192