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