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