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