xref: /titanic_51/usr/src/uts/common/fs/nfs/nfs_cmd.c (revision 593cc11b0ce1691880b59ee5a8bd6adcdc823490)
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
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
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
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
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 *
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 *
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 *
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 *
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 *
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
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
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
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