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