2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
39 * nfs version 2 and 3 server calls to vnode ops
40 * - these routines generally have 3 phases
41 * 1 - break down and validate rpc request in mbuf list
42 * 2 - do the vnode ops for the request
43 * (surprisingly ?? many are very similar to syscalls in vfs_syscalls.c)
44 * 3 - build the rpc reply in an mbuf list
46 * - do not mix the phases, since the nfsm_?? macros can return failures
47 * on a bad rpc or similar and do not do any vrele() or vput()'s
49 * - the nfsm_reply() macro generates an nfs rpc reply with the nfs
50 * error number iff error != 0 whereas
51 * returning an error from the server function implies a fatal error
52 * such as a badly constructed rpc request that should be dropped without
54 * For nfsm_reply(), the case where error == EBADRPC is treated
55 * specially; after constructing a reply, it does an immediate
56 * `goto nfsmout' to avoid getting any V3 post-op status appended.
59 * Warning: always pay careful attention to resource cleanup on return
60 * and note that nfsm_*() macros can terminate a procedure on certain
63 * lookup() and namei()
64 * may return garbage in various structural fields/return elements
65 * if an error is returned, and may garbage up nd.ni_dvp even if no
66 * error is returned and you did not request LOCKPARENT or WANTPARENT.
68 * We use the ni_cnd.cn_flags 'HASBUF' flag to track whether the name
69 * buffer has been freed or not.
72 #include <sys/param.h>
73 #include <sys/systm.h>
75 #include <sys/namei.h>
76 #include <sys/unistd.h>
77 #include <sys/vnode.h>
78 #include <sys/mount.h>
79 #include <sys/socket.h>
80 #include <sys/socketvar.h>
81 #include <sys/malloc.h>
84 #include <sys/dirent.h>
86 #include <sys/kernel.h>
87 #include <sys/sysctl.h>
92 #include <vm/vm_extern.h>
93 #include <vm/vm_object.h>
95 #include <nfs/nfsproto.h>
96 #include <nfsserver/nfs.h>
97 #include <nfs/xdr_subs.h>
98 #include <nfsserver/nfsm_subs.h>
100 FEATURE(nfsserver, "NFS server");
103 #define nfsdbprintf(info) printf info
105 #define nfsdbprintf(info)
108 #define MAX_COMMIT_COUNT (1024 * 1024)
110 #define NUM_HEURISTIC 1017
111 #define NHUSE_INIT 64
113 #define NHUSE_MAX 2048
115 static struct nfsheur {
116 struct vnode *nh_vp; /* vp to match (unreferenced pointer) */
117 off_t nh_nextr; /* next offset for sequential detection */
118 int nh_use; /* use count for selection */
119 int nh_seqcount; /* heuristic */
120 } nfsheur[NUM_HEURISTIC];
124 int nfsrvw_procrastinate = NFS_GATHERDELAY * 1000;
125 int nfsrvw_procrastinate_v3 = 0;
127 static struct timeval nfsver = { 0 };
129 SYSCTL_NODE(_vfs, OID_AUTO, nfsrv, CTLFLAG_RW, 0, "NFS server");
131 static int nfs_async;
132 static int nfs_commit_blks;
133 static int nfs_commit_miss;
134 SYSCTL_INT(_vfs_nfsrv, OID_AUTO, async, CTLFLAG_RW, &nfs_async, 0,
135 "Tell client that writes were synced even though they were not");
136 SYSCTL_INT(_vfs_nfsrv, OID_AUTO, commit_blks, CTLFLAG_RW, &nfs_commit_blks, 0,
137 "Number of completed commits");
138 SYSCTL_INT(_vfs_nfsrv, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss, 0, "");
140 struct nfsrvstats nfsrvstats;
141 SYSCTL_STRUCT(_vfs_nfsrv, NFS_NFSRVSTATS, nfsrvstats, CTLFLAG_RW,
142 &nfsrvstats, nfsrvstats, "S,nfsrvstats");
144 static int nfsrv_access(struct vnode *, accmode_t, struct ucred *,
148 * Clear nameidata fields that are tested in nsfmout cleanup code prior
149 * to using first nfsm macro (that might jump to the cleanup code).
153 ndclear(struct nameidata *nd)
156 nd->ni_cnd.cn_flags = 0;
159 nd->ni_startdir = NULL;
160 nd->ni_strictrelative = 0;
164 * Takes two vfslocked integers and returns with at most one
165 * reference to giant. The return value indicates whether giant
166 * is held by either lock. This simplifies nfsrv ops by allowing
167 * them to track only one vfslocked var.
170 nfsrv_lockedpair(int vfs1, int vfs2)
174 VFS_UNLOCK_GIANT(vfs2);
176 return (vfs1 | vfs2);
180 nfsrv_lockedpair_nd(int vfs1, struct nameidata *nd)
184 vfs2 = NDHASGIANT(nd);
186 return nfsrv_lockedpair(vfs1, vfs2);
190 * nfs v3 access service
193 nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
196 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
197 struct sockaddr *nam = nfsd->nd_nam;
198 caddr_t dpos = nfsd->nd_dpos;
199 struct ucred *cred = nfsd->nd_cr;
200 struct vnode *vp = NULL;
205 int error = 0, rdonly, getret;
206 struct mbuf *mb, *mreq;
207 struct vattr vattr, *vap = &vattr;
208 u_long testmode, nfsmode;
209 int v3 = (nfsd->nd_flag & ND_NFSV3);
212 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
214 panic("nfsrv3_access: v3 proc called on a v2 connection");
216 fhp = &nfh.fh_generic;
218 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
219 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
221 nfsm_reply(NFSX_UNSIGNED);
222 nfsm_srvpostop_attr(1, NULL);
226 nfsmode = fxdr_unsigned(u_int32_t, *tl);
227 if ((nfsmode & NFSV3ACCESS_READ) &&
228 nfsrv_access(vp, VREAD, cred, rdonly, 0))
229 nfsmode &= ~NFSV3ACCESS_READ;
230 if (vp->v_type == VDIR)
231 testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
234 testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
235 if ((nfsmode & testmode) &&
236 nfsrv_access(vp, VWRITE, cred, rdonly, 0))
237 nfsmode &= ~testmode;
238 if (vp->v_type == VDIR)
239 testmode = NFSV3ACCESS_LOOKUP;
241 testmode = NFSV3ACCESS_EXECUTE;
242 if ((nfsmode & testmode) &&
243 nfsrv_access(vp, VEXEC, cred, rdonly, 0))
244 nfsmode &= ~testmode;
245 getret = VOP_GETATTR(vp, vap, cred);
248 nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED);
249 nfsm_srvpostop_attr(getret, vap);
250 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
251 *tl = txdr_unsigned(nfsmode);
255 VFS_UNLOCK_GIANT(vfslocked);
260 * nfs getattr service
263 nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
266 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
267 struct sockaddr *nam = nfsd->nd_nam;
268 caddr_t dpos = nfsd->nd_dpos;
269 struct ucred *cred = nfsd->nd_cr;
270 struct nfs_fattr *fp;
272 struct vattr *vap = &va;
273 struct vnode *vp = NULL;
277 int error = 0, rdonly;
278 struct mbuf *mb, *mreq;
281 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
283 fhp = &nfh.fh_generic;
285 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
291 error = VOP_GETATTR(vp, vap, cred);
294 nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
299 fp = nfsm_build(struct nfs_fattr *,
300 NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
301 nfsm_srvfillattr(vap, fp);
307 VFS_UNLOCK_GIANT(vfslocked);
312 * nfs setattr service
315 nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
318 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
319 struct sockaddr *nam = nfsd->nd_nam;
320 caddr_t dpos = nfsd->nd_dpos;
321 struct ucred *cred = nfsd->nd_cr;
322 struct vattr va, preat;
323 struct vattr *vap = &va;
324 struct nfsv2_sattr *sp;
325 struct nfs_fattr *fp;
326 struct vnode *vp = NULL;
331 int error = 0, rdonly, preat_ret = 1, postat_ret = 1;
332 int v3 = (nfsd->nd_flag & ND_NFSV3), gcheck = 0;
333 struct mbuf *mb, *mreq;
334 struct timespec guard = { 0, 0 };
335 struct mount *mp = NULL;
339 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
341 fhp = &nfh.fh_generic;
343 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
347 vfslocked = VFS_LOCK_GIANT(mp);
348 (void) vn_start_write(NULL, &mp, V_WAIT);
349 vfs_rel(mp); /* The write holds a ref. */
353 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
354 gcheck = fxdr_unsigned(int, *tl);
356 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
357 fxdr_nfsv3time(tl, &guard);
360 sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
362 * Nah nah nah nah na nah
363 * There is a bug in the Sun client that puts 0xffff in the mode
364 * field of sattr when it should put in 0xffffffff. The u_short
365 * doesn't sign extend.
366 * --> check the low order 2 bytes for 0xffff
368 if ((fxdr_unsigned(int, sp->sa_mode) & 0xffff) != 0xffff)
369 vap->va_mode = nfstov_mode(sp->sa_mode);
370 if (sp->sa_uid != nfsrv_nfs_xdrneg1)
371 vap->va_uid = fxdr_unsigned(uid_t, sp->sa_uid);
372 if (sp->sa_gid != nfsrv_nfs_xdrneg1)
373 vap->va_gid = fxdr_unsigned(gid_t, sp->sa_gid);
374 if (sp->sa_size != nfsrv_nfs_xdrneg1)
375 vap->va_size = fxdr_unsigned(u_quad_t, sp->sa_size);
376 if (sp->sa_atime.nfsv2_sec != nfsrv_nfs_xdrneg1) {
378 fxdr_nfsv2time(&sp->sa_atime, &vap->va_atime);
380 vap->va_atime.tv_sec =
381 fxdr_unsigned(int32_t, sp->sa_atime.nfsv2_sec);
382 vap->va_atime.tv_nsec = 0;
385 if (sp->sa_mtime.nfsv2_sec != nfsrv_nfs_xdrneg1)
386 fxdr_nfsv2time(&sp->sa_mtime, &vap->va_mtime);
391 * Now that we have all the fields, lets do it.
393 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
394 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
396 nfsm_reply(2 * NFSX_UNSIGNED);
398 nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
404 * vp now an active resource, pay careful attention to cleanup
407 error = preat_ret = VOP_GETATTR(vp, &preat, cred);
408 if (!error && gcheck &&
409 (preat.va_ctime.tv_sec != guard.tv_sec ||
410 preat.va_ctime.tv_nsec != guard.tv_nsec))
411 error = NFSERR_NOT_SYNC;
415 nfsm_reply(NFSX_WCCDATA(v3));
417 nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
424 * If the size is being changed write acces is required, otherwise
425 * just check for a read only filesystem.
427 if (vap->va_size == ((u_quad_t)((quad_t) -1))) {
428 if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
433 if (vp->v_type == VDIR) {
436 } else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly,
440 error = VOP_SETATTR(vp, vap, cred);
441 postat_ret = VOP_GETATTR(vp, vap, cred);
449 nfsm_reply(NFSX_WCCORFATTR(v3));
451 nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
453 /* v2 non-error case. */
454 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
455 nfsm_srvfillattr(vap, fp);
463 vn_finished_write(mp);
464 VFS_UNLOCK_GIANT(vfslocked);
472 nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
475 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
476 struct sockaddr *nam = nfsd->nd_nam;
477 caddr_t dpos = nfsd->nd_dpos;
478 struct ucred *cred = nfsd->nd_cr;
479 struct nfs_fattr *fp;
480 struct nameidata nd, ind, *ndp = &nd;
481 struct vnode *vp, *dirp = NULL;
485 int error = 0, len, dirattr_ret = 1;
486 int v3 = (nfsd->nd_flag & ND_NFSV3), pubflag;
487 struct mbuf *mb, *mreq;
488 struct vattr va, dirattr, *vap = &va;
492 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
496 fhp = &nfh.fh_generic;
498 nfsm_srvnamesiz(len);
500 pubflag = nfs_ispublicfh(fhp);
502 nd.ni_cnd.cn_cred = cred;
503 nd.ni_cnd.cn_nameiop = LOOKUP;
504 nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART | MPSAFE;
505 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
506 &dirp, v3, &dirattr, &dirattr_ret, pubflag);
507 vfslocked = NDHASGIANT(&nd);
510 * namei failure, only dirp to cleanup. Clear out garbarge from
511 * structure in case macros jump to nfsmout.
519 nfsm_reply(NFSX_POSTOPATTR(v3));
521 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
527 * Locate index file for public filehandle
529 * error is 0 on entry and 0 on exit from this block.
533 if (nd.ni_vp->v_type == VDIR && nfs_pub.np_index != NULL) {
535 * Setup call to lookup() to see if we can find
536 * the index file. Arguably, this doesn't belong
537 * in a kernel.. Ugh. If an error occurs, do not
538 * try to install an index file and then clear the
541 * When we replace nd with ind and redirect ndp,
542 * maintenance of ni_startdir and ni_vp shift to
543 * ind and we have to clean them up in the old nd.
544 * However, the cnd resource continues to be maintained
545 * via the original nd. Confused? You aren't alone!
548 VOP_UNLOCK(nd.ni_vp, 0);
549 ind.ni_pathlen = strlen(nfs_pub.np_index);
550 ind.ni_cnd.cn_nameptr = ind.ni_cnd.cn_pnbuf =
552 ind.ni_startdir = nd.ni_vp;
553 VREF(ind.ni_startdir);
554 ind.ni_cnd.cn_flags &= ~GIANTHELD;
555 tvfslocked = VFS_LOCK_GIANT(ind.ni_startdir->v_mount);
557 nd.ni_cnd.cn_flags |= GIANTHELD;
558 error = lookup(&ind);
560 vfslocked = nfsrv_lockedpair_nd(vfslocked, &ind);
561 ind.ni_cnd.cn_flags &= ~GIANTHELD;
565 * Found an index file. Get rid of
566 * the old references. transfer nd.ni_vp'
572 vrele(nd.ni_startdir);
573 nd.ni_startdir = NULL;
579 * If the public filehandle was used, check that this lookup
580 * didn't result in a filehandle outside the publicly exported
581 * filesystem. We clear the poor vp here to avoid lockups due
585 if (ndp->ni_vp->v_mount != nfs_pub.np_mount) {
593 * Resources at this point:
594 * ndp->ni_vp may not be NULL
598 nfsm_reply(NFSX_POSTOPATTR(v3));
600 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
606 * Get underlying attribute, then release remaining resources ( for
607 * the same potential blocking reason ) and reply.
610 bzero((caddr_t)fhp, sizeof(nfh));
611 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
612 error = VOP_VPTOFH(vp, &fhp->fh_fid);
614 error = VOP_GETATTR(vp, vap, cred);
617 vrele(ndp->ni_startdir);
620 ndp->ni_startdir = NULL;
622 nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
625 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
629 nfsm_srvfhtom(fhp, v3);
631 nfsm_srvpostop_attr(0, vap);
632 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
634 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
635 nfsm_srvfillattr(vap, fp);
639 if (ndp->ni_vp || dirp || ndp->ni_startdir) {
644 if (ndp->ni_startdir)
645 vrele(ndp->ni_startdir);
647 NDFREE(&nd, NDF_ONLY_PNBUF);
648 VFS_UNLOCK_GIANT(vfslocked);
653 * nfs readlink service
656 nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
659 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
660 struct sockaddr *nam = nfsd->nd_nam;
661 caddr_t dpos = nfsd->nd_dpos;
662 struct ucred *cred = nfsd->nd_cr;
663 struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN];
664 struct iovec *ivp = iv;
668 int error = 0, rdonly, i, tlen, len, getret;
669 int v3 = (nfsd->nd_flag & ND_NFSV3);
670 struct mbuf *mb, *mp3, *nmp, *mreq;
671 struct vnode *vp = NULL;
675 struct uio io, *uiop = &io;
678 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
684 fhp = &nfh.fh_generic;
688 while (len < NFS_MAXPATHLEN) {
689 MGET(nmp, M_WAIT, MT_DATA);
691 nmp->m_len = NFSMSIZ(nmp);
698 if ((len + mp->m_len) > NFS_MAXPATHLEN) {
699 mp->m_len = NFS_MAXPATHLEN - len;
700 len = NFS_MAXPATHLEN;
703 ivp->iov_base = mtod(mp, caddr_t);
704 ivp->iov_len = mp->m_len;
709 uiop->uio_iovcnt = i;
710 uiop->uio_offset = 0;
711 uiop->uio_resid = len;
712 uiop->uio_rw = UIO_READ;
713 uiop->uio_segflg = UIO_SYSSPACE;
715 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
717 nfsm_reply(2 * NFSX_UNSIGNED);
719 nfsm_srvpostop_attr(1, NULL);
723 if (vp->v_type != VLNK) {
729 error = VOP_READLINK(vp, uiop, cred);
730 getret = VOP_GETATTR(vp, &attr, cred);
733 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED);
735 nfsm_srvpostop_attr(getret, &attr);
740 if (uiop->uio_resid > 0) {
741 len -= uiop->uio_resid;
742 tlen = nfsm_rndup(len);
743 nfsm_adj(mp3, NFS_MAXPATHLEN-tlen, tlen-len);
745 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
746 *tl = txdr_unsigned(len);
754 VFS_UNLOCK_GIANT(vfslocked);
762 nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
765 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
766 struct sockaddr *nam = nfsd->nd_nam;
767 caddr_t dpos = nfsd->nd_dpos;
768 struct ucred *cred = nfsd->nd_cr;
772 struct nfs_fattr *fp;
776 int error = 0, rdonly, cnt, len, left, siz, tlen, getret;
777 int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen;
778 struct mbuf *mb, *mreq;
780 struct vnode *vp = NULL;
783 struct uio io, *uiop = &io;
784 struct vattr va, *vap = &va;
791 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
793 fhp = &nfh.fh_generic;
796 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
797 off = fxdr_hyper(tl);
799 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
800 off = (off_t)fxdr_unsigned(u_int32_t, *tl);
802 nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd));
805 * Reference vp. If an error occurs, vp will be invalid, but we
806 * have to NULL it just in case. The macros might goto nfsmout
810 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
813 nfsm_reply(2 * NFSX_UNSIGNED);
815 nfsm_srvpostop_attr(1, NULL);
820 if (vp->v_type != VREG) {
824 error = (vp->v_type == VDIR) ? EISDIR : EACCES;
827 if ((error = nfsrv_access(vp, VREAD, cred, rdonly, 1)) != 0)
828 error = nfsrv_access(vp, VEXEC, cred, rdonly, 1);
830 getret = VOP_GETATTR(vp, vap, cred);
836 nfsm_reply(NFSX_POSTOPATTR(v3));
838 nfsm_srvpostop_attr(getret, vap);
844 * Calculate byte count to read
847 if (off >= vap->va_size)
849 else if ((off + reqlen) > vap->va_size)
850 cnt = vap->va_size - off;
855 * Calculate seqcount for heuristic
863 * Locate best candidate
866 hi = ((int)(vm_offset_t)vp / sizeof(struct vnode)) % NUM_HEURISTIC;
870 if (nfsheur[hi].nh_vp == vp) {
874 if (nfsheur[hi].nh_use > 0)
875 --nfsheur[hi].nh_use;
876 hi = (hi + 1) % NUM_HEURISTIC;
877 if (nfsheur[hi].nh_use < nh->nh_use)
881 if (nh->nh_vp != vp) {
884 nh->nh_use = NHUSE_INIT;
892 * Calculate heuristic
895 if ((off == 0 && nh->nh_seqcount > 0) || off == nh->nh_nextr) {
896 if (++nh->nh_seqcount > IO_SEQMAX)
897 nh->nh_seqcount = IO_SEQMAX;
898 } else if (nh->nh_seqcount > 1) {
903 nh->nh_use += NHUSE_INC;
904 if (nh->nh_use > NHUSE_MAX)
905 nh->nh_use = NHUSE_MAX;
906 ioflag |= nh->nh_seqcount << IO_SEQSHIFT;
909 nfsm_reply(NFSX_POSTOPORFATTR(v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt));
911 tl = nfsm_build(u_int32_t *, NFSX_V3FATTR + 4 * NFSX_UNSIGNED);
912 *tl++ = nfsrv_nfs_true;
913 fp = (struct nfs_fattr *)tl;
914 tl += (NFSX_V3FATTR / sizeof (u_int32_t));
916 tl = nfsm_build(u_int32_t *, NFSX_V2FATTR + NFSX_UNSIGNED);
917 fp = (struct nfs_fattr *)tl;
918 tl += (NFSX_V2FATTR / sizeof (u_int32_t));
920 len = left = nfsm_rndup(cnt);
923 * Generate the mbuf list with the uio_iov ref. to it.
928 siz = min(M_TRAILINGSPACE(m), left);
934 MGET(m, M_WAIT, MT_DATA);
941 iv = malloc(i * sizeof (struct iovec),
943 uiop->uio_iov = iv2 = iv;
949 panic("nfsrv_read iov");
950 siz = min(M_TRAILINGSPACE(m), left);
952 iv->iov_base = mtod(m, caddr_t) + m->m_len;
961 uiop->uio_iovcnt = i;
962 uiop->uio_offset = off;
963 uiop->uio_resid = len;
964 uiop->uio_rw = UIO_READ;
965 uiop->uio_segflg = UIO_SYSSPACE;
966 error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred);
967 off = uiop->uio_offset;
969 free((caddr_t)iv2, M_TEMP);
970 if (error || (getret = VOP_GETATTR(vp, vap, cred))) {
976 nfsm_reply(NFSX_POSTOPATTR(v3));
978 nfsm_srvpostop_attr(getret, vap);
986 nfsm_srvfillattr(vap, fp);
987 tlen = len - uiop->uio_resid;
988 cnt = cnt < tlen ? cnt : tlen;
989 tlen = nfsm_rndup(cnt);
990 if (len != tlen || tlen != cnt)
991 nfsm_adj(mb, len - tlen, tlen - cnt);
993 *tl++ = txdr_unsigned(cnt);
995 *tl++ = nfsrv_nfs_true;
997 *tl++ = nfsrv_nfs_false;
999 *tl = txdr_unsigned(cnt);
1003 VFS_UNLOCK_GIANT(vfslocked);
1011 nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1014 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1015 struct sockaddr *nam = nfsd->nd_nam;
1016 caddr_t dpos = nfsd->nd_dpos;
1017 struct ucred *cred = nfsd->nd_cr;
1021 struct nfs_fattr *fp;
1023 struct vattr va, forat;
1024 struct vattr *vap = &va;
1027 int error = 0, rdonly, len, forat_ret = 1;
1028 int ioflags, aftat_ret = 1, retlen = 0, zeroing, adjust;
1029 int stable = NFSV3WRITE_FILESYNC;
1030 int v3 = (nfsd->nd_flag & ND_NFSV3);
1031 struct mbuf *mb, *mreq;
1032 struct vnode *vp = NULL;
1035 struct uio io, *uiop = &io;
1037 struct mount *mntp = NULL;
1041 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1048 fhp = &nfh.fh_generic;
1050 if ((mntp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1054 vfslocked = VFS_LOCK_GIANT(mntp);
1055 (void) vn_start_write(NULL, &mntp, V_WAIT);
1056 vfs_rel(mntp); /* The write holds a ref. */
1058 tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED);
1059 off = fxdr_hyper(tl);
1061 stable = fxdr_unsigned(int, *tl++);
1063 tl = nfsm_dissect_nonblock(u_int32_t *, 4 * NFSX_UNSIGNED);
1064 off = (off_t)fxdr_unsigned(u_int32_t, *++tl);
1067 stable = NFSV3WRITE_UNSTABLE;
1069 retlen = len = fxdr_unsigned(int32_t, *tl);
1073 * For NFS Version 2, it is not obvious what a write of zero length
1074 * should do, but I might as well be consistent with Version 3,
1075 * which is to return ok so long as there are no permission problems.
1083 adjust = dpos - mtod(mp, caddr_t);
1084 mp->m_len -= adjust;
1085 if (mp->m_len > 0 && adjust > 0)
1086 mp->m_data += adjust;
1090 else if (mp->m_len > 0) {
1093 mp->m_len -= (i - len);
1102 if (len > NFS_MAXDATA || len < 0 || i < len) {
1104 nfsm_reply(2 * NFSX_UNSIGNED);
1106 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1110 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
1111 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
1114 nfsm_reply(2 * NFSX_UNSIGNED);
1116 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1121 forat_ret = VOP_GETATTR(vp, &forat, cred);
1122 if (vp->v_type != VREG) {
1126 error = (vp->v_type == VDIR) ? EISDIR : EACCES;
1129 error = nfsrv_access(vp, VWRITE, cred, rdonly, 1);
1133 nfsm_reply(NFSX_WCCDATA(v3));
1135 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1141 ivp = malloc(cnt * sizeof (struct iovec), M_TEMP,
1143 uiop->uio_iov = iv = ivp;
1144 uiop->uio_iovcnt = cnt;
1147 if (mp->m_len > 0) {
1148 ivp->iov_base = mtod(mp, caddr_t);
1149 ivp->iov_len = mp->m_len;
1157 * The IO_METASYNC flag indicates that all metadata (and not just
1158 * enough to ensure data integrity) mus be written to stable storage
1160 * (IO_METASYNC is not yet implemented in 4.4BSD-Lite.)
1162 if (stable == NFSV3WRITE_UNSTABLE)
1163 ioflags = IO_NODELOCKED;
1164 else if (stable == NFSV3WRITE_DATASYNC)
1165 ioflags = (IO_SYNC | IO_NODELOCKED);
1167 ioflags = (IO_METASYNC | IO_SYNC | IO_NODELOCKED);
1168 uiop->uio_resid = len;
1169 uiop->uio_rw = UIO_WRITE;
1170 uiop->uio_segflg = UIO_SYSSPACE;
1171 uiop->uio_td = NULL;
1172 uiop->uio_offset = off;
1173 error = VOP_WRITE(vp, uiop, ioflags, cred);
1174 /* Unlocked write. */
1175 nfsrvstats.srvvop_writes++;
1176 free((caddr_t)iv, M_TEMP);
1178 aftat_ret = VOP_GETATTR(vp, vap, cred);
1184 nfsm_reply(NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) +
1185 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(v3));
1187 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1192 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
1193 *tl++ = txdr_unsigned(retlen);
1195 * If nfs_async is set, then pretend the write was FILESYNC.
1197 if (stable == NFSV3WRITE_UNSTABLE && !nfs_async)
1198 *tl++ = txdr_unsigned(stable);
1200 *tl++ = txdr_unsigned(NFSV3WRITE_FILESYNC);
1202 * Actually, there is no need to txdr these fields,
1203 * but it may make the values more human readable,
1204 * for debugging purposes.
1206 if (nfsver.tv_sec == 0)
1208 *tl++ = txdr_unsigned(nfsver.tv_sec);
1209 *tl = txdr_unsigned(nfsver.tv_usec);
1210 } else if (!error) {
1211 /* v2 non-error case. */
1212 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
1213 nfsm_srvfillattr(vap, fp);
1219 vn_finished_write(mntp);
1220 VFS_UNLOCK_GIANT(vfslocked);
1225 * nfs create service
1226 * now does a truncate to 0 length via. setattr if it already exists
1229 nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1232 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1233 struct sockaddr *nam = nfsd->nd_nam;
1234 caddr_t dpos = nfsd->nd_dpos;
1235 struct ucred *cred = nfsd->nd_cr;
1236 struct nfs_fattr *fp;
1237 struct vattr va, dirfor, diraft;
1238 struct vattr *vap = &va;
1239 struct nfsv2_sattr *sp;
1241 struct nameidata nd;
1243 int error = 0, rdev, len, tsize, dirfor_ret = 1, diraft_ret = 1;
1244 int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0;
1245 struct mbuf *mb, *mreq;
1246 struct vnode *dirp = NULL;
1250 struct timespec cverf;
1251 struct mount *mp = NULL;
1255 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1262 fhp = &nfh.fh_generic;
1264 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1268 vfslocked = VFS_LOCK_GIANT(mp);
1269 (void) vn_start_write(NULL, &mp, V_WAIT);
1270 vfs_rel(mp); /* The write holds a ref. */
1271 nfsm_srvnamesiz(len);
1273 nd.ni_cnd.cn_cred = cred;
1274 nd.ni_cnd.cn_nameiop = CREATE;
1275 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE;
1278 * Call namei and do initial cleanup to get a few things
1279 * out of the way. If we get an initial error we cleanup
1280 * and return here to avoid special-casing the invalid nd
1281 * structure through the rest of the case. dirp may be
1282 * set even if an error occurs, but the nd structure will not
1283 * be valid at all if an error occurs so we have to invalidate it
1284 * prior to calling nfsm_reply ( which might goto nfsmout ).
1286 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
1287 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
1288 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1294 nfsm_reply(NFSX_WCCDATA(v3));
1296 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1302 * No error. Continue. State:
1304 * startdir is valid ( we release this immediately )
1306 * nd.ni_vp may be valid
1307 * nd.ni_dvp is valid
1309 * The error state is set through the code and we may also do some
1310 * opportunistic releasing of vnodes to avoid holding locks through
1311 * NFS I/O. The cleanup at the end is a catch-all
1316 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
1317 how = fxdr_unsigned(int, *tl);
1319 case NFSV3CREATE_GUARDED:
1325 case NFSV3CREATE_UNCHECKED:
1328 case NFSV3CREATE_EXCLUSIVE:
1329 tl = nfsm_dissect_nonblock(u_int32_t *,
1331 /* Unique bytes, endianness is not important. */
1332 cverf.tv_sec = (int32_t)tl[0];
1333 cverf.tv_nsec = tl[1];
1337 vap->va_type = VREG;
1339 sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
1340 vap->va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode));
1341 if (vap->va_type == VNON)
1342 vap->va_type = VREG;
1343 vap->va_mode = nfstov_mode(sp->sa_mode);
1344 switch (vap->va_type) {
1346 tsize = fxdr_unsigned(int32_t, sp->sa_size);
1348 vap->va_size = (u_quad_t)tsize;
1353 rdev = fxdr_unsigned(long, sp->sa_size);
1361 * Iff doesn't exist, create it
1362 * otherwise just truncate to 0 length
1363 * should I set the mode too ?
1365 * The only possible error we can have at this point is EEXIST.
1366 * nd.ni_vp will also be non-NULL in that case.
1368 if (nd.ni_vp == NULL) {
1369 if (vap->va_mode == (mode_t)VNOVAL)
1371 if (vap->va_type == VREG || vap->va_type == VSOCK) {
1372 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1374 NDFREE(&nd, NDF_ONLY_PNBUF);
1376 if (exclusive_flag) {
1379 vap->va_atime = cverf;
1380 error = VOP_SETATTR(nd.ni_vp, vap,
1384 } else if (vap->va_type == VCHR || vap->va_type == VBLK ||
1385 vap->va_type == VFIFO) {
1387 * NFSv2-specific code for creating device nodes
1390 * Handle SysV FIFO node special cases. All other
1391 * devices require super user to access.
1393 if (vap->va_type == VCHR && rdev == 0xffffffff)
1394 vap->va_type = VFIFO;
1395 if (vap->va_type != VFIFO &&
1396 (error = priv_check_cred(cred, PRIV_VFS_MKNOD_DEV,
1400 vap->va_rdev = rdev;
1401 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1403 NDFREE(&nd, NDF_ONLY_PNBUF);
1410 * release dvp prior to lookup
1417 * Even though LOCKPARENT was cleared, ni_dvp may
1420 nd.ni_cnd.cn_nameiop = LOOKUP;
1421 nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
1422 nd.ni_cnd.cn_thread = curthread;
1423 nd.ni_cnd.cn_cred = cred;
1424 tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
1426 nd.ni_cnd.cn_flags |= GIANTHELD;
1427 error = lookup(&nd);
1429 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1430 nd.ni_cnd.cn_flags &= ~GIANTHELD;
1434 if (nd.ni_cnd.cn_flags & ISSYMLINK) {
1442 if (vap->va_size != -1) {
1443 error = nfsrv_access(nd.ni_vp, VWRITE,
1444 cred, (nd.ni_cnd.cn_flags & RDONLY), 0);
1446 tempsize = vap->va_size;
1448 vap->va_size = tempsize;
1449 error = VOP_SETATTR(nd.ni_vp, vap, cred);
1455 bzero((caddr_t)fhp, sizeof(nfh));
1456 fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
1457 error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
1459 error = VOP_GETATTR(nd.ni_vp, vap, cred);
1462 if (exclusive_flag && !error &&
1463 bcmp(&cverf, &vap->va_atime, sizeof (cverf)))
1465 if (dirp == nd.ni_dvp)
1466 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1468 /* Drop the other locks to avoid deadlock. */
1470 if (nd.ni_dvp == nd.ni_vp)
1480 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
1481 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1482 VOP_UNLOCK(dirp, 0);
1486 nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
1489 nfsm_srvpostop_fh(fhp);
1490 nfsm_srvpostop_attr(0, vap);
1492 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1493 } else if (!error) {
1494 /* v2 non-error case. */
1495 nfsm_srvfhtom(fhp, v3);
1496 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
1497 nfsm_srvfillattr(vap, fp);
1503 if (nd.ni_dvp == nd.ni_vp)
1510 if (nd.ni_startdir) {
1511 vrele(nd.ni_startdir);
1512 nd.ni_startdir = NULL;
1516 NDFREE(&nd, NDF_ONLY_PNBUF);
1517 vn_finished_write(mp);
1518 VFS_UNLOCK_GIANT(vfslocked);
1523 * nfs v3 mknod service
1526 nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1529 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1530 struct sockaddr *nam = nfsd->nd_nam;
1531 caddr_t dpos = nfsd->nd_dpos;
1532 struct ucred *cred = nfsd->nd_cr;
1533 struct vattr va, dirfor, diraft;
1534 struct vattr *vap = &va;
1535 struct thread *td = curthread;
1537 struct nameidata nd;
1539 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1540 u_int32_t major, minor;
1542 struct mbuf *mb, *mreq;
1543 struct vnode *vp, *dirp = NULL;
1546 struct mount *mp = NULL;
1547 int v3 = (nfsd->nd_flag & ND_NFSV3);
1551 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1554 panic("nfsrv_mknod: v3 proc called on a v2 connection");
1557 fhp = &nfh.fh_generic;
1559 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1563 vfslocked = VFS_LOCK_GIANT(mp);
1564 (void) vn_start_write(NULL, &mp, V_WAIT);
1565 vfs_rel(mp); /* The write holds a ref. */
1566 nfsm_srvnamesiz(len);
1568 nd.ni_cnd.cn_cred = cred;
1569 nd.ni_cnd.cn_nameiop = CREATE;
1570 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE;
1573 * Handle nfs_namei() call. If an error occurs, the nd structure
1574 * is not valid. However, nfsm_*() routines may still jump to
1578 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
1579 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
1580 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1582 nfsm_reply(NFSX_WCCDATA(1));
1583 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1587 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
1588 vtyp = nfsv3tov_type(*tl);
1589 if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
1590 error = NFSERR_BADTYPE;
1595 if (vtyp == VCHR || vtyp == VBLK) {
1596 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
1597 major = fxdr_unsigned(u_int32_t, *tl++);
1598 minor = fxdr_unsigned(u_int32_t, *tl);
1599 vap->va_rdev = makedev(major, minor);
1603 * Iff doesn't exist, create it.
1609 vap->va_type = vtyp;
1610 if (vap->va_mode == (mode_t)VNOVAL)
1612 if (vtyp == VSOCK) {
1613 vrele(nd.ni_startdir);
1614 nd.ni_startdir = NULL;
1615 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1617 NDFREE(&nd, NDF_ONLY_PNBUF);
1619 if (vtyp != VFIFO && (error = priv_check_cred(cred,
1620 PRIV_VFS_MKNOD_DEV, 0)))
1622 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1624 NDFREE(&nd, NDF_ONLY_PNBUF);
1631 * Release dvp prior to lookup
1636 nd.ni_cnd.cn_nameiop = LOOKUP;
1637 nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
1638 nd.ni_cnd.cn_thread = td;
1639 nd.ni_cnd.cn_cred = td->td_ucred;
1640 tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
1642 nd.ni_cnd.cn_flags |= GIANTHELD;
1643 error = lookup(&nd);
1645 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1646 nd.ni_cnd.cn_flags &= ~GIANTHELD;
1650 if (nd.ni_cnd.cn_flags & ISSYMLINK)
1655 * send response, cleanup, return.
1660 bzero((caddr_t)fhp, sizeof(nfh));
1661 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
1662 error = VOP_VPTOFH(vp, &fhp->fh_fid);
1664 error = VOP_GETATTR(vp, vap, cred);
1667 if (nd.ni_dvp == nd.ni_vp)
1678 if (nd.ni_startdir) {
1679 vrele(nd.ni_startdir);
1680 nd.ni_startdir = NULL;
1682 NDFREE(&nd, NDF_ONLY_PNBUF);
1684 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
1685 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1689 nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
1692 nfsm_srvpostop_fh(fhp);
1693 nfsm_srvpostop_attr(0, vap);
1695 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1697 vn_finished_write(mp);
1698 VFS_UNLOCK_GIANT(vfslocked);
1702 if (nd.ni_dvp == nd.ni_vp)
1712 vrele(nd.ni_startdir);
1713 NDFREE(&nd, NDF_ONLY_PNBUF);
1714 vn_finished_write(mp);
1715 VFS_UNLOCK_GIANT(vfslocked);
1720 * nfs remove service
1723 nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1726 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1727 struct sockaddr *nam = nfsd->nd_nam;
1728 caddr_t dpos = nfsd->nd_dpos;
1729 struct ucred *cred = nfsd->nd_cr;
1730 struct nameidata nd;
1732 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1733 int v3 = (nfsd->nd_flag & ND_NFSV3);
1734 struct mbuf *mb, *mreq;
1736 struct vattr dirfor, diraft;
1739 struct mount *mp = NULL;
1742 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1746 fhp = &nfh.fh_generic;
1748 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1752 vfslocked = VFS_LOCK_GIANT(mp);
1753 (void) vn_start_write(NULL, &mp, V_WAIT);
1754 vfs_rel(mp); /* The write holds a ref. */
1755 nfsm_srvnamesiz(len);
1757 nd.ni_cnd.cn_cred = cred;
1758 nd.ni_cnd.cn_nameiop = DELETE;
1759 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | MPSAFE;
1760 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
1761 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
1762 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1768 if (nd.ni_vp->v_type == VDIR) {
1769 error = EPERM; /* POSIX */
1773 * The root of a mounted filesystem cannot be deleted.
1775 if (nd.ni_vp->v_vflag & VV_ROOT) {
1781 error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
1782 NDFREE(&nd, NDF_ONLY_PNBUF);
1786 if (dirp == nd.ni_dvp)
1787 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1789 /* Drop the other locks to avoid deadlock. */
1791 if (nd.ni_dvp == nd.ni_vp)
1801 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
1802 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1803 VOP_UNLOCK(dirp, 0);
1809 nfsm_reply(NFSX_WCCDATA(v3));
1811 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1814 NDFREE(&nd, NDF_ONLY_PNBUF);
1816 if (nd.ni_dvp == nd.ni_vp)
1823 vn_finished_write(mp);
1824 VFS_UNLOCK_GIANT(vfslocked);
1829 * nfs rename service
1832 nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1835 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1836 struct sockaddr *nam = nfsd->nd_nam;
1837 caddr_t dpos = nfsd->nd_dpos;
1838 struct ucred *cred = nfsd->nd_cr;
1840 int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
1841 int tdirfor_ret = 1, tdiraft_ret = 1;
1842 int v3 = (nfsd->nd_flag & ND_NFSV3);
1843 struct mbuf *mb, *mreq;
1844 struct nameidata fromnd, tond;
1845 struct vnode *fvp, *tvp, *tdvp, *fdirp = NULL;
1846 struct vnode *tdirp = NULL;
1847 struct vattr fdirfor, fdiraft, tdirfor, tdiraft;
1849 fhandle_t *ffhp, *tfhp;
1851 struct mount *mp = NULL;
1854 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1859 ffhp = &fnfh.fh_generic;
1860 tfhp = &tnfh.fh_generic;
1863 * Clear fields incase goto nfsmout occurs from macro.
1869 nfsm_srvmtofh(ffhp);
1870 if ((mp = vfs_getvfs(&ffhp->fh_fsid)) == NULL) {
1874 vfslocked = VFS_LOCK_GIANT(mp);
1875 (void) vn_start_write(NULL, &mp, V_WAIT);
1876 vfs_rel(mp); /* The write holds a ref. */
1877 nfsm_srvnamesiz(len);
1879 * Remember our original uid so that we can reset cr_uid before
1880 * the second nfs_namei() call, in case it is remapped.
1882 saved_uid = cred->cr_uid;
1883 fromnd.ni_cnd.cn_cred = cred;
1884 fromnd.ni_cnd.cn_nameiop = DELETE;
1885 fromnd.ni_cnd.cn_flags = WANTPARENT | SAVESTART | MPSAFE;
1886 error = nfs_namei(&fromnd, nfsd, ffhp, len, slp, nam, &md,
1887 &dpos, &fdirp, v3, &fdirfor, &fdirfor_ret, FALSE);
1888 vfslocked = nfsrv_lockedpair_nd(vfslocked, &fromnd);
1894 nfsm_reply(2 * NFSX_WCCDATA(v3));
1896 nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
1897 nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
1903 nfsm_srvmtofh(tfhp);
1904 nfsm_srvnamesiz(len2);
1905 cred->cr_uid = saved_uid;
1906 tond.ni_cnd.cn_cred = cred;
1907 tond.ni_cnd.cn_nameiop = RENAME;
1908 tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | MPSAFE;
1909 error = nfs_namei(&tond, nfsd, tfhp, len2, slp, nam, &md,
1910 &dpos, &tdirp, v3, &tdirfor, &tdirfor_ret, FALSE);
1911 vfslocked = nfsrv_lockedpair_nd(vfslocked, &tond);
1922 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
1928 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
1935 if (tvp->v_type == VDIR && tvp->v_mountedhere) {
1943 if (fvp->v_type == VDIR && fvp->v_mountedhere) {
1950 if (fvp->v_mount != tdvp->v_mount) {
1964 * If source is the same as the destination (that is the
1965 * same vnode with the same name in the same directory),
1966 * then there is nothing to do.
1968 if (fvp == tvp && fromnd.ni_dvp == tdvp &&
1969 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
1970 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
1971 fromnd.ni_cnd.cn_namelen))
1976 * The VOP_RENAME function releases all vnode references &
1977 * locks prior to returning so we need to clear the pointers
1978 * to bypass cleanup code later on.
1980 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
1981 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
1982 fromnd.ni_dvp = NULL;
1983 fromnd.ni_vp = NULL;
1987 NDFREE(&fromnd, NDF_ONLY_PNBUF);
1988 NDFREE(&tond, NDF_ONLY_PNBUF);
1996 nfsm_reply(2 * NFSX_WCCDATA(v3));
1998 /* Release existing locks to prevent deadlock. */
2000 if (tond.ni_dvp == tond.ni_vp)
2011 vn_lock(fdirp, LK_EXCLUSIVE | LK_RETRY);
2012 fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred);
2013 VOP_UNLOCK(fdirp, 0);
2016 vn_lock(tdirp, LK_EXCLUSIVE | LK_RETRY);
2017 tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred);
2018 VOP_UNLOCK(tdirp, 0);
2020 nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
2021 nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
2028 * Clear out tond related fields
2031 if (tond.ni_dvp == tond.ni_vp)
2040 if (tond.ni_startdir)
2041 vrele(tond.ni_startdir);
2042 NDFREE(&tond, NDF_ONLY_PNBUF);
2044 * Clear out fromnd related fields
2048 if (fromnd.ni_startdir)
2049 vrele(fromnd.ni_startdir);
2050 NDFREE(&fromnd, NDF_ONLY_PNBUF);
2052 vrele(fromnd.ni_dvp);
2054 vrele(fromnd.ni_vp);
2056 vn_finished_write(mp);
2057 VFS_UNLOCK_GIANT(vfslocked);
2065 nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2068 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2069 struct sockaddr *nam = nfsd->nd_nam;
2070 caddr_t dpos = nfsd->nd_dpos;
2071 struct ucred *cred = nfsd->nd_cr;
2072 struct nameidata nd;
2074 int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
2075 int getret = 1, v3 = (nfsd->nd_flag & ND_NFSV3);
2076 struct mbuf *mb, *mreq;
2077 struct vnode *vp = NULL, *xp, *dirp = NULL;
2078 struct vattr dirfor, diraft, at;
2080 fhandle_t *fhp, *dfhp;
2081 struct mount *mp = NULL;
2085 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2089 fhp = &nfh.fh_generic;
2090 dfhp = &dnfh.fh_generic;
2092 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2096 vfslocked = VFS_LOCK_GIANT(mp);
2097 (void) vn_start_write(NULL, &mp, V_WAIT);
2098 vfs_rel(mp); /* The write holds a ref. */
2099 nfsm_srvmtofh(dfhp);
2100 nfsm_srvnamesiz(len);
2102 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
2103 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
2105 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2107 nfsm_srvpostop_attr(getret, &at);
2108 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2115 getret = VOP_GETATTR(vp, &at, cred);
2116 if (vp->v_type == VDIR) {
2117 error = EPERM; /* POSIX */
2121 nd.ni_cnd.cn_cred = cred;
2122 nd.ni_cnd.cn_nameiop = CREATE;
2123 nd.ni_cnd.cn_flags = LOCKPARENT | MPSAFE | MPSAFE;
2124 error = nfs_namei(&nd, nfsd, dfhp, len, slp, nam, &md, &dpos,
2125 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2126 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2144 if (vp->v_mount != xp->v_mount) {
2150 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2151 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
2152 NDFREE(&nd, NDF_ONLY_PNBUF);
2157 getret = VOP_GETATTR(vp, &at, cred);
2160 if (dirp == nd.ni_dvp)
2161 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2163 /* Release existing locks to prevent deadlock. */
2165 if (nd.ni_dvp == nd.ni_vp)
2175 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2176 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2177 VOP_UNLOCK(dirp, 0);
2181 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2183 nfsm_srvpostop_attr(getret, &at);
2184 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2190 NDFREE(&nd, NDF_ONLY_PNBUF);
2194 if (nd.ni_dvp == nd.ni_vp)
2203 vn_finished_write(mp);
2204 VFS_UNLOCK_GIANT(vfslocked);
2209 * nfs symbolic link service
2212 nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2215 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2216 struct sockaddr *nam = nfsd->nd_nam;
2217 caddr_t dpos = nfsd->nd_dpos;
2218 struct ucred *cred = nfsd->nd_cr;
2219 struct vattr va, dirfor, diraft;
2220 struct nameidata nd;
2221 struct vattr *vap = &va;
2222 struct nfsv2_sattr *sp;
2223 char *bpos, *pathcp = NULL;
2226 int error = 0, len, len2, dirfor_ret = 1, diraft_ret = 1;
2227 int v3 = (nfsd->nd_flag & ND_NFSV3);
2228 struct mbuf *mb, *mreq;
2229 struct vnode *dirp = NULL;
2232 struct mount *mp = NULL;
2236 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2240 fhp = &nfh.fh_generic;
2242 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2246 vfslocked = VFS_LOCK_GIANT(mp);
2247 (void) vn_start_write(NULL, &mp, V_WAIT);
2248 vfs_rel(mp); /* The write holds a ref. */
2249 nfsm_srvnamesiz(len);
2250 nd.ni_cnd.cn_cred = cred;
2251 nd.ni_cnd.cn_nameiop = CREATE;
2252 nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART | MPSAFE;
2253 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
2254 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2255 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2260 nfsm_srvpathsiz(len2);
2268 pathcp = malloc(len2 + 1, M_TEMP, M_WAITOK);
2269 iv.iov_base = pathcp;
2271 io.uio_resid = len2;
2275 io.uio_segflg = UIO_SYSSPACE;
2276 io.uio_rw = UIO_READ;
2278 nfsm_mtouio(&io, len2);
2280 sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
2281 vap->va_mode = nfstov_mode(sp->sa_mode);
2283 *(pathcp + len2) = '\0';
2290 * issue symlink op. SAVESTART is set so the underlying path component
2291 * is only freed by the VOP if an error occurs.
2293 if (vap->va_mode == (mode_t)VNOVAL)
2295 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp);
2297 NDFREE(&nd, NDF_ONLY_PNBUF);
2302 * releases directory prior to potential lookup op.
2310 * Issue lookup. Leave SAVESTART set so we can easily free
2311 * the name buffer later on.
2313 * since LOCKPARENT is not set, ni_dvp will be garbage on
2314 * return whether an error occurs or not.
2316 nd.ni_cnd.cn_nameiop = LOOKUP;
2317 nd.ni_cnd.cn_flags &= ~(LOCKPARENT | FOLLOW);
2318 nd.ni_cnd.cn_flags |= (NOFOLLOW | LOCKLEAF);
2319 nd.ni_cnd.cn_thread = curthread;
2320 nd.ni_cnd.cn_cred = cred;
2321 tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
2323 nd.ni_cnd.cn_flags |= GIANTHELD;
2324 error = lookup(&nd);
2326 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2327 nd.ni_cnd.cn_flags &= ~GIANTHELD;
2330 bzero((caddr_t)fhp, sizeof(nfh));
2331 fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
2332 error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
2334 error = VOP_GETATTR(nd.ni_vp, vap, cred);
2342 * These releases aren't strictly required, does even doing them
2343 * make any sense? XXX can nfsm_reply() block?
2346 free(pathcp, M_TEMP);
2350 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2351 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2352 VOP_UNLOCK(dirp, 0);
2354 if (nd.ni_startdir) {
2355 vrele(nd.ni_startdir);
2356 nd.ni_startdir = NULL;
2358 nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2361 nfsm_srvpostop_fh(fhp);
2362 nfsm_srvpostop_attr(0, vap);
2364 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2370 NDFREE(&nd, NDF_ONLY_PNBUF);
2372 if (nd.ni_dvp == nd.ni_vp)
2380 vrele(nd.ni_startdir);
2384 free(pathcp, M_TEMP);
2386 vn_finished_write(mp);
2387 VFS_UNLOCK_GIANT(vfslocked);
2395 nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2398 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2399 struct sockaddr *nam = nfsd->nd_nam;
2400 caddr_t dpos = nfsd->nd_dpos;
2401 struct ucred *cred = nfsd->nd_cr;
2402 struct vattr va, dirfor, diraft;
2403 struct vattr *vap = &va;
2404 struct nfs_fattr *fp;
2405 struct nameidata nd;
2408 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
2409 int v3 = (nfsd->nd_flag & ND_NFSV3);
2410 struct mbuf *mb, *mreq;
2411 struct vnode *dirp = NULL;
2415 struct mount *mp = NULL;
2418 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2422 fhp = &nfh.fh_generic;
2424 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2428 vfslocked = VFS_LOCK_GIANT(mp);
2429 (void) vn_start_write(NULL, &mp, V_WAIT);
2430 vfs_rel(mp); /* The write holds a ref. */
2431 nfsm_srvnamesiz(len);
2432 nd.ni_cnd.cn_cred = cred;
2433 nd.ni_cnd.cn_nameiop = CREATE;
2434 nd.ni_cnd.cn_flags = LOCKPARENT | MPSAFE;
2436 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
2437 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2438 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2444 nfsm_reply(NFSX_WCCDATA(v3));
2446 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2454 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
2455 vap->va_mode = nfstov_mode(*tl++);
2459 * At this point nd.ni_dvp is referenced and exclusively locked and
2460 * nd.ni_vp, if it exists, is referenced but not locked.
2463 vap->va_type = VDIR;
2464 if (nd.ni_vp != NULL) {
2465 NDFREE(&nd, NDF_ONLY_PNBUF);
2471 * Issue mkdir op. Since SAVESTART is not set, the pathname
2472 * component is freed by the VOP call. This will fill-in
2473 * nd.ni_vp, reference, and exclusively lock it.
2475 if (vap->va_mode == (mode_t)VNOVAL)
2477 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
2478 NDFREE(&nd, NDF_ONLY_PNBUF);
2485 bzero((caddr_t)fhp, sizeof(nfh));
2486 fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
2487 error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
2489 error = VOP_GETATTR(nd.ni_vp, vap, cred);
2493 if (dirp == nd.ni_dvp) {
2494 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2496 /* Release existing locks to prevent deadlock. */
2498 NDFREE(&nd, NDF_ONLY_PNBUF);
2499 if (nd.ni_dvp == nd.ni_vp && vpexcl)
2512 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2513 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2514 VOP_UNLOCK(dirp, 0);
2517 nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2520 nfsm_srvpostop_fh(fhp);
2521 nfsm_srvpostop_attr(0, vap);
2523 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2524 } else if (!error) {
2525 /* v2 non-error case. */
2526 nfsm_srvfhtom(fhp, v3);
2527 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
2528 nfsm_srvfillattr(vap, fp);
2535 NDFREE(&nd, NDF_ONLY_PNBUF);
2536 if (nd.ni_dvp == nd.ni_vp && vpexcl)
2549 vn_finished_write(mp);
2550 VFS_UNLOCK_GIANT(vfslocked);
2558 nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2561 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2562 struct sockaddr *nam = nfsd->nd_nam;
2563 caddr_t dpos = nfsd->nd_dpos;
2564 struct ucred *cred = nfsd->nd_cr;
2566 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
2567 int v3 = (nfsd->nd_flag & ND_NFSV3);
2568 struct mbuf *mb, *mreq;
2569 struct vnode *vp, *dirp = NULL;
2570 struct vattr dirfor, diraft;
2573 struct nameidata nd;
2574 struct mount *mp = NULL;
2577 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2581 fhp = &nfh.fh_generic;
2583 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2587 vfslocked = VFS_LOCK_GIANT(mp);
2588 (void) vn_start_write(NULL, &mp, V_WAIT);
2589 vfs_rel(mp); /* The write holds a ref. */
2590 nfsm_srvnamesiz(len);
2591 nd.ni_cnd.cn_cred = cred;
2592 nd.ni_cnd.cn_nameiop = DELETE;
2593 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | MPSAFE;
2594 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
2595 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2596 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2602 nfsm_reply(NFSX_WCCDATA(v3));
2604 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2609 if (vp->v_type != VDIR) {
2614 * No rmdir "." please.
2616 if (nd.ni_dvp == vp) {
2621 * The root of a mounted filesystem cannot be deleted.
2623 if (vp->v_vflag & VV_ROOT)
2627 * Issue or abort op. Since SAVESTART is not set, path name
2628 * component is freed by the VOP after either.
2631 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
2632 NDFREE(&nd, NDF_ONLY_PNBUF);
2635 if (dirp == nd.ni_dvp)
2636 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2638 /* Release existing locks to prevent deadlock. */
2640 if (nd.ni_dvp == nd.ni_vp)
2649 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2650 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2651 VOP_UNLOCK(dirp, 0);
2654 nfsm_reply(NFSX_WCCDATA(v3));
2657 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2661 NDFREE(&nd, NDF_ONLY_PNBUF);
2663 if (nd.ni_dvp == nd.ni_vp)
2673 vn_finished_write(mp);
2674 VFS_UNLOCK_GIANT(vfslocked);
2679 * nfs readdir service
2680 * - mallocs what it thinks is enough to read
2681 * count rounded up to a multiple of NFS_DIRBLKSIZ <= NFS_MAXREADDIR
2682 * - calls VOP_READDIR()
2683 * - loops around building the reply
2684 * if the output generated exceeds count break out of loop
2685 * The nfsm_clget macro is used here so that the reply will be packed
2686 * tightly in mbuf clusters.
2687 * - it only knows that it has encountered eof when the VOP_READDIR()
2689 * - as such one readdir rpc will return eof false although you are there
2690 * and then the next will return eof
2691 * - it trims out records with d_fileno == 0
2692 * this doesn't matter for Unix clients, but they might confuse clients
2694 * NB: It is tempting to set eof to true if the VOP_READDIR() reads less
2695 * than requested, but this may not apply to all filesystems. For
2696 * example, client NFS does not { although it is never remote mounted
2698 * The alternate call nfsrv_readdirplus() does lookups as well.
2699 * PS: The NFS protocol spec. does not clarify what the "count" byte
2700 * argument is a count of.. just name strings and file id's or the
2701 * entire reply rpc or ...
2702 * I tried just file name and id sizes and it confused the Sun client,
2703 * so I am using the full rpc size now. The "paranoia.." comment refers
2704 * to including the status longwords that are not a part of the dir.
2705 * "entry" structures, but are in the rpc.
2709 u_int32_t fl_postopok;
2710 u_int32_t fl_fattr[NFSX_V3FATTR / sizeof (u_int32_t)];
2712 u_int32_t fl_fhsize;
2713 u_int32_t fl_nfh[NFSX_V3FH / sizeof (u_int32_t)];
2717 nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2720 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2721 struct sockaddr *nam = nfsd->nd_nam;
2722 caddr_t dpos = nfsd->nd_dpos;
2723 struct ucred *cred = nfsd->nd_cr;
2730 struct mbuf *mb, *mreq;
2731 char *cpos, *cend, *rbuf;
2732 struct vnode *vp = NULL;
2738 int len, nlen, rem, xfer, tsiz, i, error = 0, getret = 1;
2739 int siz, cnt, fullsiz, eofflag, rdonly, ncookies;
2740 int v3 = (nfsd->nd_flag & ND_NFSV3);
2741 u_quad_t off, toff, verf;
2742 u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
2743 int vfslocked, not_zfs;
2745 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2747 fhp = &nfh.fh_generic;
2750 tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED);
2751 toff = fxdr_hyper(tl);
2753 verf = fxdr_hyper(tl);
2756 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
2757 toff = fxdr_unsigned(u_quad_t, *tl++);
2758 verf = 0; /* shut up gcc */
2761 cnt = fxdr_unsigned(int, *tl);
2762 siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
2763 xfer = NFS_SRVMAXDATA(nfsd);
2769 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
2770 if (!error && vp->v_type != VDIR) {
2776 nfsm_reply(NFSX_UNSIGNED);
2778 nfsm_srvpostop_attr(getret, &at);
2784 * Obtain lock on vnode for this section of the code
2787 error = getret = VOP_GETATTR(vp, &at, cred);
2790 * XXX This check may be too strict for Solaris 2.5 clients.
2792 if (!error && toff && verf && verf != at.va_filerev)
2793 error = NFSERR_BAD_COOKIE;
2797 error = nfsrv_access(vp, VEXEC, cred, rdonly, 0);
2801 nfsm_reply(NFSX_POSTOPATTR(v3));
2803 nfsm_srvpostop_attr(getret, &at);
2807 not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
2811 * end section. Allocate rbuf and continue
2813 rbuf = malloc(siz, M_TEMP, M_WAITOK);
2816 iv.iov_len = fullsiz;
2819 io.uio_offset = (off_t)off;
2820 io.uio_resid = fullsiz;
2821 io.uio_segflg = UIO_SYSSPACE;
2822 io.uio_rw = UIO_READ;
2826 free((caddr_t)cookies, M_TEMP);
2829 vn_lock(vp, LK_SHARED | LK_RETRY);
2830 error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
2831 off = (off_t)io.uio_offset;
2832 if (!cookies && !error)
2833 error = NFSERR_PERM;
2835 getret = VOP_GETATTR(vp, &at, cred);
2843 free((caddr_t)rbuf, M_TEMP);
2845 free((caddr_t)cookies, M_TEMP);
2846 nfsm_reply(NFSX_POSTOPATTR(v3));
2848 nfsm_srvpostop_attr(getret, &at);
2853 siz -= io.uio_resid;
2856 * If nothing read, return eof
2862 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) +
2865 nfsm_srvpostop_attr(getret, &at);
2866 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
2867 txdr_hyper(at.va_filerev, tl);
2870 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
2871 *tl++ = nfsrv_nfs_false;
2872 *tl = nfsrv_nfs_true;
2873 free((caddr_t)rbuf, M_TEMP);
2874 free((caddr_t)cookies, M_TEMP);
2881 * Check for degenerate cases of nothing useful read.
2882 * If so go try again
2886 dp = (struct dirent *)cpos;
2889 * For some reason FreeBSD's ufs_readdir() chooses to back the
2890 * directory offset up to a block boundary, so it is necessary to
2891 * skip over the records that precede the requested offset. This
2892 * requires the assumption that file offset cookies monotonically
2894 * Since the offset cookies don't monotonically increase for ZFS,
2895 * this is not done when ZFS is the file system.
2897 while (cpos < cend && ncookies > 0 &&
2898 (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
2899 (not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
2900 cpos += dp->d_reclen;
2901 dp = (struct dirent *)cpos;
2905 if (cpos >= cend || ncookies == 0) {
2911 len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */
2912 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + siz);
2914 nfsm_srvpostop_attr(getret, &at);
2915 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
2916 txdr_hyper(at.va_filerev, tl);
2920 be = bp + M_TRAILINGSPACE(mp);
2922 /* Loop through the records and build reply */
2923 while (cpos < cend && ncookies > 0) {
2924 if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
2925 nlen = dp->d_namlen;
2926 rem = nfsm_rndup(nlen) - nlen;
2927 len += (4 * NFSX_UNSIGNED + nlen + rem);
2929 len += 2 * NFSX_UNSIGNED;
2935 * Build the directory record xdr from
2939 *tl = nfsrv_nfs_true;
2940 bp += NFSX_UNSIGNED;
2944 bp += NFSX_UNSIGNED;
2947 *tl = txdr_unsigned(dp->d_fileno);
2948 bp += NFSX_UNSIGNED;
2950 *tl = txdr_unsigned(nlen);
2951 bp += NFSX_UNSIGNED;
2953 /* And loop around copying the name */
2962 bcopy(cp, bp, tsiz);
2968 /* And null pad to an int32_t boundary. */
2969 for (i = 0; i < rem; i++)
2973 /* Finish off the record */
2976 bp += NFSX_UNSIGNED;
2979 *tl = txdr_unsigned(*cookiep);
2980 bp += NFSX_UNSIGNED;
2982 cpos += dp->d_reclen;
2983 dp = (struct dirent *)cpos;
2990 *tl = nfsrv_nfs_false;
2991 bp += NFSX_UNSIGNED;
2994 *tl = nfsrv_nfs_true;
2996 *tl = nfsrv_nfs_false;
2997 bp += NFSX_UNSIGNED;
3000 mp->m_len = bp - mtod(mp, caddr_t);
3002 mp->m_len += bp - bpos;
3003 free((caddr_t)rbuf, M_TEMP);
3004 free((caddr_t)cookies, M_TEMP);
3009 VFS_UNLOCK_GIANT(vfslocked);
3014 nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3017 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3018 struct sockaddr *nam = nfsd->nd_nam;
3019 caddr_t dpos = nfsd->nd_dpos;
3020 struct ucred *cred = nfsd->nd_cr;
3027 struct mbuf *mb, *mreq;
3028 char *cpos, *cend, *rbuf;
3029 struct vnode *vp = NULL, *nvp;
3032 fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh;
3035 struct vattr va, at, *vap = &va;
3036 struct nfs_fattr *fp;
3037 int len, nlen, rem, xfer, tsiz, i, error = 0, error1, getret = 1;
3039 int siz, cnt, fullsiz, eofflag, rdonly, dirlen, ncookies;
3040 u_quad_t off, toff, verf;
3041 u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
3042 int v3 = (nfsd->nd_flag & ND_NFSV3);
3043 int usevget = 1, vfslocked;
3044 struct componentname cn;
3045 struct mount *mntp = NULL;
3048 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3052 panic("nfsrv_readdirplus: v3 proc called on a v2 connection");
3053 fhp = &nfh.fh_generic;
3055 tl = nfsm_dissect_nonblock(u_int32_t *, 6 * NFSX_UNSIGNED);
3056 toff = fxdr_hyper(tl);
3058 verf = fxdr_hyper(tl);
3060 siz = fxdr_unsigned(int, *tl++);
3061 cnt = fxdr_unsigned(int, *tl);
3063 siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
3064 xfer = NFS_SRVMAXDATA(nfsd);
3070 error = nfsrv_fhtovp(fhp, NFSRV_FLAG_BUSY, &vp, &vfslocked, nfsd, slp,
3075 if (vp->v_type != VDIR) {
3083 nfsm_reply(NFSX_UNSIGNED);
3084 nfsm_srvpostop_attr(getret, &at);
3088 error = getret = VOP_GETATTR(vp, &at, cred);
3091 * XXX This check may be too strict for Solaris 2.5 clients.
3093 if (!error && toff && verf && verf != at.va_filerev)
3094 error = NFSERR_BAD_COOKIE;
3097 error = nfsrv_access(vp, VEXEC, cred, rdonly, 0);
3102 nfsm_reply(NFSX_V3POSTOPATTR);
3103 nfsm_srvpostop_attr(getret, &at);
3107 not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
3110 rbuf = malloc(siz, M_TEMP, M_WAITOK);
3113 iv.iov_len = fullsiz;
3116 io.uio_offset = (off_t)off;
3117 io.uio_resid = fullsiz;
3118 io.uio_segflg = UIO_SYSSPACE;
3119 io.uio_rw = UIO_READ;
3124 free((caddr_t)cookies, M_TEMP);
3127 vn_lock(vp, LK_SHARED | LK_RETRY);
3128 error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
3129 off = (u_quad_t)io.uio_offset;
3130 getret = VOP_GETATTR(vp, &at, cred);
3133 if (!cookies && !error)
3134 error = NFSERR_PERM;
3141 free((caddr_t)cookies, M_TEMP);
3142 free((caddr_t)rbuf, M_TEMP);
3143 nfsm_reply(NFSX_V3POSTOPATTR);
3144 nfsm_srvpostop_attr(getret, &at);
3149 siz -= io.uio_resid;
3152 * If nothing read, return eof
3158 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
3160 nfsm_srvpostop_attr(getret, &at);
3161 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
3162 txdr_hyper(at.va_filerev, tl);
3164 *tl++ = nfsrv_nfs_false;
3165 *tl = nfsrv_nfs_true;
3166 free((caddr_t)cookies, M_TEMP);
3167 free((caddr_t)rbuf, M_TEMP);
3174 * Check for degenerate cases of nothing useful read.
3175 * If so go try again
3179 dp = (struct dirent *)cpos;
3182 * For some reason FreeBSD's ufs_readdir() chooses to back the
3183 * directory offset up to a block boundary, so it is necessary to
3184 * skip over the records that precede the requested offset. This
3185 * requires the assumption that file offset cookies monotonically
3187 * Since the offset cookies don't monotonically increase for ZFS,
3188 * this is not done when ZFS is the file system.
3190 while (cpos < cend && ncookies > 0 &&
3191 (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
3192 (not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
3193 cpos += dp->d_reclen;
3194 dp = (struct dirent *)cpos;
3198 if (cpos >= cend || ncookies == 0) {
3204 dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
3207 nfsm_srvpostop_attr(getret, &at);
3208 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
3209 txdr_hyper(at.va_filerev, tl);
3212 be = bp + M_TRAILINGSPACE(mp);
3214 /* Loop through the records and build reply */
3215 while (cpos < cend && ncookies > 0) {
3216 if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
3217 nlen = dp->d_namlen;
3218 rem = nfsm_rndup(nlen)-nlen;
3222 * For readdir_and_lookup get the vnode using
3225 error = VFS_VGET(mntp, dp->d_fileno, LK_SHARED,
3227 if (error != 0 && error != EOPNOTSUPP) {
3230 } else if (error == EOPNOTSUPP) {
3232 * VFS_VGET() not supported?
3233 * Let's switch to VOP_LOOKUP().
3237 cn.cn_nameiop = LOOKUP;
3238 cn.cn_flags = ISLASTCN | NOFOLLOW | \
3239 LOCKSHARED | LOCKLEAF | MPSAFE;
3240 cn.cn_lkflags = LK_SHARED | LK_RETRY;
3242 cn.cn_thread = curthread;
3246 cn.cn_nameptr = dp->d_name;
3247 cn.cn_namelen = dp->d_namlen;
3248 if (dp->d_namlen == 2 &&
3249 dp->d_name[0] == '.' &&
3250 dp->d_name[1] == '.') {
3251 cn.cn_flags |= ISDOTDOT;
3253 cn.cn_flags &= ~ISDOTDOT;
3256 vn_lock(vp, LK_SHARED | LK_RETRY);
3259 if ((vp->v_vflag & VV_ROOT) != 0 &&
3260 (cn.cn_flags & ISDOTDOT) != 0) {
3263 } else if (VOP_LOOKUP(vp, &nvp, &cn) != 0)
3267 bzero((caddr_t)nfhp, NFSX_V3FH);
3268 nfhp->fh_fsid = nvp->v_mount->mnt_stat.f_fsid;
3269 if ((error1 = VOP_VPTOFH(nvp, &nfhp->fh_fid)) == 0)
3270 error1 = VOP_GETATTR(nvp, vap, cred);
3271 if (!usevget && vp == nvp)
3280 * If either the dircount or maxcount will be
3281 * exceeded, get out now. Both of these lengths
3282 * are calculated conservatively, including all
3285 len += (8 * NFSX_UNSIGNED + nlen + rem + NFSX_V3FH +
3287 dirlen += (6 * NFSX_UNSIGNED + nlen + rem);
3288 if (len > cnt || dirlen > fullsiz) {
3294 * Build the directory record xdr from
3297 fp = (struct nfs_fattr *)&fl.fl_fattr;
3298 nfsm_srvfillattr(vap, fp);
3299 fl.fl_fhsize = txdr_unsigned(NFSX_V3FH);
3300 fl.fl_fhok = nfsrv_nfs_true;
3301 fl.fl_postopok = nfsrv_nfs_true;
3302 fl.fl_off.nfsuquad[0] = 0;
3303 fl.fl_off.nfsuquad[1] = txdr_unsigned(*cookiep);
3306 *tl = nfsrv_nfs_true;
3307 bp += NFSX_UNSIGNED;
3310 bp += NFSX_UNSIGNED;
3312 *tl = txdr_unsigned(dp->d_fileno);
3313 bp += NFSX_UNSIGNED;
3315 *tl = txdr_unsigned(nlen);
3316 bp += NFSX_UNSIGNED;
3318 /* And loop around copying the name */
3323 if ((bp + xfer) > be)
3327 bcopy(cp, bp, tsiz);
3333 /* And null pad to an int32_t boundary. */
3334 for (i = 0; i < rem; i++)
3338 * Now copy the flrep structure out.
3340 xfer = sizeof (struct flrep);
3344 if ((bp + xfer) > be)
3348 bcopy(cp, bp, tsiz);
3356 cpos += dp->d_reclen;
3357 dp = (struct dirent *)cpos;
3361 if (!usevget && vp_locked)
3367 *tl = nfsrv_nfs_false;
3368 bp += NFSX_UNSIGNED;
3371 *tl = nfsrv_nfs_true;
3373 *tl = nfsrv_nfs_false;
3374 bp += NFSX_UNSIGNED;
3377 mp->m_len = bp - mtod(mp, caddr_t);
3379 mp->m_len += bp - bpos;
3380 free((caddr_t)cookies, M_TEMP);
3381 free((caddr_t)rbuf, M_TEMP);
3387 VFS_UNLOCK_GIANT(vfslocked);
3392 * nfs commit service
3395 nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3398 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3399 struct sockaddr *nam = nfsd->nd_nam;
3400 caddr_t dpos = nfsd->nd_dpos;
3401 struct ucred *cred = nfsd->nd_cr;
3402 struct vattr bfor, aft;
3403 struct vnode *vp = NULL;
3408 int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt;
3409 struct mbuf *mb, *mreq;
3411 struct mount *mp = NULL;
3412 int v3 = (nfsd->nd_flag & ND_NFSV3);
3416 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3419 panic("nfsrv_commit: v3 proc called on a v2 connection");
3420 fhp = &nfh.fh_generic;
3422 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
3426 vfslocked = VFS_LOCK_GIANT(mp);
3427 (void) vn_start_write(NULL, &mp, V_WAIT);
3428 vfs_rel(mp); /* The write holds a ref. */
3429 tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED);
3432 * XXX At this time VOP_FSYNC() does not accept offset and byte
3433 * count parameters, so these arguments are useless (someday maybe).
3435 off = fxdr_hyper(tl);
3437 cnt = fxdr_unsigned(int, *tl);
3438 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
3439 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
3441 nfsm_reply(2 * NFSX_UNSIGNED);
3442 nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
3446 for_ret = VOP_GETATTR(vp, &bfor, cred);
3448 if (cnt > MAX_COMMIT_COUNT) {
3450 * Give up and do the whole thing
3453 (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) {
3454 VM_OBJECT_LOCK(vp->v_object);
3455 vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC);
3456 VM_OBJECT_UNLOCK(vp->v_object);
3458 error = VOP_FSYNC(vp, MNT_WAIT, curthread);
3461 * Locate and synchronously write any buffers that fall
3462 * into the requested range. Note: we are assuming that
3463 * f_iosize is a power of 2.
3465 int iosize = vp->v_mount->mnt_stat.f_iosize;
3466 int iomask = iosize - 1;
3471 * Align to iosize boundry, super-align to page boundry.
3474 cnt += off & iomask;
3475 off &= ~(u_quad_t)iomask;
3477 if (off & PAGE_MASK) {
3478 cnt += off & PAGE_MASK;
3479 off &= ~(u_quad_t)PAGE_MASK;
3481 lblkno = off / iosize;
3484 (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) {
3485 VM_OBJECT_LOCK(vp->v_object);
3486 vm_object_page_clean(vp->v_object, off, off + cnt,
3488 VM_OBJECT_UNLOCK(vp->v_object);
3497 * If we have a buffer and it is marked B_DELWRI we
3498 * have to lock and write it. Otherwise the prior
3499 * write is assumed to have already been committed.
3501 * gbincore() can return invalid buffers now so we
3502 * have to check that bit as well (though B_DELWRI
3503 * should not be set if B_INVAL is set there could be
3504 * a race here since we haven't locked the buffer).
3506 if ((bp = gbincore(&vp->v_bufobj, lblkno)) != NULL) {
3507 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL |
3508 LK_INTERLOCK, BO_MTX(bo)) == ENOLCK) {
3510 continue; /* retry */
3512 if ((bp->b_flags & (B_DELWRI|B_INVAL)) ==
3515 bp->b_flags &= ~B_ASYNC;
3531 aft_ret = VOP_GETATTR(vp, &aft, cred);
3535 nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF);
3536 nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
3538 tl = nfsm_build(u_int32_t *, NFSX_V3WRITEVERF);
3539 if (nfsver.tv_sec == 0)
3541 *tl++ = txdr_unsigned(nfsver.tv_sec);
3542 *tl = txdr_unsigned(nfsver.tv_usec);
3549 vn_finished_write(mp);
3550 VFS_UNLOCK_GIANT(vfslocked);
3555 * nfs statfs service
3558 nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3561 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3562 struct sockaddr *nam = nfsd->nd_nam;
3563 caddr_t dpos = nfsd->nd_dpos;
3564 struct ucred *cred = nfsd->nd_cr;
3566 struct nfs_statfs *sfp;
3568 int error = 0, rdonly, getret = 1;
3569 int v3 = (nfsd->nd_flag & ND_NFSV3);
3570 struct mbuf *mb, *mreq;
3571 struct vnode *vp = NULL;
3575 struct statfs statfs;
3579 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3581 fhp = &nfh.fh_generic;
3583 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
3585 nfsm_reply(NFSX_UNSIGNED);
3587 nfsm_srvpostop_attr(getret, &at);
3592 error = VFS_STATFS(vp->v_mount, sf);
3593 getret = VOP_GETATTR(vp, &at, cred);
3596 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_STATFS(v3));
3598 nfsm_srvpostop_attr(getret, &at);
3603 sfp = nfsm_build(struct nfs_statfs *, NFSX_STATFS(v3));
3605 tval = (u_quad_t)sf->f_blocks;
3606 tval *= (u_quad_t)sf->f_bsize;
3607 txdr_hyper(tval, &sfp->sf_tbytes);
3608 tval = (u_quad_t)sf->f_bfree;
3609 tval *= (u_quad_t)sf->f_bsize;
3610 txdr_hyper(tval, &sfp->sf_fbytes);
3612 * Don't send negative values for available space,
3613 * since this field is unsigned in the NFS protocol.
3614 * Otherwise, the client would see absurdly high
3615 * numbers for free space.
3617 if (sf->f_bavail < 0)
3620 tval = (u_quad_t)sf->f_bavail;
3621 tval *= (u_quad_t)sf->f_bsize;
3622 txdr_hyper(tval, &sfp->sf_abytes);
3623 sfp->sf_tfiles.nfsuquad[0] = 0;
3624 sfp->sf_tfiles.nfsuquad[1] = txdr_unsigned(sf->f_files);
3625 sfp->sf_ffiles.nfsuquad[0] = 0;
3626 sfp->sf_ffiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
3627 sfp->sf_afiles.nfsuquad[0] = 0;
3628 sfp->sf_afiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
3629 sfp->sf_invarsec = 0;
3631 sfp->sf_tsize = txdr_unsigned(NFS_MAXDGRAMDATA);
3632 sfp->sf_bsize = txdr_unsigned(sf->f_bsize);
3633 sfp->sf_blocks = txdr_unsigned(sf->f_blocks);
3634 sfp->sf_bfree = txdr_unsigned(sf->f_bfree);
3635 if (sf->f_bavail < 0)
3638 sfp->sf_bavail = txdr_unsigned(sf->f_bavail);
3643 VFS_UNLOCK_GIANT(vfslocked);
3648 * nfs fsinfo service
3651 nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3654 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3655 struct sockaddr *nam = nfsd->nd_nam;
3656 caddr_t dpos = nfsd->nd_dpos;
3657 struct ucred *cred = nfsd->nd_cr;
3658 struct nfsv3_fsinfo *sip;
3660 int error = 0, rdonly, getret = 1, pref;
3661 struct mbuf *mb, *mreq;
3662 struct vnode *vp = NULL;
3668 int v3 = (nfsd->nd_flag & ND_NFSV3);
3671 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3673 panic("nfsrv_fsinfo: v3 proc called on a v2 connection");
3674 fhp = &nfh.fh_generic;
3677 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
3679 nfsm_reply(NFSX_UNSIGNED);
3680 nfsm_srvpostop_attr(getret, &at);
3685 /* XXX Try to make a guess on the max file size. */
3686 VFS_STATFS(vp->v_mount, &sb);
3687 maxfsize = (u_quad_t)0x80000000 * sb.f_bsize - 1;
3689 getret = VOP_GETATTR(vp, &at, cred);
3692 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO);
3693 nfsm_srvpostop_attr(getret, &at);
3694 sip = nfsm_build(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
3698 * There should be filesystem VFS OP(s) to get this information.
3699 * For now, assume ufs.
3701 pref = NFS_SRVMAXDATA(nfsd);
3702 sip->fs_rtmax = txdr_unsigned(pref);
3703 sip->fs_rtpref = txdr_unsigned(pref);
3704 sip->fs_rtmult = txdr_unsigned(NFS_FABLKSIZE);
3705 sip->fs_wtmax = txdr_unsigned(pref);
3706 sip->fs_wtpref = txdr_unsigned(pref);
3707 sip->fs_wtmult = txdr_unsigned(NFS_FABLKSIZE);
3708 sip->fs_dtpref = txdr_unsigned(pref);
3709 txdr_hyper(maxfsize, &sip->fs_maxfilesize);
3710 sip->fs_timedelta.nfsv3_sec = 0;
3711 sip->fs_timedelta.nfsv3_nsec = txdr_unsigned(1);
3712 sip->fs_properties = txdr_unsigned(NFSV3FSINFO_LINK |
3713 NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS |
3714 NFSV3FSINFO_CANSETTIME);
3718 VFS_UNLOCK_GIANT(vfslocked);
3723 * nfs pathconf service
3726 nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3729 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3730 struct sockaddr *nam = nfsd->nd_nam;
3731 caddr_t dpos = nfsd->nd_dpos;
3732 struct ucred *cred = nfsd->nd_cr;
3733 struct nfsv3_pathconf *pc;
3735 int error = 0, rdonly, getret = 1;
3736 register_t linkmax, namemax, chownres, notrunc;
3737 struct mbuf *mb, *mreq;
3738 struct vnode *vp = NULL;
3742 int v3 = (nfsd->nd_flag & ND_NFSV3);
3745 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3747 panic("nfsrv_pathconf: v3 proc called on a v2 connection");
3749 fhp = &nfh.fh_generic;
3751 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
3753 nfsm_reply(NFSX_UNSIGNED);
3754 nfsm_srvpostop_attr(getret, &at);
3758 error = VOP_PATHCONF(vp, _PC_LINK_MAX, &linkmax);
3760 error = VOP_PATHCONF(vp, _PC_NAME_MAX, &namemax);
3762 error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &chownres);
3764 error = VOP_PATHCONF(vp, _PC_NO_TRUNC, ¬runc);
3765 getret = VOP_GETATTR(vp, &at, cred);
3768 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF);
3769 nfsm_srvpostop_attr(getret, &at);
3774 pc = nfsm_build(struct nfsv3_pathconf *, NFSX_V3PATHCONF);
3776 pc->pc_linkmax = txdr_unsigned(linkmax);
3777 pc->pc_namemax = txdr_unsigned(namemax);
3778 pc->pc_notrunc = txdr_unsigned(notrunc);
3779 pc->pc_chownrestricted = txdr_unsigned(chownres);
3782 * These should probably be supported by VOP_PATHCONF(), but
3783 * until msdosfs is exportable (why would you want to?), the
3784 * Unix defaults should be ok.
3786 pc->pc_caseinsensitive = nfsrv_nfs_false;
3787 pc->pc_casepreserving = nfsrv_nfs_true;
3791 VFS_UNLOCK_GIANT(vfslocked);
3796 * Null operation, used by clients to ping server
3800 nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3803 struct mbuf *mrep = nfsd->nd_mrep;
3805 int error = NFSERR_RETVOID;
3806 struct mbuf *mb, *mreq;
3808 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3815 * No operation, used for obsolete procedures
3819 nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3822 struct mbuf *mrep = nfsd->nd_mrep;
3825 struct mbuf *mb, *mreq;
3827 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3828 if (nfsd->nd_repstat)
3829 error = nfsd->nd_repstat;
3831 error = EPROCUNAVAIL;
3839 * Perform access checking for vnodes obtained from file handles that would
3840 * refer to files already opened by a Unix client. You cannot just use
3841 * vn_writechk() and VOP_ACCESS() for two reasons.
3842 * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write
3844 * 2 - The owner is to be given access irrespective of mode bits for some
3845 * operations, so that processes that chmod after opening a file don't
3846 * break. I don't like this because it opens a security hole, but since
3847 * the nfs server opens a security hole the size of a barn door anyhow,
3850 * The exception to rule 2 is EPERM. If a file is IMMUTABLE, VOP_ACCESS()
3851 * will return EPERM instead of EACCES. EPERM is always an error.
3854 nfsrv_access(struct vnode *vp, accmode_t accmode, struct ucred *cred,
3855 int rdonly, int override)
3860 VFS_ASSERT_GIANT(vp->v_mount);
3862 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3864 if (accmode & VWRITE) {
3865 /* Just vn_writechk() changed to check rdonly */
3867 * Disallow write attempts on read-only filesystems;
3868 * unless the file is a socket or a block or character
3869 * device resident on the filesystem.
3871 if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
3872 switch (vp->v_type) {
3882 * If there's shared text associated with
3883 * the inode, we can't allow writing.
3885 if (vp->v_vflag & VV_TEXT)
3889 error = VOP_GETATTR(vp, &vattr, cred);
3892 error = VOP_ACCESS(vp, accmode, cred, curthread);
3894 * Allow certain operations for the owner (reads and writes
3895 * on files that are already open).
3897 if (override && error == EACCES && cred->cr_uid == vattr.va_uid)