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