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