Home | History | Annotate | Line # | Download | only in client
nfs_clcomsubs.c revision 1.1.1.1.10.2
      1  1.1.1.1.10.2  tls /*	$NetBSD: nfs_clcomsubs.c,v 1.1.1.1.10.2 2014/08/20 00:04:26 tls Exp $	*/
      2  1.1.1.1.10.2  tls /*-
      3  1.1.1.1.10.2  tls  * Copyright (c) 1989, 1993
      4  1.1.1.1.10.2  tls  *	The Regents of the University of California.  All rights reserved.
      5  1.1.1.1.10.2  tls  *
      6  1.1.1.1.10.2  tls  * This code is derived from software contributed to Berkeley by
      7  1.1.1.1.10.2  tls  * Rick Macklem at The University of Guelph.
      8  1.1.1.1.10.2  tls  *
      9  1.1.1.1.10.2  tls  * Redistribution and use in source and binary forms, with or without
     10  1.1.1.1.10.2  tls  * modification, are permitted provided that the following conditions
     11  1.1.1.1.10.2  tls  * are met:
     12  1.1.1.1.10.2  tls  * 1. Redistributions of source code must retain the above copyright
     13  1.1.1.1.10.2  tls  *    notice, this list of conditions and the following disclaimer.
     14  1.1.1.1.10.2  tls  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1.1.1.10.2  tls  *    notice, this list of conditions and the following disclaimer in the
     16  1.1.1.1.10.2  tls  *    documentation and/or other materials provided with the distribution.
     17  1.1.1.1.10.2  tls  * 4. Neither the name of the University nor the names of its contributors
     18  1.1.1.1.10.2  tls  *    may be used to endorse or promote products derived from this software
     19  1.1.1.1.10.2  tls  *    without specific prior written permission.
     20  1.1.1.1.10.2  tls  *
     21  1.1.1.1.10.2  tls  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  1.1.1.1.10.2  tls  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  1.1.1.1.10.2  tls  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  1.1.1.1.10.2  tls  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  1.1.1.1.10.2  tls  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  1.1.1.1.10.2  tls  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  1.1.1.1.10.2  tls  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  1.1.1.1.10.2  tls  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  1.1.1.1.10.2  tls  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  1.1.1.1.10.2  tls  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  1.1.1.1.10.2  tls  * SUCH DAMAGE.
     32  1.1.1.1.10.2  tls  *
     33  1.1.1.1.10.2  tls  */
     34  1.1.1.1.10.2  tls 
     35  1.1.1.1.10.2  tls #include <sys/cdefs.h>
     36  1.1.1.1.10.2  tls /* __FBSDID("FreeBSD: head/sys/fs/nfsclient/nfs_clcomsubs.c 244042 2012-12-08 22:52:39Z rmacklem "); */
     37  1.1.1.1.10.2  tls __RCSID("$NetBSD: nfs_clcomsubs.c,v 1.1.1.1.10.2 2014/08/20 00:04:26 tls Exp $");
     38  1.1.1.1.10.2  tls 
     39  1.1.1.1.10.2  tls /*
     40  1.1.1.1.10.2  tls  * These functions support the macros and help fiddle mbuf chains for
     41  1.1.1.1.10.2  tls  * the nfs op functions. They do things like create the rpc header and
     42  1.1.1.1.10.2  tls  * copy data between mbuf chains and uio lists.
     43  1.1.1.1.10.2  tls  */
     44  1.1.1.1.10.2  tls #ifndef APPLEKEXT
     45  1.1.1.1.10.2  tls #include <fs/nfs/nfsport.h>
     46  1.1.1.1.10.2  tls 
     47  1.1.1.1.10.2  tls extern struct nfsstats newnfsstats;
     48  1.1.1.1.10.2  tls extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
     49  1.1.1.1.10.2  tls extern int ncl_mbuf_mlen;
     50  1.1.1.1.10.2  tls extern enum vtype newnv2tov_type[8];
     51  1.1.1.1.10.2  tls extern enum vtype nv34tov_type[8];
     52  1.1.1.1.10.2  tls extern int	nfs_bigreply[NFSV41_NPROCS];
     53  1.1.1.1.10.2  tls NFSCLSTATEMUTEX;
     54  1.1.1.1.10.2  tls #endif	/* !APPLEKEXT */
     55  1.1.1.1.10.2  tls 
     56  1.1.1.1.10.2  tls static nfsuint64 nfs_nullcookie = {{ 0, 0 }};
     57  1.1.1.1.10.2  tls static struct {
     58  1.1.1.1.10.2  tls 	int	op;
     59  1.1.1.1.10.2  tls 	int	opcnt;
     60  1.1.1.1.10.2  tls 	const u_char *tag;
     61  1.1.1.1.10.2  tls 	int	taglen;
     62  1.1.1.1.10.2  tls } nfsv4_opmap[NFSV41_NPROCS] = {
     63  1.1.1.1.10.2  tls 	{ 0, 1, "Null", 4 },
     64  1.1.1.1.10.2  tls 	{ NFSV4OP_GETATTR, 1, "Getattr", 7, },
     65  1.1.1.1.10.2  tls 	{ NFSV4OP_SETATTR, 2, "Setattr", 7, },
     66  1.1.1.1.10.2  tls 	{ NFSV4OP_LOOKUP, 3, "Lookup", 6, },
     67  1.1.1.1.10.2  tls 	{ NFSV4OP_ACCESS, 2, "Access", 6, },
     68  1.1.1.1.10.2  tls 	{ NFSV4OP_READLINK, 2, "Readlink", 8, },
     69  1.1.1.1.10.2  tls 	{ NFSV4OP_READ, 1, "Read", 4, },
     70  1.1.1.1.10.2  tls 	{ NFSV4OP_WRITE, 2, "Write", 5, },
     71  1.1.1.1.10.2  tls 	{ NFSV4OP_OPEN, 3, "Open", 4, },
     72  1.1.1.1.10.2  tls 	{ NFSV4OP_CREATE, 3, "Create", 6, },
     73  1.1.1.1.10.2  tls 	{ NFSV4OP_CREATE, 1, "Create", 6, },
     74  1.1.1.1.10.2  tls 	{ NFSV4OP_CREATE, 3, "Create", 6, },
     75  1.1.1.1.10.2  tls 	{ NFSV4OP_REMOVE, 1, "Remove", 6, },
     76  1.1.1.1.10.2  tls 	{ NFSV4OP_REMOVE, 1, "Remove", 6, },
     77  1.1.1.1.10.2  tls 	{ NFSV4OP_SAVEFH, 5, "Rename", 6, },
     78  1.1.1.1.10.2  tls 	{ NFSV4OP_SAVEFH, 4, "Link", 4, },
     79  1.1.1.1.10.2  tls 	{ NFSV4OP_READDIR, 2, "Readdir", 7, },
     80  1.1.1.1.10.2  tls 	{ NFSV4OP_READDIR, 2, "Readdir", 7, },
     81  1.1.1.1.10.2  tls 	{ NFSV4OP_GETATTR, 1, "Getattr", 7, },
     82  1.1.1.1.10.2  tls 	{ NFSV4OP_GETATTR, 1, "Getattr", 7, },
     83  1.1.1.1.10.2  tls 	{ NFSV4OP_GETATTR, 1, "Getattr", 7, },
     84  1.1.1.1.10.2  tls 	{ NFSV4OP_COMMIT, 2, "Commit", 6, },
     85  1.1.1.1.10.2  tls 	{ NFSV4OP_LOOKUPP, 3, "Lookupp", 7, },
     86  1.1.1.1.10.2  tls 	{ NFSV4OP_SETCLIENTID, 1, "SetClientID", 11, },
     87  1.1.1.1.10.2  tls 	{ NFSV4OP_SETCLIENTIDCFRM, 1, "SetClientIDConfirm", 18, },
     88  1.1.1.1.10.2  tls 	{ NFSV4OP_LOCK, 1, "Lock", 4, },
     89  1.1.1.1.10.2  tls 	{ NFSV4OP_LOCKU, 1, "LockU", 5, },
     90  1.1.1.1.10.2  tls 	{ NFSV4OP_OPEN, 2, "Open", 4, },
     91  1.1.1.1.10.2  tls 	{ NFSV4OP_CLOSE, 1, "Close", 5, },
     92  1.1.1.1.10.2  tls 	{ NFSV4OP_OPENCONFIRM, 1, "Openconfirm", 11, },
     93  1.1.1.1.10.2  tls 	{ NFSV4OP_LOCKT, 1, "LockT", 5, },
     94  1.1.1.1.10.2  tls 	{ NFSV4OP_OPENDOWNGRADE, 1, "Opendowngrade", 13, },
     95  1.1.1.1.10.2  tls 	{ NFSV4OP_RENEW, 1, "Renew", 5, },
     96  1.1.1.1.10.2  tls 	{ NFSV4OP_PUTROOTFH, 1, "Dirpath", 7, },
     97  1.1.1.1.10.2  tls 	{ NFSV4OP_RELEASELCKOWN, 1, "Rellckown", 9, },
     98  1.1.1.1.10.2  tls 	{ NFSV4OP_DELEGRETURN, 1, "Delegret", 8, },
     99  1.1.1.1.10.2  tls 	{ NFSV4OP_DELEGRETURN, 3, "DelegRemove", 11, },
    100  1.1.1.1.10.2  tls 	{ NFSV4OP_DELEGRETURN, 7, "DelegRename1", 12, },
    101  1.1.1.1.10.2  tls 	{ NFSV4OP_DELEGRETURN, 9, "DelegRename2", 12, },
    102  1.1.1.1.10.2  tls 	{ NFSV4OP_GETATTR, 1, "Getacl", 6, },
    103  1.1.1.1.10.2  tls 	{ NFSV4OP_SETATTR, 1, "Setacl", 6, },
    104  1.1.1.1.10.2  tls 	{ NFSV4OP_EXCHANGEID, 1, "ExchangeID", 10, },
    105  1.1.1.1.10.2  tls 	{ NFSV4OP_CREATESESSION, 1, "CreateSession", 13, },
    106  1.1.1.1.10.2  tls 	{ NFSV4OP_DESTROYSESSION, 1, "DestroySession", 14, },
    107  1.1.1.1.10.2  tls 	{ NFSV4OP_DESTROYCLIENTID, 1, "DestroyClient", 13, },
    108  1.1.1.1.10.2  tls 	{ NFSV4OP_FREESTATEID, 1, "FreeStateID", 11, },
    109  1.1.1.1.10.2  tls 	{ NFSV4OP_LAYOUTGET, 1, "LayoutGet", 9, },
    110  1.1.1.1.10.2  tls 	{ NFSV4OP_GETDEVINFO, 1, "GetDeviceInfo", 13, },
    111  1.1.1.1.10.2  tls 	{ NFSV4OP_LAYOUTCOMMIT, 1, "LayoutCommit", 12, },
    112  1.1.1.1.10.2  tls 	{ NFSV4OP_LAYOUTRETURN, 1, "LayoutReturn", 12, },
    113  1.1.1.1.10.2  tls 	{ NFSV4OP_RECLAIMCOMPL, 1, "ReclaimComplete", 15, },
    114  1.1.1.1.10.2  tls 	{ NFSV4OP_WRITE, 1, "WriteDS", 7, },
    115  1.1.1.1.10.2  tls 	{ NFSV4OP_READ, 1, "ReadDS", 6, },
    116  1.1.1.1.10.2  tls 	{ NFSV4OP_COMMIT, 1, "CommitDS", 8, },
    117  1.1.1.1.10.2  tls };
    118  1.1.1.1.10.2  tls 
    119  1.1.1.1.10.2  tls /*
    120  1.1.1.1.10.2  tls  * NFS RPCS that have large request message size.
    121  1.1.1.1.10.2  tls  */
    122  1.1.1.1.10.2  tls static int nfs_bigrequest[NFSV41_NPROCS] = {
    123  1.1.1.1.10.2  tls 	0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    124  1.1.1.1.10.2  tls 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    125  1.1.1.1.10.2  tls 	0, 0, 0, 0, 0, 0, 1, 0, 0
    126  1.1.1.1.10.2  tls };
    127  1.1.1.1.10.2  tls 
    128  1.1.1.1.10.2  tls /*
    129  1.1.1.1.10.2  tls  * Start building a request. Mostly just put the first file handle in
    130  1.1.1.1.10.2  tls  * place.
    131  1.1.1.1.10.2  tls  */
    132  1.1.1.1.10.2  tls APPLESTATIC void
    133  1.1.1.1.10.2  tls nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
    134  1.1.1.1.10.2  tls     u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep)
    135  1.1.1.1.10.2  tls {
    136  1.1.1.1.10.2  tls 	struct mbuf *mb;
    137  1.1.1.1.10.2  tls 	u_int32_t *tl;
    138  1.1.1.1.10.2  tls 	int opcnt;
    139  1.1.1.1.10.2  tls 	nfsattrbit_t attrbits;
    140  1.1.1.1.10.2  tls 
    141  1.1.1.1.10.2  tls 	/*
    142  1.1.1.1.10.2  tls 	 * First, fill in some of the fields of nd.
    143  1.1.1.1.10.2  tls 	 */
    144  1.1.1.1.10.2  tls 	nd->nd_slotseq = NULL;
    145  1.1.1.1.10.2  tls 	if (NFSHASNFSV4(nmp)) {
    146  1.1.1.1.10.2  tls 		nd->nd_flag = ND_NFSV4 | ND_NFSCL;
    147  1.1.1.1.10.2  tls 		if (NFSHASNFSV4N(nmp))
    148  1.1.1.1.10.2  tls 			nd->nd_flag |= ND_NFSV41;
    149  1.1.1.1.10.2  tls 	} else if (NFSHASNFSV3(nmp))
    150  1.1.1.1.10.2  tls 		nd->nd_flag = ND_NFSV3 | ND_NFSCL;
    151  1.1.1.1.10.2  tls 	else
    152  1.1.1.1.10.2  tls 		nd->nd_flag = ND_NFSV2 | ND_NFSCL;
    153  1.1.1.1.10.2  tls 	nd->nd_procnum = procnum;
    154  1.1.1.1.10.2  tls 	nd->nd_repstat = 0;
    155  1.1.1.1.10.2  tls 
    156  1.1.1.1.10.2  tls 	/*
    157  1.1.1.1.10.2  tls 	 * Get the first mbuf for the request.
    158  1.1.1.1.10.2  tls 	 */
    159  1.1.1.1.10.2  tls 	if (nfs_bigrequest[procnum])
    160  1.1.1.1.10.2  tls 		NFSMCLGET(mb, M_WAITOK);
    161  1.1.1.1.10.2  tls 	else
    162  1.1.1.1.10.2  tls 		NFSMGET(mb);
    163  1.1.1.1.10.2  tls 	mbuf_setlen(mb, 0);
    164  1.1.1.1.10.2  tls 	nd->nd_mreq = nd->nd_mb = mb;
    165  1.1.1.1.10.2  tls 	nd->nd_bpos = NFSMTOD(mb, caddr_t);
    166  1.1.1.1.10.2  tls 
    167  1.1.1.1.10.2  tls 	/*
    168  1.1.1.1.10.2  tls 	 * And fill the first file handle into the request.
    169  1.1.1.1.10.2  tls 	 */
    170  1.1.1.1.10.2  tls 	if (nd->nd_flag & ND_NFSV4) {
    171  1.1.1.1.10.2  tls 		opcnt = nfsv4_opmap[procnum].opcnt +
    172  1.1.1.1.10.2  tls 		    nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh;
    173  1.1.1.1.10.2  tls 		if ((nd->nd_flag & ND_NFSV41) != 0) {
    174  1.1.1.1.10.2  tls 			opcnt += nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq;
    175  1.1.1.1.10.2  tls 			if (procnum == NFSPROC_RENEW)
    176  1.1.1.1.10.2  tls 				/*
    177  1.1.1.1.10.2  tls 				 * For the special case of Renew, just do a
    178  1.1.1.1.10.2  tls 				 * Sequence Op.
    179  1.1.1.1.10.2  tls 				 */
    180  1.1.1.1.10.2  tls 				opcnt = 1;
    181  1.1.1.1.10.2  tls 			else if (procnum == NFSPROC_WRITEDS ||
    182  1.1.1.1.10.2  tls 			    procnum == NFSPROC_COMMITDS)
    183  1.1.1.1.10.2  tls 				/*
    184  1.1.1.1.10.2  tls 				 * For the special case of a Writeor Commit to
    185  1.1.1.1.10.2  tls 				 * a DS, the opcnt == 3, for Sequence, PutFH,
    186  1.1.1.1.10.2  tls 				 * Write/Commit.
    187  1.1.1.1.10.2  tls 				 */
    188  1.1.1.1.10.2  tls 				opcnt = 3;
    189  1.1.1.1.10.2  tls 		}
    190  1.1.1.1.10.2  tls 		/*
    191  1.1.1.1.10.2  tls 		 * What should the tag really be?
    192  1.1.1.1.10.2  tls 		 */
    193  1.1.1.1.10.2  tls 		(void) nfsm_strtom(nd, nfsv4_opmap[procnum].tag,
    194  1.1.1.1.10.2  tls 			nfsv4_opmap[procnum].taglen);
    195  1.1.1.1.10.2  tls 		NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
    196  1.1.1.1.10.2  tls 		if ((nd->nd_flag & ND_NFSV41) != 0)
    197  1.1.1.1.10.2  tls 			*tl++ = txdr_unsigned(NFSV41_MINORVERSION);
    198  1.1.1.1.10.2  tls 		else
    199  1.1.1.1.10.2  tls 			*tl++ = txdr_unsigned(NFSV4_MINORVERSION);
    200  1.1.1.1.10.2  tls 		if (opcntpp != NULL)
    201  1.1.1.1.10.2  tls 			*opcntpp = tl;
    202  1.1.1.1.10.2  tls 		*tl = txdr_unsigned(opcnt);
    203  1.1.1.1.10.2  tls 		if ((nd->nd_flag & ND_NFSV41) != 0 &&
    204  1.1.1.1.10.2  tls 		    nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq > 0) {
    205  1.1.1.1.10.2  tls 			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
    206  1.1.1.1.10.2  tls 			*tl = txdr_unsigned(NFSV4OP_SEQUENCE);
    207  1.1.1.1.10.2  tls 			if (sep == NULL)
    208  1.1.1.1.10.2  tls 				nfsv4_setsequence(nd, NFSMNT_MDSSESSION(nmp),
    209  1.1.1.1.10.2  tls 				    nfs_bigreply[procnum]);
    210  1.1.1.1.10.2  tls 			else
    211  1.1.1.1.10.2  tls 				nfsv4_setsequence(nd, sep,
    212  1.1.1.1.10.2  tls 				    nfs_bigreply[procnum]);
    213  1.1.1.1.10.2  tls 		}
    214  1.1.1.1.10.2  tls 		if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
    215  1.1.1.1.10.2  tls 			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
    216  1.1.1.1.10.2  tls 			*tl = txdr_unsigned(NFSV4OP_PUTFH);
    217  1.1.1.1.10.2  tls 			(void) nfsm_fhtom(nd, nfhp, fhlen, 0);
    218  1.1.1.1.10.2  tls 			if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh
    219  1.1.1.1.10.2  tls 			    == 2 && procnum != NFSPROC_WRITEDS &&
    220  1.1.1.1.10.2  tls 			    procnum != NFSPROC_COMMITDS) {
    221  1.1.1.1.10.2  tls 				NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
    222  1.1.1.1.10.2  tls 				*tl = txdr_unsigned(NFSV4OP_GETATTR);
    223  1.1.1.1.10.2  tls 				NFSWCCATTR_ATTRBIT(&attrbits);
    224  1.1.1.1.10.2  tls 				(void) nfsrv_putattrbit(nd, &attrbits);
    225  1.1.1.1.10.2  tls 				nd->nd_flag |= ND_V4WCCATTR;
    226  1.1.1.1.10.2  tls 			}
    227  1.1.1.1.10.2  tls 		}
    228  1.1.1.1.10.2  tls 		if (procnum != NFSPROC_RENEW ||
    229  1.1.1.1.10.2  tls 		    (nd->nd_flag & ND_NFSV41) == 0) {
    230  1.1.1.1.10.2  tls 			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
    231  1.1.1.1.10.2  tls 			*tl = txdr_unsigned(nfsv4_opmap[procnum].op);
    232  1.1.1.1.10.2  tls 		}
    233  1.1.1.1.10.2  tls 	} else {
    234  1.1.1.1.10.2  tls 		(void) nfsm_fhtom(nd, nfhp, fhlen, 0);
    235  1.1.1.1.10.2  tls 	}
    236  1.1.1.1.10.2  tls 	if (procnum < NFSV4_NPROCS)
    237  1.1.1.1.10.2  tls 		NFSINCRGLOBAL(newnfsstats.rpccnt[procnum]);
    238  1.1.1.1.10.2  tls }
    239  1.1.1.1.10.2  tls 
    240  1.1.1.1.10.2  tls #ifndef APPLE
    241  1.1.1.1.10.2  tls /*
    242  1.1.1.1.10.2  tls  * copies a uio scatter/gather list to an mbuf chain.
    243  1.1.1.1.10.2  tls  * NOTE: can ony handle iovcnt == 1
    244  1.1.1.1.10.2  tls  */
    245  1.1.1.1.10.2  tls APPLESTATIC void
    246  1.1.1.1.10.2  tls nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz)
    247  1.1.1.1.10.2  tls {
    248  1.1.1.1.10.2  tls 	char *uiocp;
    249  1.1.1.1.10.2  tls 	struct mbuf *mp, *mp2;
    250  1.1.1.1.10.2  tls 	int xfer, left, mlen;
    251  1.1.1.1.10.2  tls 	int uiosiz, clflg, rem;
    252  1.1.1.1.10.2  tls 	char *cp, *tcp;
    253  1.1.1.1.10.2  tls 
    254  1.1.1.1.10.2  tls 	KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));
    255  1.1.1.1.10.2  tls 
    256  1.1.1.1.10.2  tls 	if (siz > ncl_mbuf_mlen)	/* or should it >= MCLBYTES ?? */
    257  1.1.1.1.10.2  tls 		clflg = 1;
    258  1.1.1.1.10.2  tls 	else
    259  1.1.1.1.10.2  tls 		clflg = 0;
    260  1.1.1.1.10.2  tls 	rem = NFSM_RNDUP(siz) - siz;
    261  1.1.1.1.10.2  tls 	mp = mp2 = nd->nd_mb;
    262  1.1.1.1.10.2  tls 	while (siz > 0) {
    263  1.1.1.1.10.2  tls 		left = uiop->uio_iov->iov_len;
    264  1.1.1.1.10.2  tls 		uiocp = uiop->uio_iov->iov_base;
    265  1.1.1.1.10.2  tls 		if (left > siz)
    266  1.1.1.1.10.2  tls 			left = siz;
    267  1.1.1.1.10.2  tls 		uiosiz = left;
    268  1.1.1.1.10.2  tls 		while (left > 0) {
    269  1.1.1.1.10.2  tls 			mlen = M_TRAILINGSPACE(mp);
    270  1.1.1.1.10.2  tls 			if (mlen == 0) {
    271  1.1.1.1.10.2  tls 				if (clflg)
    272  1.1.1.1.10.2  tls 					NFSMCLGET(mp, M_WAITOK);
    273  1.1.1.1.10.2  tls 				else
    274  1.1.1.1.10.2  tls 					NFSMGET(mp);
    275  1.1.1.1.10.2  tls 				mbuf_setlen(mp, 0);
    276  1.1.1.1.10.2  tls 				mbuf_setnext(mp2, mp);
    277  1.1.1.1.10.2  tls 				mp2 = mp;
    278  1.1.1.1.10.2  tls 				mlen = M_TRAILINGSPACE(mp);
    279  1.1.1.1.10.2  tls 			}
    280  1.1.1.1.10.2  tls 			xfer = (left > mlen) ? mlen : left;
    281  1.1.1.1.10.2  tls #ifdef notdef
    282  1.1.1.1.10.2  tls 			/* Not Yet.. */
    283  1.1.1.1.10.2  tls 			if (uiop->uio_iov->iov_op != NULL)
    284  1.1.1.1.10.2  tls 				(*(uiop->uio_iov->iov_op))
    285  1.1.1.1.10.2  tls 				(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
    286  1.1.1.1.10.2  tls 				    xfer);
    287  1.1.1.1.10.2  tls 			else
    288  1.1.1.1.10.2  tls #endif
    289  1.1.1.1.10.2  tls 			if (uiop->uio_segflg == UIO_SYSSPACE)
    290  1.1.1.1.10.2  tls 			    NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
    291  1.1.1.1.10.2  tls 				xfer);
    292  1.1.1.1.10.2  tls 			else
    293  1.1.1.1.10.2  tls 			    copyin(CAST_USER_ADDR_T(uiocp), NFSMTOD(mp, caddr_t)
    294  1.1.1.1.10.2  tls 				+ mbuf_len(mp), xfer);
    295  1.1.1.1.10.2  tls 			mbuf_setlen(mp, mbuf_len(mp) + xfer);
    296  1.1.1.1.10.2  tls 			left -= xfer;
    297  1.1.1.1.10.2  tls 			uiocp += xfer;
    298  1.1.1.1.10.2  tls 			uiop->uio_offset += xfer;
    299  1.1.1.1.10.2  tls 			uiop->uio_resid -= xfer;
    300  1.1.1.1.10.2  tls 		}
    301  1.1.1.1.10.2  tls 		tcp = (char *)uiop->uio_iov->iov_base;
    302  1.1.1.1.10.2  tls 		tcp += uiosiz;
    303  1.1.1.1.10.2  tls 		uiop->uio_iov->iov_base = (void *)tcp;
    304  1.1.1.1.10.2  tls 		uiop->uio_iov->iov_len -= uiosiz;
    305  1.1.1.1.10.2  tls 		siz -= uiosiz;
    306  1.1.1.1.10.2  tls 	}
    307  1.1.1.1.10.2  tls 	if (rem > 0) {
    308  1.1.1.1.10.2  tls 		if (rem > M_TRAILINGSPACE(mp)) {
    309  1.1.1.1.10.2  tls 			NFSMGET(mp);
    310  1.1.1.1.10.2  tls 			mbuf_setlen(mp, 0);
    311  1.1.1.1.10.2  tls 			mbuf_setnext(mp2, mp);
    312  1.1.1.1.10.2  tls 		}
    313  1.1.1.1.10.2  tls 		cp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
    314  1.1.1.1.10.2  tls 		for (left = 0; left < rem; left++)
    315  1.1.1.1.10.2  tls 			*cp++ = '\0';
    316  1.1.1.1.10.2  tls 		mbuf_setlen(mp, mbuf_len(mp) + rem);
    317  1.1.1.1.10.2  tls 		nd->nd_bpos = cp;
    318  1.1.1.1.10.2  tls 	} else
    319  1.1.1.1.10.2  tls 		nd->nd_bpos = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
    320  1.1.1.1.10.2  tls 	nd->nd_mb = mp;
    321  1.1.1.1.10.2  tls }
    322  1.1.1.1.10.2  tls #endif	/* !APPLE */
    323  1.1.1.1.10.2  tls 
    324  1.1.1.1.10.2  tls /*
    325  1.1.1.1.10.2  tls  * Load vnode attributes from the xdr file attributes.
    326  1.1.1.1.10.2  tls  * Returns EBADRPC if they can't be parsed, 0 otherwise.
    327  1.1.1.1.10.2  tls  */
    328  1.1.1.1.10.2  tls APPLESTATIC int
    329  1.1.1.1.10.2  tls nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap)
    330  1.1.1.1.10.2  tls {
    331  1.1.1.1.10.2  tls 	struct nfs_fattr *fp;
    332  1.1.1.1.10.2  tls 	int error = 0;
    333  1.1.1.1.10.2  tls 
    334  1.1.1.1.10.2  tls 	if (nd->nd_flag & ND_NFSV4) {
    335  1.1.1.1.10.2  tls 		error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL,
    336  1.1.1.1.10.2  tls 		    NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL);
    337  1.1.1.1.10.2  tls 	} else if (nd->nd_flag & ND_NFSV3) {
    338  1.1.1.1.10.2  tls 		NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V3FATTR);
    339  1.1.1.1.10.2  tls 		nap->na_type = nfsv34tov_type(fp->fa_type);
    340  1.1.1.1.10.2  tls 		nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
    341  1.1.1.1.10.2  tls 		nap->na_rdev = makedev(fxdr_unsigned(u_char, fp->fa3_rdev.specdata1),
    342  1.1.1.1.10.2  tls 			fxdr_unsigned(u_char, fp->fa3_rdev.specdata2));
    343  1.1.1.1.10.2  tls 		nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
    344  1.1.1.1.10.2  tls 		nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
    345  1.1.1.1.10.2  tls 		nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
    346  1.1.1.1.10.2  tls 		nap->na_size = fxdr_hyper(&fp->fa3_size);
    347  1.1.1.1.10.2  tls 		nap->na_blocksize = NFS_FABLKSIZE;
    348  1.1.1.1.10.2  tls 		nap->na_bytes = fxdr_hyper(&fp->fa3_used);
    349  1.1.1.1.10.2  tls 		nap->na_fileid = fxdr_hyper(&fp->fa3_fileid);
    350  1.1.1.1.10.2  tls 		fxdr_nfsv3time(&fp->fa3_atime, &nap->na_atime);
    351  1.1.1.1.10.2  tls 		fxdr_nfsv3time(&fp->fa3_ctime, &nap->na_ctime);
    352  1.1.1.1.10.2  tls 		fxdr_nfsv3time(&fp->fa3_mtime, &nap->na_mtime);
    353  1.1.1.1.10.2  tls 		nap->na_flags = 0;
    354  1.1.1.1.10.2  tls 		nap->na_filerev = 0;
    355  1.1.1.1.10.2  tls 	} else {
    356  1.1.1.1.10.2  tls 		NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V2FATTR);
    357  1.1.1.1.10.2  tls 		nap->na_type = nfsv2tov_type(fp->fa_type);
    358  1.1.1.1.10.2  tls 		nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
    359  1.1.1.1.10.2  tls 		if (nap->na_type == VNON || nap->na_type == VREG)
    360  1.1.1.1.10.2  tls 			nap->na_type = IFTOVT(nap->na_mode);
    361  1.1.1.1.10.2  tls 		nap->na_rdev = fxdr_unsigned(dev_t, fp->fa2_rdev);
    362  1.1.1.1.10.2  tls 
    363  1.1.1.1.10.2  tls 		/*
    364  1.1.1.1.10.2  tls 		 * Really ugly NFSv2 kludge.
    365  1.1.1.1.10.2  tls 		 */
    366  1.1.1.1.10.2  tls 		if (nap->na_type == VCHR && nap->na_rdev == ((dev_t)-1))
    367  1.1.1.1.10.2  tls 			nap->na_type = VFIFO;
    368  1.1.1.1.10.2  tls 		nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
    369  1.1.1.1.10.2  tls 		nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
    370  1.1.1.1.10.2  tls 		nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
    371  1.1.1.1.10.2  tls 		nap->na_size = fxdr_unsigned(u_int32_t, fp->fa2_size);
    372  1.1.1.1.10.2  tls 		nap->na_blocksize = fxdr_unsigned(int32_t, fp->fa2_blocksize);
    373  1.1.1.1.10.2  tls 		nap->na_bytes =
    374  1.1.1.1.10.2  tls 		    (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) *
    375  1.1.1.1.10.2  tls 		    NFS_FABLKSIZE;
    376  1.1.1.1.10.2  tls 		nap->na_fileid = fxdr_unsigned(uint64_t, fp->fa2_fileid);
    377  1.1.1.1.10.2  tls 		fxdr_nfsv2time(&fp->fa2_atime, &nap->na_atime);
    378  1.1.1.1.10.2  tls 		fxdr_nfsv2time(&fp->fa2_mtime, &nap->na_mtime);
    379  1.1.1.1.10.2  tls 		nap->na_flags = 0;
    380  1.1.1.1.10.2  tls 		nap->na_ctime.tv_sec = fxdr_unsigned(u_int32_t,
    381  1.1.1.1.10.2  tls 		    fp->fa2_ctime.nfsv2_sec);
    382  1.1.1.1.10.2  tls 		nap->na_ctime.tv_nsec = 0;
    383  1.1.1.1.10.2  tls 		nap->na_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
    384  1.1.1.1.10.2  tls 		nap->na_filerev = 0;
    385  1.1.1.1.10.2  tls 	}
    386  1.1.1.1.10.2  tls nfsmout:
    387  1.1.1.1.10.2  tls 	return (error);
    388  1.1.1.1.10.2  tls }
    389  1.1.1.1.10.2  tls 
    390  1.1.1.1.10.2  tls /*
    391  1.1.1.1.10.2  tls  * This function finds the directory cookie that corresponds to the
    392  1.1.1.1.10.2  tls  * logical byte offset given.
    393  1.1.1.1.10.2  tls  */
    394  1.1.1.1.10.2  tls APPLESTATIC nfsuint64 *
    395  1.1.1.1.10.2  tls nfscl_getcookie(struct nfsnode *np, off_t off, int add)
    396  1.1.1.1.10.2  tls {
    397  1.1.1.1.10.2  tls 	struct nfsdmap *dp, *dp2;
    398  1.1.1.1.10.2  tls 	int pos;
    399  1.1.1.1.10.2  tls 
    400  1.1.1.1.10.2  tls 	pos = off / NFS_DIRBLKSIZ;
    401  1.1.1.1.10.2  tls 	if (pos == 0) {
    402  1.1.1.1.10.2  tls 		KASSERT(!add, ("nfs getcookie add at 0"));
    403  1.1.1.1.10.2  tls 		return (&nfs_nullcookie);
    404  1.1.1.1.10.2  tls 	}
    405  1.1.1.1.10.2  tls 	pos--;
    406  1.1.1.1.10.2  tls 	dp = LIST_FIRST(&np->n_cookies);
    407  1.1.1.1.10.2  tls 	if (!dp) {
    408  1.1.1.1.10.2  tls 		if (add) {
    409  1.1.1.1.10.2  tls 			MALLOC(dp, struct nfsdmap *, sizeof (struct nfsdmap),
    410  1.1.1.1.10.2  tls 				M_NFSDIROFF, M_WAITOK);
    411  1.1.1.1.10.2  tls 			dp->ndm_eocookie = 0;
    412  1.1.1.1.10.2  tls 			LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
    413  1.1.1.1.10.2  tls 		} else
    414  1.1.1.1.10.2  tls 			return (NULL);
    415  1.1.1.1.10.2  tls 	}
    416  1.1.1.1.10.2  tls 	while (pos >= NFSNUMCOOKIES) {
    417  1.1.1.1.10.2  tls 		pos -= NFSNUMCOOKIES;
    418  1.1.1.1.10.2  tls 		if (LIST_NEXT(dp, ndm_list) != NULL) {
    419  1.1.1.1.10.2  tls 			if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
    420  1.1.1.1.10.2  tls 				pos >= dp->ndm_eocookie)
    421  1.1.1.1.10.2  tls 				return (NULL);
    422  1.1.1.1.10.2  tls 			dp = LIST_NEXT(dp, ndm_list);
    423  1.1.1.1.10.2  tls 		} else if (add) {
    424  1.1.1.1.10.2  tls 			MALLOC(dp2, struct nfsdmap *, sizeof (struct nfsdmap),
    425  1.1.1.1.10.2  tls 				M_NFSDIROFF, M_WAITOK);
    426  1.1.1.1.10.2  tls 			dp2->ndm_eocookie = 0;
    427  1.1.1.1.10.2  tls 			LIST_INSERT_AFTER(dp, dp2, ndm_list);
    428  1.1.1.1.10.2  tls 			dp = dp2;
    429  1.1.1.1.10.2  tls 		} else
    430  1.1.1.1.10.2  tls 			return (NULL);
    431  1.1.1.1.10.2  tls 	}
    432  1.1.1.1.10.2  tls 	if (pos >= dp->ndm_eocookie) {
    433  1.1.1.1.10.2  tls 		if (add)
    434  1.1.1.1.10.2  tls 			dp->ndm_eocookie = pos + 1;
    435  1.1.1.1.10.2  tls 		else
    436  1.1.1.1.10.2  tls 			return (NULL);
    437  1.1.1.1.10.2  tls 	}
    438  1.1.1.1.10.2  tls 	return (&dp->ndm_cookies[pos]);
    439  1.1.1.1.10.2  tls }
    440  1.1.1.1.10.2  tls 
    441  1.1.1.1.10.2  tls /*
    442  1.1.1.1.10.2  tls  * Gets a file handle out of an nfs reply sent to the client and returns
    443  1.1.1.1.10.2  tls  * the file handle and the file's attributes.
    444  1.1.1.1.10.2  tls  * For V4, it assumes that Getfh and Getattr Op's results are here.
    445  1.1.1.1.10.2  tls  */
    446  1.1.1.1.10.2  tls APPLESTATIC int
    447  1.1.1.1.10.2  tls nfscl_mtofh(struct nfsrv_descript *nd, struct nfsfh **nfhpp,
    448  1.1.1.1.10.2  tls     struct nfsvattr *nap, int *attrflagp)
    449  1.1.1.1.10.2  tls {
    450  1.1.1.1.10.2  tls 	u_int32_t *tl;
    451  1.1.1.1.10.2  tls 	int error = 0, flag = 1;
    452  1.1.1.1.10.2  tls 
    453  1.1.1.1.10.2  tls 	*nfhpp = NULL;
    454  1.1.1.1.10.2  tls 	*attrflagp = 0;
    455  1.1.1.1.10.2  tls 	/*
    456  1.1.1.1.10.2  tls 	 * First get the file handle and vnode.
    457  1.1.1.1.10.2  tls 	 */
    458  1.1.1.1.10.2  tls 	if (nd->nd_flag & ND_NFSV3) {
    459  1.1.1.1.10.2  tls 		NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
    460  1.1.1.1.10.2  tls 		flag = fxdr_unsigned(int, *tl);
    461  1.1.1.1.10.2  tls 	} else if (nd->nd_flag & ND_NFSV4) {
    462  1.1.1.1.10.2  tls 		NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
    463  1.1.1.1.10.2  tls 	}
    464  1.1.1.1.10.2  tls 	if (flag) {
    465  1.1.1.1.10.2  tls 		error = nfsm_getfh(nd, nfhpp);
    466  1.1.1.1.10.2  tls 		if (error)
    467  1.1.1.1.10.2  tls 			return (error);
    468  1.1.1.1.10.2  tls 	}
    469  1.1.1.1.10.2  tls 
    470  1.1.1.1.10.2  tls 	/*
    471  1.1.1.1.10.2  tls 	 * Now, get the attributes.
    472  1.1.1.1.10.2  tls 	 */
    473  1.1.1.1.10.2  tls 	if (nd->nd_flag & ND_NFSV4) {
    474  1.1.1.1.10.2  tls 		NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
    475  1.1.1.1.10.2  tls 	} else if (nd->nd_flag & ND_NFSV3) {
    476  1.1.1.1.10.2  tls 		NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
    477  1.1.1.1.10.2  tls 		if (flag) {
    478  1.1.1.1.10.2  tls 			flag = fxdr_unsigned(int, *tl);
    479  1.1.1.1.10.2  tls 		} else if (fxdr_unsigned(int, *tl)) {
    480  1.1.1.1.10.2  tls 			error = nfsm_advance(nd, NFSX_V3FATTR, -1);
    481  1.1.1.1.10.2  tls 			if (error)
    482  1.1.1.1.10.2  tls 				return (error);
    483  1.1.1.1.10.2  tls 		}
    484  1.1.1.1.10.2  tls 	}
    485  1.1.1.1.10.2  tls 	if (flag) {
    486  1.1.1.1.10.2  tls 		error = nfsm_loadattr(nd, nap);
    487  1.1.1.1.10.2  tls 		if (!error)
    488  1.1.1.1.10.2  tls 			*attrflagp = 1;
    489  1.1.1.1.10.2  tls 	}
    490  1.1.1.1.10.2  tls nfsmout:
    491  1.1.1.1.10.2  tls 	return (error);
    492  1.1.1.1.10.2  tls }
    493  1.1.1.1.10.2  tls 
    494  1.1.1.1.10.2  tls /*
    495  1.1.1.1.10.2  tls  * Put a state Id in the mbuf list.
    496  1.1.1.1.10.2  tls  */
    497  1.1.1.1.10.2  tls APPLESTATIC void
    498  1.1.1.1.10.2  tls nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag)
    499  1.1.1.1.10.2  tls {
    500  1.1.1.1.10.2  tls 	nfsv4stateid_t *st;
    501  1.1.1.1.10.2  tls 
    502  1.1.1.1.10.2  tls 	NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID);
    503  1.1.1.1.10.2  tls 	if (flag == NFSSTATEID_PUTALLZERO) {
    504  1.1.1.1.10.2  tls 		st->seqid = 0;
    505  1.1.1.1.10.2  tls 		st->other[0] = 0;
    506  1.1.1.1.10.2  tls 		st->other[1] = 0;
    507  1.1.1.1.10.2  tls 		st->other[2] = 0;
    508  1.1.1.1.10.2  tls 	} else if (flag == NFSSTATEID_PUTALLONE) {
    509  1.1.1.1.10.2  tls 		st->seqid = 0xffffffff;
    510  1.1.1.1.10.2  tls 		st->other[0] = 0xffffffff;
    511  1.1.1.1.10.2  tls 		st->other[1] = 0xffffffff;
    512  1.1.1.1.10.2  tls 		st->other[2] = 0xffffffff;
    513  1.1.1.1.10.2  tls 	} else if (flag == NFSSTATEID_PUTSEQIDZERO) {
    514  1.1.1.1.10.2  tls 		st->seqid = 0;
    515  1.1.1.1.10.2  tls 		st->other[0] = stateidp->other[0];
    516  1.1.1.1.10.2  tls 		st->other[1] = stateidp->other[1];
    517  1.1.1.1.10.2  tls 		st->other[2] = stateidp->other[2];
    518  1.1.1.1.10.2  tls 	} else {
    519  1.1.1.1.10.2  tls 		st->seqid = stateidp->seqid;
    520  1.1.1.1.10.2  tls 		st->other[0] = stateidp->other[0];
    521  1.1.1.1.10.2  tls 		st->other[1] = stateidp->other[1];
    522  1.1.1.1.10.2  tls 		st->other[2] = stateidp->other[2];
    523  1.1.1.1.10.2  tls 	}
    524  1.1.1.1.10.2  tls }
    525  1.1.1.1.10.2  tls 
    526  1.1.1.1.10.2  tls /*
    527  1.1.1.1.10.2  tls  * Initialize the owner/delegation sleep lock.
    528  1.1.1.1.10.2  tls  */
    529  1.1.1.1.10.2  tls APPLESTATIC void
    530  1.1.1.1.10.2  tls nfscl_lockinit(struct nfsv4lock *lckp)
    531  1.1.1.1.10.2  tls {
    532  1.1.1.1.10.2  tls 
    533  1.1.1.1.10.2  tls 	lckp->nfslock_usecnt = 0;
    534  1.1.1.1.10.2  tls 	lckp->nfslock_lock = 0;
    535  1.1.1.1.10.2  tls }
    536  1.1.1.1.10.2  tls 
    537  1.1.1.1.10.2  tls /*
    538  1.1.1.1.10.2  tls  * Get an exclusive lock. (Not needed for OpenBSD4, since there is only one
    539  1.1.1.1.10.2  tls  * thread for each posix process in the kernel.)
    540  1.1.1.1.10.2  tls  */
    541  1.1.1.1.10.2  tls APPLESTATIC void
    542  1.1.1.1.10.2  tls nfscl_lockexcl(struct nfsv4lock *lckp, void *mutex)
    543  1.1.1.1.10.2  tls {
    544  1.1.1.1.10.2  tls 	int igotlock;
    545  1.1.1.1.10.2  tls 
    546  1.1.1.1.10.2  tls 	do {
    547  1.1.1.1.10.2  tls 		igotlock = nfsv4_lock(lckp, 1, NULL, mutex, NULL);
    548  1.1.1.1.10.2  tls 	} while (!igotlock);
    549  1.1.1.1.10.2  tls }
    550  1.1.1.1.10.2  tls 
    551  1.1.1.1.10.2  tls /*
    552  1.1.1.1.10.2  tls  * Release an exclusive lock.
    553  1.1.1.1.10.2  tls  */
    554  1.1.1.1.10.2  tls APPLESTATIC void
    555  1.1.1.1.10.2  tls nfscl_lockunlock(struct nfsv4lock *lckp)
    556  1.1.1.1.10.2  tls {
    557  1.1.1.1.10.2  tls 
    558  1.1.1.1.10.2  tls 	nfsv4_unlock(lckp, 0);
    559  1.1.1.1.10.2  tls }
    560  1.1.1.1.10.2  tls 
    561  1.1.1.1.10.2  tls /*
    562  1.1.1.1.10.2  tls  * Called to derefernce a lock on a stateid (delegation or open owner).
    563  1.1.1.1.10.2  tls  */
    564  1.1.1.1.10.2  tls APPLESTATIC void
    565  1.1.1.1.10.2  tls nfscl_lockderef(struct nfsv4lock *lckp)
    566  1.1.1.1.10.2  tls {
    567  1.1.1.1.10.2  tls 
    568  1.1.1.1.10.2  tls 	NFSLOCKCLSTATE();
    569  1.1.1.1.10.2  tls 	lckp->nfslock_usecnt--;
    570  1.1.1.1.10.2  tls 	if (lckp->nfslock_usecnt == 0 && (lckp->nfslock_lock & NFSV4LOCK_WANTED)) {
    571  1.1.1.1.10.2  tls 		lckp->nfslock_lock &= ~NFSV4LOCK_WANTED;
    572  1.1.1.1.10.2  tls 		wakeup((caddr_t)lckp);
    573  1.1.1.1.10.2  tls 	}
    574  1.1.1.1.10.2  tls 	NFSUNLOCKCLSTATE();
    575  1.1.1.1.10.2  tls }
    576  1.1.1.1.10.2  tls 
    577