xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_alloc.c (revision bbf6f00c25b6a2bed23c35eac6d62998ecdb338c)
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