1b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
2b89a8333Snatalie li - Sun Microsystems - Irvine United States * CDDL HEADER START
3b89a8333Snatalie li - Sun Microsystems - Irvine United States *
4b89a8333Snatalie li - Sun Microsystems - Irvine United States * The contents of this file are subject to the terms of the
5b89a8333Snatalie li - Sun Microsystems - Irvine United States * Common Development and Distribution License (the "License").
6b89a8333Snatalie li - Sun Microsystems - Irvine United States * You may not use this file except in compliance with the License.
7b89a8333Snatalie li - Sun Microsystems - Irvine United States *
8b89a8333Snatalie li - Sun Microsystems - Irvine United States * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9b89a8333Snatalie li - Sun Microsystems - Irvine United States * or http://www.opensolaris.org/os/licensing.
10b89a8333Snatalie li - Sun Microsystems - Irvine United States * See the License for the specific language governing permissions
11b89a8333Snatalie li - Sun Microsystems - Irvine United States * and limitations under the License.
12b89a8333Snatalie li - Sun Microsystems - Irvine United States *
13b89a8333Snatalie li - Sun Microsystems - Irvine United States * When distributing Covered Code, include this CDDL HEADER in each
14b89a8333Snatalie li - Sun Microsystems - Irvine United States * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15b89a8333Snatalie li - Sun Microsystems - Irvine United States * If applicable, add the following below this CDDL HEADER, with the
16b89a8333Snatalie li - Sun Microsystems - Irvine United States * fields enclosed by brackets "[]" replaced with your own identifying
17b89a8333Snatalie li - Sun Microsystems - Irvine United States * information: Portions Copyright [yyyy] [name of copyright owner]
18b89a8333Snatalie li - Sun Microsystems - Irvine United States *
19b89a8333Snatalie li - Sun Microsystems - Irvine United States * CDDL HEADER END
20b89a8333Snatalie li - Sun Microsystems - Irvine United States */
21b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
22*593cc11bSJan Kryl * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23b89a8333Snatalie li - Sun Microsystems - Irvine United States * Use is subject to license terms.
24b89a8333Snatalie li - Sun Microsystems - Irvine United States */
25b89a8333Snatalie li - Sun Microsystems - Irvine United States
26b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/param.h>
27b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/types.h>
28b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/pathname.h>
29b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/errno.h>
30b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/cmn_err.h>
31b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/debug.h>
32b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/systm.h>
33b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/unistd.h>
34b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/door.h>
35b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/socket.h>
36b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <nfs/export.h>
37b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <nfs/nfs_cmd.h>
38b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/kmem.h>
39b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <sys/sunddi.h>
40b89a8333Snatalie li - Sun Microsystems - Irvine United States
41b89a8333Snatalie li - Sun Microsystems - Irvine United States #define NFSCMD_DR_TRYCNT 8
42b89a8333Snatalie li - Sun Microsystems - Irvine United States
43b89a8333Snatalie li - Sun Microsystems - Irvine United States #ifdef nextdp
44b89a8333Snatalie li - Sun Microsystems - Irvine United States #undef nextdp
45b89a8333Snatalie li - Sun Microsystems - Irvine United States #endif
46b89a8333Snatalie li - Sun Microsystems - Irvine United States #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
47b89a8333Snatalie li - Sun Microsystems - Irvine United States
48b89a8333Snatalie li - Sun Microsystems - Irvine United States kmutex_t nfscmd_lock;
49b89a8333Snatalie li - Sun Microsystems - Irvine United States door_handle_t nfscmd_dh;
50b89a8333Snatalie li - Sun Microsystems - Irvine United States
51*593cc11bSJan Kryl static struct charset_cache *nfscmd_charmap(exportinfo_t *exi,
52*593cc11bSJan Kryl struct sockaddr *sp);
53*593cc11bSJan Kryl
54*593cc11bSJan Kryl
55b89a8333Snatalie li - Sun Microsystems - Irvine United States void
nfscmd_args(uint_t did)56b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_args(uint_t did)
57b89a8333Snatalie li - Sun Microsystems - Irvine United States {
58b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_enter(&nfscmd_lock);
59b89a8333Snatalie li - Sun Microsystems - Irvine United States if (nfscmd_dh)
60b89a8333Snatalie li - Sun Microsystems - Irvine United States door_ki_rele(nfscmd_dh);
61b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_dh = door_ki_lookup(did);
62b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_exit(&nfscmd_lock);
63b89a8333Snatalie li - Sun Microsystems - Irvine United States }
64b89a8333Snatalie li - Sun Microsystems - Irvine United States
65b89a8333Snatalie li - Sun Microsystems - Irvine United States void
nfscmd_init(void)66b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_init(void)
67b89a8333Snatalie li - Sun Microsystems - Irvine United States {
68b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_init(&nfscmd_lock, NULL, MUTEX_DEFAULT, NULL);
69b89a8333Snatalie li - Sun Microsystems - Irvine United States }
70b89a8333Snatalie li - Sun Microsystems - Irvine United States
71b89a8333Snatalie li - Sun Microsystems - Irvine United States void
nfscmd_fini(void)72b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_fini(void)
73b89a8333Snatalie li - Sun Microsystems - Irvine United States {
74b89a8333Snatalie li - Sun Microsystems - Irvine United States }
75b89a8333Snatalie li - Sun Microsystems - Irvine United States
76b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
77b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_send(arg, result)
78b89a8333Snatalie li - Sun Microsystems - Irvine United States *
79*593cc11bSJan Kryl * Send a command to the daemon listening on the door. The result is
80*593cc11bSJan Kryl * returned in the result pointer if the function return value is
81*593cc11bSJan Kryl * NFSCMD_ERR_SUCCESS. Otherwise it is the error value.
82b89a8333Snatalie li - Sun Microsystems - Irvine United States */
83b89a8333Snatalie li - Sun Microsystems - Irvine United States int
nfscmd_send(nfscmd_arg_t * arg,nfscmd_res_t * res)84b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_send(nfscmd_arg_t *arg, nfscmd_res_t *res)
85b89a8333Snatalie li - Sun Microsystems - Irvine United States {
86b89a8333Snatalie li - Sun Microsystems - Irvine United States door_handle_t dh;
87b89a8333Snatalie li - Sun Microsystems - Irvine United States door_arg_t da;
88b89a8333Snatalie li - Sun Microsystems - Irvine United States door_info_t di;
89b89a8333Snatalie li - Sun Microsystems - Irvine United States int ntries = 0;
90b89a8333Snatalie li - Sun Microsystems - Irvine United States int last = 0;
91b89a8333Snatalie li - Sun Microsystems - Irvine United States
92b89a8333Snatalie li - Sun Microsystems - Irvine United States retry:
93b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_enter(&nfscmd_lock);
94b89a8333Snatalie li - Sun Microsystems - Irvine United States dh = nfscmd_dh;
95b89a8333Snatalie li - Sun Microsystems - Irvine United States if (dh != NULL)
96b89a8333Snatalie li - Sun Microsystems - Irvine United States door_ki_hold(dh);
97b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_exit(&nfscmd_lock);
98b89a8333Snatalie li - Sun Microsystems - Irvine United States
99b89a8333Snatalie li - Sun Microsystems - Irvine United States if (dh == NULL) {
100b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
101b89a8333Snatalie li - Sun Microsystems - Irvine United States * The rendezvous point has not been established yet !
102b89a8333Snatalie li - Sun Microsystems - Irvine United States * This could mean that either mountd(1m) has not yet
103b89a8333Snatalie li - Sun Microsystems - Irvine United States * been started or that _this_ routine nuked the door
104b89a8333Snatalie li - Sun Microsystems - Irvine United States * handle after receiving an EINTR for a REVOKED door.
105b89a8333Snatalie li - Sun Microsystems - Irvine United States *
106b89a8333Snatalie li - Sun Microsystems - Irvine United States * Returning NFSAUTH_DROP will cause the NFS client
107b89a8333Snatalie li - Sun Microsystems - Irvine United States * to retransmit the request, so let's try to be more
108b89a8333Snatalie li - Sun Microsystems - Irvine United States * rescillient and attempt for ntries before we bail.
109b89a8333Snatalie li - Sun Microsystems - Irvine United States */
110b89a8333Snatalie li - Sun Microsystems - Irvine United States if (++ntries % NFSCMD_DR_TRYCNT) {
111b89a8333Snatalie li - Sun Microsystems - Irvine United States delay(hz);
112b89a8333Snatalie li - Sun Microsystems - Irvine United States goto retry;
113b89a8333Snatalie li - Sun Microsystems - Irvine United States }
114b89a8333Snatalie li - Sun Microsystems - Irvine United States return (NFSCMD_ERR_DROP);
115b89a8333Snatalie li - Sun Microsystems - Irvine United States }
116b89a8333Snatalie li - Sun Microsystems - Irvine United States
117b89a8333Snatalie li - Sun Microsystems - Irvine United States da.data_ptr = (char *)arg;
118b89a8333Snatalie li - Sun Microsystems - Irvine United States da.data_size = sizeof (nfscmd_arg_t);
119b89a8333Snatalie li - Sun Microsystems - Irvine United States da.desc_ptr = NULL;
120b89a8333Snatalie li - Sun Microsystems - Irvine United States da.desc_num = 0;
121b89a8333Snatalie li - Sun Microsystems - Irvine United States da.rbuf = (char *)res;
122b89a8333Snatalie li - Sun Microsystems - Irvine United States da.rsize = sizeof (nfscmd_res_t);
123b89a8333Snatalie li - Sun Microsystems - Irvine United States
124b89a8333Snatalie li - Sun Microsystems - Irvine United States switch (door_ki_upcall(dh, &da)) {
125b89a8333Snatalie li - Sun Microsystems - Irvine United States case 0:
126b89a8333Snatalie li - Sun Microsystems - Irvine United States /* Success */
127b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
128b89a8333Snatalie li - Sun Microsystems - Irvine United States case EAGAIN:
129b89a8333Snatalie li - Sun Microsystems - Irvine United States /* Need to retry a couple of times */
130b89a8333Snatalie li - Sun Microsystems - Irvine United States door_ki_rele(dh);
131b89a8333Snatalie li - Sun Microsystems - Irvine United States delay(hz);
132b89a8333Snatalie li - Sun Microsystems - Irvine United States goto retry;
133b89a8333Snatalie li - Sun Microsystems - Irvine United States /* NOTREACHED */
134b89a8333Snatalie li - Sun Microsystems - Irvine United States case EINTR:
135b89a8333Snatalie li - Sun Microsystems - Irvine United States if (!door_ki_info(dh, &di)) {
136b89a8333Snatalie li - Sun Microsystems - Irvine United States if (di.di_attributes & DOOR_REVOKED) {
137b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
138b89a8333Snatalie li - Sun Microsystems - Irvine United States * The server barfed and revoked
139b89a8333Snatalie li - Sun Microsystems - Irvine United States * the (existing) door on us; we
140b89a8333Snatalie li - Sun Microsystems - Irvine United States * want to wait to give smf(5) a
141b89a8333Snatalie li - Sun Microsystems - Irvine United States * chance to restart mountd(1m)
142b89a8333Snatalie li - Sun Microsystems - Irvine United States * and establish a new door handle.
143b89a8333Snatalie li - Sun Microsystems - Irvine United States */
144b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_enter(&nfscmd_lock);
145b89a8333Snatalie li - Sun Microsystems - Irvine United States if (dh == nfscmd_dh)
146b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_dh = NULL;
147b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_exit(&nfscmd_lock);
148b89a8333Snatalie li - Sun Microsystems - Irvine United States door_ki_rele(dh);
149b89a8333Snatalie li - Sun Microsystems - Irvine United States delay(hz);
150b89a8333Snatalie li - Sun Microsystems - Irvine United States goto retry;
151b89a8333Snatalie li - Sun Microsystems - Irvine United States }
152b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
153b89a8333Snatalie li - Sun Microsystems - Irvine United States * If the door was _not_ revoked on us,
154b89a8333Snatalie li - Sun Microsystems - Irvine United States * then more than likely we took an INTR,
155b89a8333Snatalie li - Sun Microsystems - Irvine United States * so we need to fail the operation.
156b89a8333Snatalie li - Sun Microsystems - Irvine United States */
157b89a8333Snatalie li - Sun Microsystems - Irvine United States door_ki_rele(dh);
158b89a8333Snatalie li - Sun Microsystems - Irvine United States }
159b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
160b89a8333Snatalie li - Sun Microsystems - Irvine United States * The only failure that can occur from getting
161b89a8333Snatalie li - Sun Microsystems - Irvine United States * the door info is EINVAL, so we let the code
162b89a8333Snatalie li - Sun Microsystems - Irvine United States * below handle it.
163b89a8333Snatalie li - Sun Microsystems - Irvine United States */
164b89a8333Snatalie li - Sun Microsystems - Irvine United States /* FALLTHROUGH */
165b89a8333Snatalie li - Sun Microsystems - Irvine United States
166b89a8333Snatalie li - Sun Microsystems - Irvine United States case EBADF:
167b89a8333Snatalie li - Sun Microsystems - Irvine United States case EINVAL:
168b89a8333Snatalie li - Sun Microsystems - Irvine United States default:
169b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
170b89a8333Snatalie li - Sun Microsystems - Irvine United States * If we have a stale door handle, give smf a last
171b89a8333Snatalie li - Sun Microsystems - Irvine United States * chance to start it by sleeping for a little bit.
172b89a8333Snatalie li - Sun Microsystems - Irvine United States * If we're still hosed, we'll fail the call.
173b89a8333Snatalie li - Sun Microsystems - Irvine United States *
174b89a8333Snatalie li - Sun Microsystems - Irvine United States * Since we're going to reacquire the door handle
175b89a8333Snatalie li - Sun Microsystems - Irvine United States * upon the retry, we opt to sleep for a bit and
176b89a8333Snatalie li - Sun Microsystems - Irvine United States * _not_ to clear mountd_dh. If mountd restarted
177b89a8333Snatalie li - Sun Microsystems - Irvine United States * and was able to set mountd_dh, we should see
178b89a8333Snatalie li - Sun Microsystems - Irvine United States * the new instance; if not, we won't get caught
179b89a8333Snatalie li - Sun Microsystems - Irvine United States * up in the retry/DELAY loop.
180b89a8333Snatalie li - Sun Microsystems - Irvine United States */
181b89a8333Snatalie li - Sun Microsystems - Irvine United States door_ki_rele(dh);
182b89a8333Snatalie li - Sun Microsystems - Irvine United States if (!last) {
183b89a8333Snatalie li - Sun Microsystems - Irvine United States delay(hz);
184b89a8333Snatalie li - Sun Microsystems - Irvine United States last++;
185b89a8333Snatalie li - Sun Microsystems - Irvine United States goto retry;
186b89a8333Snatalie li - Sun Microsystems - Irvine United States }
187b89a8333Snatalie li - Sun Microsystems - Irvine United States res->error = NFSCMD_ERR_FAIL;
188b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
189b89a8333Snatalie li - Sun Microsystems - Irvine United States }
190*593cc11bSJan Kryl return (res->error);
191b89a8333Snatalie li - Sun Microsystems - Irvine United States }
192b89a8333Snatalie li - Sun Microsystems - Irvine United States
193b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
194b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_findmap(export, addr)
195b89a8333Snatalie li - Sun Microsystems - Irvine United States *
196*593cc11bSJan Kryl * Find a characterset map for the specified client address.
197*593cc11bSJan Kryl * First try to find a cached entry. If not successful,
198*593cc11bSJan Kryl * ask mountd daemon running in userland.
199*593cc11bSJan Kryl *
200*593cc11bSJan Kryl * For most of the clients this function is NOOP, since
201*593cc11bSJan Kryl * EX_CHARMAP flag won't be set.
202b89a8333Snatalie li - Sun Microsystems - Irvine United States */
203b89a8333Snatalie li - Sun Microsystems - Irvine United States struct charset_cache *
nfscmd_findmap(struct exportinfo * exi,struct sockaddr * sp)204b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_findmap(struct exportinfo *exi, struct sockaddr *sp)
205b89a8333Snatalie li - Sun Microsystems - Irvine United States {
206b89a8333Snatalie li - Sun Microsystems - Irvine United States struct charset_cache *charset;
207b89a8333Snatalie li - Sun Microsystems - Irvine United States
208*593cc11bSJan Kryl /*
209*593cc11bSJan Kryl * In debug kernel we want to know about strayed nulls.
210*593cc11bSJan Kryl * In non-debug kernel we behave gracefully.
211*593cc11bSJan Kryl */
212*593cc11bSJan Kryl ASSERT(exi != NULL);
213*593cc11bSJan Kryl ASSERT(sp != NULL);
214*593cc11bSJan Kryl
215*593cc11bSJan Kryl if (exi == NULL || sp == NULL)
216*593cc11bSJan Kryl return (NULL);
217*593cc11bSJan Kryl
218b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_enter(&exi->exi_lock);
219*593cc11bSJan Kryl
220*593cc11bSJan Kryl if (!(exi->exi_export.ex_flags & EX_CHARMAP)) {
221*593cc11bSJan Kryl mutex_exit(&exi->exi_lock);
222*593cc11bSJan Kryl return (NULL);
223*593cc11bSJan Kryl }
224*593cc11bSJan Kryl
225b89a8333Snatalie li - Sun Microsystems - Irvine United States for (charset = exi->exi_charset;
226b89a8333Snatalie li - Sun Microsystems - Irvine United States charset != NULL;
227b89a8333Snatalie li - Sun Microsystems - Irvine United States charset = charset->next) {
228b89a8333Snatalie li - Sun Microsystems - Irvine United States if (bcmp(sp, &charset->client_addr,
229b89a8333Snatalie li - Sun Microsystems - Irvine United States sizeof (struct sockaddr)) == 0)
230b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
231b89a8333Snatalie li - Sun Microsystems - Irvine United States }
232b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_exit(&exi->exi_lock);
233*593cc11bSJan Kryl
234*593cc11bSJan Kryl /* the slooow way - ask daemon */
235*593cc11bSJan Kryl if (charset == NULL)
236*593cc11bSJan Kryl charset = nfscmd_charmap(exi, sp);
237*593cc11bSJan Kryl
238b89a8333Snatalie li - Sun Microsystems - Irvine United States return (charset);
239b89a8333Snatalie li - Sun Microsystems - Irvine United States }
240b89a8333Snatalie li - Sun Microsystems - Irvine United States
241b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
242b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_insert_charmap(export, addr, name)
243b89a8333Snatalie li - Sun Microsystems - Irvine United States *
244b89a8333Snatalie li - Sun Microsystems - Irvine United States * Insert a new character set conversion map into the export structure
245b89a8333Snatalie li - Sun Microsystems - Irvine United States * for the share. The entry has the IP address of the client and the
246b89a8333Snatalie li - Sun Microsystems - Irvine United States * character set name.
247b89a8333Snatalie li - Sun Microsystems - Irvine United States */
248b89a8333Snatalie li - Sun Microsystems - Irvine United States
249b89a8333Snatalie li - Sun Microsystems - Irvine United States static struct charset_cache *
nfscmd_insert_charmap(struct exportinfo * exi,struct sockaddr * sp,char * name)250b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_insert_charmap(struct exportinfo *exi, struct sockaddr *sp, char *name)
251b89a8333Snatalie li - Sun Microsystems - Irvine United States {
252b89a8333Snatalie li - Sun Microsystems - Irvine United States struct charset_cache *charset;
253b89a8333Snatalie li - Sun Microsystems - Irvine United States
254b89a8333Snatalie li - Sun Microsystems - Irvine United States charset = (struct charset_cache *)
255b89a8333Snatalie li - Sun Microsystems - Irvine United States kmem_zalloc(sizeof (struct charset_cache), KM_SLEEP);
256b89a8333Snatalie li - Sun Microsystems - Irvine United States
257b89a8333Snatalie li - Sun Microsystems - Irvine United States if (charset == NULL)
258b89a8333Snatalie li - Sun Microsystems - Irvine United States return (NULL);
259b89a8333Snatalie li - Sun Microsystems - Irvine United States if (name != NULL) {
260b89a8333Snatalie li - Sun Microsystems - Irvine United States charset->inbound = kiconv_open("UTF-8", name);
261b89a8333Snatalie li - Sun Microsystems - Irvine United States charset->outbound = kiconv_open(name, "UTF-8");
262b89a8333Snatalie li - Sun Microsystems - Irvine United States }
263b89a8333Snatalie li - Sun Microsystems - Irvine United States charset->client_addr = *sp;
264b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_enter(&exi->exi_lock);
265b89a8333Snatalie li - Sun Microsystems - Irvine United States charset->next = exi->exi_charset;
266b89a8333Snatalie li - Sun Microsystems - Irvine United States exi->exi_charset = charset;
267b89a8333Snatalie li - Sun Microsystems - Irvine United States mutex_exit(&exi->exi_lock);
268b89a8333Snatalie li - Sun Microsystems - Irvine United States
269b89a8333Snatalie li - Sun Microsystems - Irvine United States return (charset);
270b89a8333Snatalie li - Sun Microsystems - Irvine United States }
271b89a8333Snatalie li - Sun Microsystems - Irvine United States
272b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
273b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_charmap(response, sp, exi)
274b89a8333Snatalie li - Sun Microsystems - Irvine United States *
275*593cc11bSJan Kryl * Check to see if this client needs a character set conversion.
276b89a8333Snatalie li - Sun Microsystems - Irvine United States */
277*593cc11bSJan Kryl static struct charset_cache *
nfscmd_charmap(exportinfo_t * exi,struct sockaddr * sp)278*593cc11bSJan Kryl nfscmd_charmap(exportinfo_t *exi, struct sockaddr *sp)
279b89a8333Snatalie li - Sun Microsystems - Irvine United States {
280b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_arg_t req;
281*593cc11bSJan Kryl int ret;
282*593cc11bSJan Kryl char *path;
283b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_res_t res;
284*593cc11bSJan Kryl struct charset_cache *charset;
285b89a8333Snatalie li - Sun Microsystems - Irvine United States
286b89a8333Snatalie li - Sun Microsystems - Irvine United States path = exi->exi_export.ex_path;
287*593cc11bSJan Kryl if (path == NULL)
288*593cc11bSJan Kryl return (NULL);
289b89a8333Snatalie li - Sun Microsystems - Irvine United States
290b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
291*593cc11bSJan Kryl * nfscmd_findmap() did not find one in the cache so make
292*593cc11bSJan Kryl * the request to the daemon. We need to add the entry in
293*593cc11bSJan Kryl * either case since we want negative as well as
294b89a8333Snatalie li - Sun Microsystems - Irvine United States * positive cacheing.
295b89a8333Snatalie li - Sun Microsystems - Irvine United States */
296b89a8333Snatalie li - Sun Microsystems - Irvine United States req.cmd = NFSCMD_CHARMAP_LOOKUP;
297b89a8333Snatalie li - Sun Microsystems - Irvine United States req.version = NFSCMD_VERSION;
298b89a8333Snatalie li - Sun Microsystems - Irvine United States req.arg.charmap.addr = *sp;
299b89a8333Snatalie li - Sun Microsystems - Irvine United States (void) strncpy(req.arg.charmap.path, path, MAXPATHLEN);
300b89a8333Snatalie li - Sun Microsystems - Irvine United States bzero((caddr_t)&res, sizeof (nfscmd_res_t));
301b89a8333Snatalie li - Sun Microsystems - Irvine United States ret = nfscmd_send(&req, &res);
302b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ret == NFSCMD_ERR_SUCCESS)
303b89a8333Snatalie li - Sun Microsystems - Irvine United States charset = nfscmd_insert_charmap(exi, sp,
304b89a8333Snatalie li - Sun Microsystems - Irvine United States res.result.charmap.codeset);
305b89a8333Snatalie li - Sun Microsystems - Irvine United States else
306b89a8333Snatalie li - Sun Microsystems - Irvine United States charset = nfscmd_insert_charmap(exi, sp, NULL);
307*593cc11bSJan Kryl
308*593cc11bSJan Kryl return (charset);
309b89a8333Snatalie li - Sun Microsystems - Irvine United States }
310b89a8333Snatalie li - Sun Microsystems - Irvine United States
311b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
312b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_convname(addr, export, name, inbound, size)
313b89a8333Snatalie li - Sun Microsystems - Irvine United States *
314b89a8333Snatalie li - Sun Microsystems - Irvine United States * Convert the given "name" string to the appropriate character set.
315b89a8333Snatalie li - Sun Microsystems - Irvine United States * If inbound is true, convert from the client character set to UTF-8.
316b89a8333Snatalie li - Sun Microsystems - Irvine United States * If inbound is false, convert from UTF-8 to the client characters set.
317*593cc11bSJan Kryl *
318*593cc11bSJan Kryl * In case of NFS v4 this is used for ill behaved clients, since
319*593cc11bSJan Kryl * according to the standard all file names should be utf-8 encoded
320*593cc11bSJan Kryl * on client-side.
321b89a8333Snatalie li - Sun Microsystems - Irvine United States */
322b89a8333Snatalie li - Sun Microsystems - Irvine United States
323b89a8333Snatalie li - Sun Microsystems - Irvine United States char *
nfscmd_convname(struct sockaddr * ca,struct exportinfo * exi,char * name,int inbound,size_t size)324b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_convname(struct sockaddr *ca, struct exportinfo *exi, char *name,
325b89a8333Snatalie li - Sun Microsystems - Irvine United States int inbound, size_t size)
326b89a8333Snatalie li - Sun Microsystems - Irvine United States {
327b89a8333Snatalie li - Sun Microsystems - Irvine United States char *newname;
328b89a8333Snatalie li - Sun Microsystems - Irvine United States char *holdname;
329b89a8333Snatalie li - Sun Microsystems - Irvine United States int err;
330b89a8333Snatalie li - Sun Microsystems - Irvine United States int ret;
331b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t nsize;
332b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t osize;
333b89a8333Snatalie li - Sun Microsystems - Irvine United States struct charset_cache *charset = NULL;
334b89a8333Snatalie li - Sun Microsystems - Irvine United States
335b89a8333Snatalie li - Sun Microsystems - Irvine United States charset = nfscmd_findmap(exi, ca);
336*593cc11bSJan Kryl if (charset == NULL ||
337*593cc11bSJan Kryl (charset->inbound == NULL && inbound) ||
338*593cc11bSJan Kryl (charset->outbound == NULL && !inbound))
339b89a8333Snatalie li - Sun Microsystems - Irvine United States return (name);
340b89a8333Snatalie li - Sun Microsystems - Irvine United States
341b89a8333Snatalie li - Sun Microsystems - Irvine United States /* make sure we have more than enough space */
342b89a8333Snatalie li - Sun Microsystems - Irvine United States newname = kmem_zalloc(size, KM_SLEEP);
343b89a8333Snatalie li - Sun Microsystems - Irvine United States nsize = strlen(name);
344b89a8333Snatalie li - Sun Microsystems - Irvine United States osize = size;
345b89a8333Snatalie li - Sun Microsystems - Irvine United States holdname = newname;
346b89a8333Snatalie li - Sun Microsystems - Irvine United States if (inbound)
347b89a8333Snatalie li - Sun Microsystems - Irvine United States ret = kiconv(charset->inbound, &name, &nsize,
348b89a8333Snatalie li - Sun Microsystems - Irvine United States &holdname, &osize, &err);
349b89a8333Snatalie li - Sun Microsystems - Irvine United States else
350b89a8333Snatalie li - Sun Microsystems - Irvine United States ret = kiconv(charset->outbound, &name, &nsize,
351b89a8333Snatalie li - Sun Microsystems - Irvine United States &holdname, &osize, &err);
352b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ret == (size_t)-1) {
353b89a8333Snatalie li - Sun Microsystems - Irvine United States kmem_free(newname, size);
354b89a8333Snatalie li - Sun Microsystems - Irvine United States newname = NULL;
355b89a8333Snatalie li - Sun Microsystems - Irvine United States }
356b89a8333Snatalie li - Sun Microsystems - Irvine United States
357b89a8333Snatalie li - Sun Microsystems - Irvine United States return (newname);
358b89a8333Snatalie li - Sun Microsystems - Irvine United States }
359b89a8333Snatalie li - Sun Microsystems - Irvine United States
360b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
361b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_convdirent()
362b89a8333Snatalie li - Sun Microsystems - Irvine United States *
363b89a8333Snatalie li - Sun Microsystems - Irvine United States * There is only one entry in the data. Convert to new charset, if
364b89a8333Snatalie li - Sun Microsystems - Irvine United States * required and only return a success if it fits.
365b89a8333Snatalie li - Sun Microsystems - Irvine United States */
366b89a8333Snatalie li - Sun Microsystems - Irvine United States char *
nfscmd_convdirent(struct sockaddr * ca,struct exportinfo * exi,char * data,size_t size,enum nfsstat3 * error)367b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_convdirent(struct sockaddr *ca, struct exportinfo *exi, char *data,
368b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t size, enum nfsstat3 *error)
369b89a8333Snatalie li - Sun Microsystems - Irvine United States {
370b89a8333Snatalie li - Sun Microsystems - Irvine United States char *newdata;
371b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t ret;
372b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t nsize;
373b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t count;
374b89a8333Snatalie li - Sun Microsystems - Irvine United States int err = 0;
375b89a8333Snatalie li - Sun Microsystems - Irvine United States char *iname;
376b89a8333Snatalie li - Sun Microsystems - Irvine United States char *oname;
377b89a8333Snatalie li - Sun Microsystems - Irvine United States struct charset_cache *charset;
378b89a8333Snatalie li - Sun Microsystems - Irvine United States
379b89a8333Snatalie li - Sun Microsystems - Irvine United States charset = nfscmd_findmap(exi, ca);
380b89a8333Snatalie li - Sun Microsystems - Irvine United States if (charset == NULL || charset->outbound == (void *)~0)
381b89a8333Snatalie li - Sun Microsystems - Irvine United States return (data);
382b89a8333Snatalie li - Sun Microsystems - Irvine United States
383b89a8333Snatalie li - Sun Microsystems - Irvine United States newdata = kmem_zalloc(size, KM_SLEEP);
384b89a8333Snatalie li - Sun Microsystems - Irvine United States
385b89a8333Snatalie li - Sun Microsystems - Irvine United States nsize = strlen(((struct dirent64 *)data)->d_name);
386b89a8333Snatalie li - Sun Microsystems - Irvine United States count = size;
387b89a8333Snatalie li - Sun Microsystems - Irvine United States bcopy(data, newdata, sizeof (struct dirent64));
388b89a8333Snatalie li - Sun Microsystems - Irvine United States
389b89a8333Snatalie li - Sun Microsystems - Irvine United States iname = ((struct dirent64 *)data)->d_name;
390b89a8333Snatalie li - Sun Microsystems - Irvine United States oname = ((struct dirent64 *)newdata)->d_name;
391b89a8333Snatalie li - Sun Microsystems - Irvine United States
392b89a8333Snatalie li - Sun Microsystems - Irvine United States ret = kiconv(charset->outbound, &iname, &nsize, &oname, &count, &err);
393b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ret == (size_t)-1) {
394b89a8333Snatalie li - Sun Microsystems - Irvine United States kmem_free(newdata, size);
395b89a8333Snatalie li - Sun Microsystems - Irvine United States newdata = NULL;
396b89a8333Snatalie li - Sun Microsystems - Irvine United States if (err == E2BIG) {
397b89a8333Snatalie li - Sun Microsystems - Irvine United States if (error != NULL)
398b89a8333Snatalie li - Sun Microsystems - Irvine United States *error = NFS3ERR_NAMETOOLONG;
399b89a8333Snatalie li - Sun Microsystems - Irvine United States } else {
400b89a8333Snatalie li - Sun Microsystems - Irvine United States newdata = data;
401b89a8333Snatalie li - Sun Microsystems - Irvine United States }
402b89a8333Snatalie li - Sun Microsystems - Irvine United States } else {
403b89a8333Snatalie li - Sun Microsystems - Irvine United States ret = strlen(((struct dirent64 *)newdata)->d_name);
404b89a8333Snatalie li - Sun Microsystems - Irvine United States ((struct dirent64 *)newdata)->d_reclen =
405b89a8333Snatalie li - Sun Microsystems - Irvine United States DIRENT64_RECLEN(ret + 1);
406b89a8333Snatalie li - Sun Microsystems - Irvine United States }
407b89a8333Snatalie li - Sun Microsystems - Irvine United States return (newdata);
408b89a8333Snatalie li - Sun Microsystems - Irvine United States }
409b89a8333Snatalie li - Sun Microsystems - Irvine United States
410b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
411b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_convdirplus(addr, export, data, nents, maxsize, ndata)
412b89a8333Snatalie li - Sun Microsystems - Irvine United States *
413b89a8333Snatalie li - Sun Microsystems - Irvine United States * Convert the dirents in data into a new list of dirents in ndata.
414b89a8333Snatalie li - Sun Microsystems - Irvine United States */
415b89a8333Snatalie li - Sun Microsystems - Irvine United States
416b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t
nfscmd_convdirplus(struct sockaddr * ca,struct exportinfo * exi,char * data,size_t nents,size_t maxsize,char ** ndata)417b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_convdirplus(struct sockaddr *ca, struct exportinfo *exi, char *data,
418b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t nents, size_t maxsize, char **ndata)
419b89a8333Snatalie li - Sun Microsystems - Irvine United States {
420b89a8333Snatalie li - Sun Microsystems - Irvine United States char *newdata;
421b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t nsize;
422b89a8333Snatalie li - Sun Microsystems - Irvine United States struct dirent64 *dp;
423b89a8333Snatalie li - Sun Microsystems - Irvine United States struct dirent64 *ndp;
424b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t i;
425b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t ret;
426b89a8333Snatalie li - Sun Microsystems - Irvine United States char *iname;
427b89a8333Snatalie li - Sun Microsystems - Irvine United States char *oname;
428b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t ilen;
429b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t olen;
430b89a8333Snatalie li - Sun Microsystems - Irvine United States int err;
431b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t skipped;
432b89a8333Snatalie li - Sun Microsystems - Irvine United States struct charset_cache *charset;
433b89a8333Snatalie li - Sun Microsystems - Irvine United States *ndata = data; /* return the data if no changes to make */
434b89a8333Snatalie li - Sun Microsystems - Irvine United States
435b89a8333Snatalie li - Sun Microsystems - Irvine United States charset = nfscmd_findmap(exi, ca);
436b89a8333Snatalie li - Sun Microsystems - Irvine United States
437b89a8333Snatalie li - Sun Microsystems - Irvine United States if (charset == NULL || charset->outbound == (void *)~0)
438b89a8333Snatalie li - Sun Microsystems - Irvine United States return (0);
439b89a8333Snatalie li - Sun Microsystems - Irvine United States
440b89a8333Snatalie li - Sun Microsystems - Irvine United States newdata = kmem_zalloc(maxsize, KM_SLEEP);
441b89a8333Snatalie li - Sun Microsystems - Irvine United States nsize = 0;
442b89a8333Snatalie li - Sun Microsystems - Irvine United States
443b89a8333Snatalie li - Sun Microsystems - Irvine United States dp = (struct dirent64 *)data;
444b89a8333Snatalie li - Sun Microsystems - Irvine United States ndp = (struct dirent64 *)newdata;
445b89a8333Snatalie li - Sun Microsystems - Irvine United States
446b89a8333Snatalie li - Sun Microsystems - Irvine United States for (skipped = 0, i = 0; i < nents; i++) {
447b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
448b89a8333Snatalie li - Sun Microsystems - Irvine United States * Copy the dp information if it fits. Then copy and
449b89a8333Snatalie li - Sun Microsystems - Irvine United States * convert the name in the entry.
450b89a8333Snatalie li - Sun Microsystems - Irvine United States */
451b89a8333Snatalie li - Sun Microsystems - Irvine United States if ((maxsize - nsize) < dp->d_reclen)
452b89a8333Snatalie li - Sun Microsystems - Irvine United States /* doesn't fit */
453b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
454b89a8333Snatalie li - Sun Microsystems - Irvine United States *ndp = *dp;
455b89a8333Snatalie li - Sun Microsystems - Irvine United States iname = dp->d_name;
456b89a8333Snatalie li - Sun Microsystems - Irvine United States ilen = strlen(iname);
457b89a8333Snatalie li - Sun Microsystems - Irvine United States oname = ndp->d_name;
458b89a8333Snatalie li - Sun Microsystems - Irvine United States olen = MIN(MAXNAMELEN, maxsize - nsize);
459b89a8333Snatalie li - Sun Microsystems - Irvine United States ret = kiconv(charset->outbound, &iname, &ilen, &oname,
460b89a8333Snatalie li - Sun Microsystems - Irvine United States &olen, &err);
461b89a8333Snatalie li - Sun Microsystems - Irvine United States
462b89a8333Snatalie li - Sun Microsystems - Irvine United States if (ret == (size_t)-1) {
463b89a8333Snatalie li - Sun Microsystems - Irvine United States switch (err) {
464b89a8333Snatalie li - Sun Microsystems - Irvine United States default:
465b89a8333Snatalie li - Sun Microsystems - Irvine United States case E2BIG:
466b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
467b89a8333Snatalie li - Sun Microsystems - Irvine United States case EILSEQ:
468b89a8333Snatalie li - Sun Microsystems - Irvine United States skipped++;
469b89a8333Snatalie li - Sun Microsystems - Irvine United States dp = nextdp(dp);
470b89a8333Snatalie li - Sun Microsystems - Irvine United States continue;
471b89a8333Snatalie li - Sun Microsystems - Irvine United States }
472b89a8333Snatalie li - Sun Microsystems - Irvine United States }
473b89a8333Snatalie li - Sun Microsystems - Irvine United States ilen = MIN(MAXNAMELEN, maxsize - nsize) - olen;
474b89a8333Snatalie li - Sun Microsystems - Irvine United States ndp->d_name[ilen] = '\0';
475b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
476b89a8333Snatalie li - Sun Microsystems - Irvine United States * What to do with other errors?
477b89a8333Snatalie li - Sun Microsystems - Irvine United States * For now, we return the unconverted string.
478b89a8333Snatalie li - Sun Microsystems - Irvine United States */
479b89a8333Snatalie li - Sun Microsystems - Irvine United States ndp->d_reclen = DIRENT64_RECLEN(strlen(ndp->d_name) + 1);
480b89a8333Snatalie li - Sun Microsystems - Irvine United States nsize += ndp->d_reclen;
481b89a8333Snatalie li - Sun Microsystems - Irvine United States dp = nextdp(dp);
482b89a8333Snatalie li - Sun Microsystems - Irvine United States ndp = nextdp(ndp);
483b89a8333Snatalie li - Sun Microsystems - Irvine United States }
484b89a8333Snatalie li - Sun Microsystems - Irvine United States
485b89a8333Snatalie li - Sun Microsystems - Irvine United States *ndata = newdata;
486b89a8333Snatalie li - Sun Microsystems - Irvine United States return (nents - (i + skipped));
487b89a8333Snatalie li - Sun Microsystems - Irvine United States }
488b89a8333Snatalie li - Sun Microsystems - Irvine United States
489b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
490b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_countents(data, len)
491b89a8333Snatalie li - Sun Microsystems - Irvine United States *
492b89a8333Snatalie li - Sun Microsystems - Irvine United States * How many dirents are there in the data buffer?
493b89a8333Snatalie li - Sun Microsystems - Irvine United States */
494b89a8333Snatalie li - Sun Microsystems - Irvine United States
495b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t
nfscmd_countents(char * data,size_t len)496b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_countents(char *data, size_t len)
497b89a8333Snatalie li - Sun Microsystems - Irvine United States {
498b89a8333Snatalie li - Sun Microsystems - Irvine United States struct dirent64 *dp = (struct dirent64 *)data;
499b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t curlen;
500b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t reclen;
501b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t nents;
502b89a8333Snatalie li - Sun Microsystems - Irvine United States
503b89a8333Snatalie li - Sun Microsystems - Irvine United States for (nents = 0, curlen = 0; curlen < len; curlen += reclen, nents++) {
504b89a8333Snatalie li - Sun Microsystems - Irvine United States reclen = dp->d_reclen;
505b89a8333Snatalie li - Sun Microsystems - Irvine United States dp = nextdp(dp);
506b89a8333Snatalie li - Sun Microsystems - Irvine United States }
507b89a8333Snatalie li - Sun Microsystems - Irvine United States return (nents);
508b89a8333Snatalie li - Sun Microsystems - Irvine United States }
509b89a8333Snatalie li - Sun Microsystems - Irvine United States
510b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
511b89a8333Snatalie li - Sun Microsystems - Irvine United States * nfscmd_dropped_entrysize(dir, drop, nents)
512b89a8333Snatalie li - Sun Microsystems - Irvine United States *
513b89a8333Snatalie li - Sun Microsystems - Irvine United States * We need to drop "drop" entries from dir in order to fit in the
514b89a8333Snatalie li - Sun Microsystems - Irvine United States * buffer. How much do we reduce the overall size by?
515b89a8333Snatalie li - Sun Microsystems - Irvine United States */
516b89a8333Snatalie li - Sun Microsystems - Irvine United States
517b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t
nfscmd_dropped_entrysize(struct dirent64 * dir,size_t drop,size_t nents)518b89a8333Snatalie li - Sun Microsystems - Irvine United States nfscmd_dropped_entrysize(struct dirent64 *dir, size_t drop, size_t nents)
519b89a8333Snatalie li - Sun Microsystems - Irvine United States {
520b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t size;
521b89a8333Snatalie li - Sun Microsystems - Irvine United States size_t i;
522b89a8333Snatalie li - Sun Microsystems - Irvine United States
523b89a8333Snatalie li - Sun Microsystems - Irvine United States for (i = nents - drop; i > 0 && dir != NULL; i--)
524b89a8333Snatalie li - Sun Microsystems - Irvine United States dir = nextdp(dir);
525b89a8333Snatalie li - Sun Microsystems - Irvine United States
526b89a8333Snatalie li - Sun Microsystems - Irvine United States if (dir == NULL)
527b89a8333Snatalie li - Sun Microsystems - Irvine United States return (0);
528b89a8333Snatalie li - Sun Microsystems - Irvine United States
529b89a8333Snatalie li - Sun Microsystems - Irvine United States for (size = 0, i = 0; i < drop && dir != NULL; i++) {
530b89a8333Snatalie li - Sun Microsystems - Irvine United States size += dir->d_reclen;
531b89a8333Snatalie li - Sun Microsystems - Irvine United States dir = nextdp(dir);
532b89a8333Snatalie li - Sun Microsystems - Irvine United States }
533b89a8333Snatalie li - Sun Microsystems - Irvine United States return (size);
534b89a8333Snatalie li - Sun Microsystems - Irvine United States }
535