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