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;
163 * Takes two vfslocked integers and returns with at most one
164 * reference to giant. The return value indicates whether giant
165 * is held by either lock. This simplifies nfsrv ops by allowing
166 * them to track only one vfslocked var.
169 nfsrv_lockedpair(int vfs1, int vfs2)
173 VFS_UNLOCK_GIANT(vfs2);
175 return (vfs1 | vfs2);
179 nfsrv_lockedpair_nd(int vfs1, struct nameidata *nd)
183 vfs2 = NDHASGIANT(nd);
185 return nfsrv_lockedpair(vfs1, vfs2);
189 * nfs v3 access service
192 nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
195 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
196 struct sockaddr *nam = nfsd->nd_nam;
197 caddr_t dpos = nfsd->nd_dpos;
198 struct ucred *cred = nfsd->nd_cr;
199 struct vnode *vp = NULL;
204 int error = 0, rdonly, getret;
205 struct mbuf *mb, *mreq;
206 struct vattr vattr, *vap = &vattr;
207 u_long testmode, nfsmode;
208 int v3 = (nfsd->nd_flag & ND_NFSV3);
211 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
213 panic("nfsrv3_access: v3 proc called on a v2 connection");
215 fhp = &nfh.fh_generic;
217 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
218 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
220 nfsm_reply(NFSX_UNSIGNED);
221 nfsm_srvpostop_attr(1, NULL);
225 nfsmode = fxdr_unsigned(u_int32_t, *tl);
226 if ((nfsmode & NFSV3ACCESS_READ) &&
227 nfsrv_access(vp, VREAD, cred, rdonly, 0))
228 nfsmode &= ~NFSV3ACCESS_READ;
229 if (vp->v_type == VDIR)
230 testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
233 testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
234 if ((nfsmode & testmode) &&
235 nfsrv_access(vp, VWRITE, cred, rdonly, 0))
236 nfsmode &= ~testmode;
237 if (vp->v_type == VDIR)
238 testmode = NFSV3ACCESS_LOOKUP;
240 testmode = NFSV3ACCESS_EXECUTE;
241 if ((nfsmode & testmode) &&
242 nfsrv_access(vp, VEXEC, cred, rdonly, 0))
243 nfsmode &= ~testmode;
244 getret = VOP_GETATTR(vp, vap, cred);
247 nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED);
248 nfsm_srvpostop_attr(getret, vap);
249 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
250 *tl = txdr_unsigned(nfsmode);
254 VFS_UNLOCK_GIANT(vfslocked);
259 * nfs getattr service
262 nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
265 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
266 struct sockaddr *nam = nfsd->nd_nam;
267 caddr_t dpos = nfsd->nd_dpos;
268 struct ucred *cred = nfsd->nd_cr;
269 struct nfs_fattr *fp;
271 struct vattr *vap = &va;
272 struct vnode *vp = NULL;
276 int error = 0, rdonly;
277 struct mbuf *mb, *mreq;
280 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
282 fhp = &nfh.fh_generic;
284 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
290 error = VOP_GETATTR(vp, vap, cred);
293 nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
298 fp = nfsm_build(struct nfs_fattr *,
299 NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
300 nfsm_srvfillattr(vap, fp);
306 VFS_UNLOCK_GIANT(vfslocked);
311 * nfs setattr service
314 nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
317 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
318 struct sockaddr *nam = nfsd->nd_nam;
319 caddr_t dpos = nfsd->nd_dpos;
320 struct ucred *cred = nfsd->nd_cr;
321 struct vattr va, preat;
322 struct vattr *vap = &va;
323 struct nfsv2_sattr *sp;
324 struct nfs_fattr *fp;
325 struct vnode *vp = NULL;
330 int error = 0, rdonly, preat_ret = 1, postat_ret = 1;
331 int v3 = (nfsd->nd_flag & ND_NFSV3), gcheck = 0;
332 struct mbuf *mb, *mreq;
333 struct timespec guard = { 0, 0 };
334 struct mount *mp = NULL;
338 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
340 fhp = &nfh.fh_generic;
342 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
346 vfslocked = VFS_LOCK_GIANT(mp);
347 (void) vn_start_write(NULL, &mp, V_WAIT);
348 vfs_rel(mp); /* The write holds a ref. */
352 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
353 gcheck = fxdr_unsigned(int, *tl);
355 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
356 fxdr_nfsv3time(tl, &guard);
359 sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
361 * Nah nah nah nah na nah
362 * There is a bug in the Sun client that puts 0xffff in the mode
363 * field of sattr when it should put in 0xffffffff. The u_short
364 * doesn't sign extend.
365 * --> check the low order 2 bytes for 0xffff
367 if ((fxdr_unsigned(int, sp->sa_mode) & 0xffff) != 0xffff)
368 vap->va_mode = nfstov_mode(sp->sa_mode);
369 if (sp->sa_uid != nfsrv_nfs_xdrneg1)
370 vap->va_uid = fxdr_unsigned(uid_t, sp->sa_uid);
371 if (sp->sa_gid != nfsrv_nfs_xdrneg1)
372 vap->va_gid = fxdr_unsigned(gid_t, sp->sa_gid);
373 if (sp->sa_size != nfsrv_nfs_xdrneg1)
374 vap->va_size = fxdr_unsigned(u_quad_t, sp->sa_size);
375 if (sp->sa_atime.nfsv2_sec != nfsrv_nfs_xdrneg1) {
377 fxdr_nfsv2time(&sp->sa_atime, &vap->va_atime);
379 vap->va_atime.tv_sec =
380 fxdr_unsigned(int32_t, sp->sa_atime.nfsv2_sec);
381 vap->va_atime.tv_nsec = 0;
384 if (sp->sa_mtime.nfsv2_sec != nfsrv_nfs_xdrneg1)
385 fxdr_nfsv2time(&sp->sa_mtime, &vap->va_mtime);
390 * Now that we have all the fields, lets do it.
392 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
393 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
395 nfsm_reply(2 * NFSX_UNSIGNED);
397 nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
403 * vp now an active resource, pay careful attention to cleanup
406 error = preat_ret = VOP_GETATTR(vp, &preat, cred);
407 if (!error && gcheck &&
408 (preat.va_ctime.tv_sec != guard.tv_sec ||
409 preat.va_ctime.tv_nsec != guard.tv_nsec))
410 error = NFSERR_NOT_SYNC;
414 nfsm_reply(NFSX_WCCDATA(v3));
416 nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
423 * If the size is being changed write acces is required, otherwise
424 * just check for a read only filesystem.
426 if (vap->va_size == ((u_quad_t)((quad_t) -1))) {
427 if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
432 if (vp->v_type == VDIR) {
435 } else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly,
439 error = VOP_SETATTR(vp, vap, cred);
440 postat_ret = VOP_GETATTR(vp, vap, cred);
448 nfsm_reply(NFSX_WCCORFATTR(v3));
450 nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
452 /* v2 non-error case. */
453 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
454 nfsm_srvfillattr(vap, fp);
462 vn_finished_write(mp);
463 VFS_UNLOCK_GIANT(vfslocked);
471 nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
474 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
475 struct sockaddr *nam = nfsd->nd_nam;
476 caddr_t dpos = nfsd->nd_dpos;
477 struct ucred *cred = nfsd->nd_cr;
478 struct nfs_fattr *fp;
479 struct nameidata nd, ind, *ndp = &nd;
480 struct vnode *vp, *dirp = NULL;
484 int error = 0, len, dirattr_ret = 1;
485 int v3 = (nfsd->nd_flag & ND_NFSV3), pubflag;
486 struct mbuf *mb, *mreq;
487 struct vattr va, dirattr, *vap = &va;
491 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
495 fhp = &nfh.fh_generic;
497 nfsm_srvnamesiz(len);
499 pubflag = nfs_ispublicfh(fhp);
501 nd.ni_cnd.cn_cred = cred;
502 nd.ni_cnd.cn_nameiop = LOOKUP;
503 nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART | MPSAFE;
504 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
505 &dirp, v3, &dirattr, &dirattr_ret, pubflag);
506 vfslocked = NDHASGIANT(&nd);
509 * namei failure, only dirp to cleanup. Clear out garbarge from
510 * structure in case macros jump to nfsmout.
518 nfsm_reply(NFSX_POSTOPATTR(v3));
520 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
526 * Locate index file for public filehandle
528 * error is 0 on entry and 0 on exit from this block.
532 if (nd.ni_vp->v_type == VDIR && nfs_pub.np_index != NULL) {
534 * Setup call to lookup() to see if we can find
535 * the index file. Arguably, this doesn't belong
536 * in a kernel.. Ugh. If an error occurs, do not
537 * try to install an index file and then clear the
540 * When we replace nd with ind and redirect ndp,
541 * maintenance of ni_startdir and ni_vp shift to
542 * ind and we have to clean them up in the old nd.
543 * However, the cnd resource continues to be maintained
544 * via the original nd. Confused? You aren't alone!
547 VOP_UNLOCK(nd.ni_vp, 0);
548 ind.ni_pathlen = strlen(nfs_pub.np_index);
549 ind.ni_cnd.cn_nameptr = ind.ni_cnd.cn_pnbuf =
551 ind.ni_startdir = nd.ni_vp;
552 VREF(ind.ni_startdir);
553 ind.ni_cnd.cn_flags &= ~GIANTHELD;
554 tvfslocked = VFS_LOCK_GIANT(ind.ni_startdir->v_mount);
556 nd.ni_cnd.cn_flags |= GIANTHELD;
557 error = lookup(&ind);
559 vfslocked = nfsrv_lockedpair_nd(vfslocked, &ind);
560 ind.ni_cnd.cn_flags &= ~GIANTHELD;
564 * Found an index file. Get rid of
565 * the old references. transfer nd.ni_vp'
571 vrele(nd.ni_startdir);
572 nd.ni_startdir = NULL;
578 * If the public filehandle was used, check that this lookup
579 * didn't result in a filehandle outside the publicly exported
580 * filesystem. We clear the poor vp here to avoid lockups due
584 if (ndp->ni_vp->v_mount != nfs_pub.np_mount) {
592 * Resources at this point:
593 * ndp->ni_vp may not be NULL
597 nfsm_reply(NFSX_POSTOPATTR(v3));
599 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
605 * Get underlying attribute, then release remaining resources ( for
606 * the same potential blocking reason ) and reply.
609 bzero((caddr_t)fhp, sizeof(nfh));
610 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
611 error = VOP_VPTOFH(vp, &fhp->fh_fid);
613 error = VOP_GETATTR(vp, vap, cred);
616 vrele(ndp->ni_startdir);
619 ndp->ni_startdir = NULL;
621 nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
624 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
628 nfsm_srvfhtom(fhp, v3);
630 nfsm_srvpostop_attr(0, vap);
631 nfsm_srvpostop_attr(dirattr_ret, &dirattr);
633 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
634 nfsm_srvfillattr(vap, fp);
638 if (ndp->ni_vp || dirp || ndp->ni_startdir) {
643 if (ndp->ni_startdir)
644 vrele(ndp->ni_startdir);
646 NDFREE(&nd, NDF_ONLY_PNBUF);
647 VFS_UNLOCK_GIANT(vfslocked);
652 * nfs readlink service
655 nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
658 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
659 struct sockaddr *nam = nfsd->nd_nam;
660 caddr_t dpos = nfsd->nd_dpos;
661 struct ucred *cred = nfsd->nd_cr;
662 struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN];
663 struct iovec *ivp = iv;
667 int error = 0, rdonly, i, tlen, len, getret;
668 int v3 = (nfsd->nd_flag & ND_NFSV3);
669 struct mbuf *mb, *mp3, *nmp, *mreq;
670 struct vnode *vp = NULL;
674 struct uio io, *uiop = &io;
677 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
683 fhp = &nfh.fh_generic;
687 while (len < NFS_MAXPATHLEN) {
688 MGET(nmp, M_WAIT, MT_DATA);
690 nmp->m_len = NFSMSIZ(nmp);
697 if ((len + mp->m_len) > NFS_MAXPATHLEN) {
698 mp->m_len = NFS_MAXPATHLEN - len;
699 len = NFS_MAXPATHLEN;
702 ivp->iov_base = mtod(mp, caddr_t);
703 ivp->iov_len = mp->m_len;
708 uiop->uio_iovcnt = i;
709 uiop->uio_offset = 0;
710 uiop->uio_resid = len;
711 uiop->uio_rw = UIO_READ;
712 uiop->uio_segflg = UIO_SYSSPACE;
714 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
716 nfsm_reply(2 * NFSX_UNSIGNED);
718 nfsm_srvpostop_attr(1, NULL);
722 if (vp->v_type != VLNK) {
728 error = VOP_READLINK(vp, uiop, cred);
729 getret = VOP_GETATTR(vp, &attr, cred);
732 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED);
734 nfsm_srvpostop_attr(getret, &attr);
739 if (uiop->uio_resid > 0) {
740 len -= uiop->uio_resid;
741 tlen = nfsm_rndup(len);
742 nfsm_adj(mp3, NFS_MAXPATHLEN-tlen, tlen-len);
744 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
745 *tl = txdr_unsigned(len);
753 VFS_UNLOCK_GIANT(vfslocked);
761 nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
764 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
765 struct sockaddr *nam = nfsd->nd_nam;
766 caddr_t dpos = nfsd->nd_dpos;
767 struct ucred *cred = nfsd->nd_cr;
771 struct nfs_fattr *fp;
775 int error = 0, rdonly, cnt, len, left, siz, tlen, getret;
776 int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen;
777 struct mbuf *mb, *mreq;
779 struct vnode *vp = NULL;
782 struct uio io, *uiop = &io;
783 struct vattr va, *vap = &va;
790 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
792 fhp = &nfh.fh_generic;
795 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
796 off = fxdr_hyper(tl);
798 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
799 off = (off_t)fxdr_unsigned(u_int32_t, *tl);
801 nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd));
804 * Reference vp. If an error occurs, vp will be invalid, but we
805 * have to NULL it just in case. The macros might goto nfsmout
809 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
812 nfsm_reply(2 * NFSX_UNSIGNED);
814 nfsm_srvpostop_attr(1, NULL);
819 if (vp->v_type != VREG) {
823 error = (vp->v_type == VDIR) ? EISDIR : EACCES;
826 if ((error = nfsrv_access(vp, VREAD, cred, rdonly, 1)) != 0)
827 error = nfsrv_access(vp, VEXEC, cred, rdonly, 1);
829 getret = VOP_GETATTR(vp, vap, cred);
835 nfsm_reply(NFSX_POSTOPATTR(v3));
837 nfsm_srvpostop_attr(getret, vap);
843 * Calculate byte count to read
846 if (off >= vap->va_size)
848 else if ((off + reqlen) > vap->va_size)
849 cnt = vap->va_size - off;
854 * Calculate seqcount for heuristic
862 * Locate best candidate
865 hi = ((int)(vm_offset_t)vp / sizeof(struct vnode)) % NUM_HEURISTIC;
869 if (nfsheur[hi].nh_vp == vp) {
873 if (nfsheur[hi].nh_use > 0)
874 --nfsheur[hi].nh_use;
875 hi = (hi + 1) % NUM_HEURISTIC;
876 if (nfsheur[hi].nh_use < nh->nh_use)
880 if (nh->nh_vp != vp) {
883 nh->nh_use = NHUSE_INIT;
891 * Calculate heuristic
894 if ((off == 0 && nh->nh_seqcount > 0) || off == nh->nh_nextr) {
895 if (++nh->nh_seqcount > IO_SEQMAX)
896 nh->nh_seqcount = IO_SEQMAX;
897 } else if (nh->nh_seqcount > 1) {
902 nh->nh_use += NHUSE_INC;
903 if (nh->nh_use > NHUSE_MAX)
904 nh->nh_use = NHUSE_MAX;
905 ioflag |= nh->nh_seqcount << IO_SEQSHIFT;
908 nfsm_reply(NFSX_POSTOPORFATTR(v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt));
910 tl = nfsm_build(u_int32_t *, NFSX_V3FATTR + 4 * NFSX_UNSIGNED);
911 *tl++ = nfsrv_nfs_true;
912 fp = (struct nfs_fattr *)tl;
913 tl += (NFSX_V3FATTR / sizeof (u_int32_t));
915 tl = nfsm_build(u_int32_t *, NFSX_V2FATTR + NFSX_UNSIGNED);
916 fp = (struct nfs_fattr *)tl;
917 tl += (NFSX_V2FATTR / sizeof (u_int32_t));
919 len = left = nfsm_rndup(cnt);
922 * Generate the mbuf list with the uio_iov ref. to it.
927 siz = min(M_TRAILINGSPACE(m), left);
933 MGET(m, M_WAIT, MT_DATA);
940 iv = malloc(i * sizeof (struct iovec),
942 uiop->uio_iov = iv2 = iv;
948 panic("nfsrv_read iov");
949 siz = min(M_TRAILINGSPACE(m), left);
951 iv->iov_base = mtod(m, caddr_t) + m->m_len;
960 uiop->uio_iovcnt = i;
961 uiop->uio_offset = off;
962 uiop->uio_resid = len;
963 uiop->uio_rw = UIO_READ;
964 uiop->uio_segflg = UIO_SYSSPACE;
965 error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred);
966 off = uiop->uio_offset;
968 free((caddr_t)iv2, M_TEMP);
969 if (error || (getret = VOP_GETATTR(vp, vap, cred))) {
975 nfsm_reply(NFSX_POSTOPATTR(v3));
977 nfsm_srvpostop_attr(getret, vap);
985 nfsm_srvfillattr(vap, fp);
986 tlen = len - uiop->uio_resid;
987 cnt = cnt < tlen ? cnt : tlen;
988 tlen = nfsm_rndup(cnt);
989 if (len != tlen || tlen != cnt)
990 nfsm_adj(mb, len - tlen, tlen - cnt);
992 *tl++ = txdr_unsigned(cnt);
994 *tl++ = nfsrv_nfs_true;
996 *tl++ = nfsrv_nfs_false;
998 *tl = txdr_unsigned(cnt);
1002 VFS_UNLOCK_GIANT(vfslocked);
1010 nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1013 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1014 struct sockaddr *nam = nfsd->nd_nam;
1015 caddr_t dpos = nfsd->nd_dpos;
1016 struct ucred *cred = nfsd->nd_cr;
1020 struct nfs_fattr *fp;
1022 struct vattr va, forat;
1023 struct vattr *vap = &va;
1026 int error = 0, rdonly, len, forat_ret = 1;
1027 int ioflags, aftat_ret = 1, retlen = 0, zeroing, adjust;
1028 int stable = NFSV3WRITE_FILESYNC;
1029 int v3 = (nfsd->nd_flag & ND_NFSV3);
1030 struct mbuf *mb, *mreq;
1031 struct vnode *vp = NULL;
1034 struct uio io, *uiop = &io;
1036 struct mount *mntp = NULL;
1040 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1047 fhp = &nfh.fh_generic;
1049 if ((mntp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1053 vfslocked = VFS_LOCK_GIANT(mntp);
1054 (void) vn_start_write(NULL, &mntp, V_WAIT);
1055 vfs_rel(mntp); /* The write holds a ref. */
1057 tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED);
1058 off = fxdr_hyper(tl);
1060 stable = fxdr_unsigned(int, *tl++);
1062 tl = nfsm_dissect_nonblock(u_int32_t *, 4 * NFSX_UNSIGNED);
1063 off = (off_t)fxdr_unsigned(u_int32_t, *++tl);
1066 stable = NFSV3WRITE_UNSTABLE;
1068 retlen = len = fxdr_unsigned(int32_t, *tl);
1072 * For NFS Version 2, it is not obvious what a write of zero length
1073 * should do, but I might as well be consistent with Version 3,
1074 * which is to return ok so long as there are no permission problems.
1082 adjust = dpos - mtod(mp, caddr_t);
1083 mp->m_len -= adjust;
1084 if (mp->m_len > 0 && adjust > 0)
1085 mp->m_data += adjust;
1089 else if (mp->m_len > 0) {
1092 mp->m_len -= (i - len);
1101 if (len > NFS_MAXDATA || len < 0 || i < len) {
1103 nfsm_reply(2 * NFSX_UNSIGNED);
1105 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1109 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
1110 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
1113 nfsm_reply(2 * NFSX_UNSIGNED);
1115 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1120 forat_ret = VOP_GETATTR(vp, &forat, cred);
1121 if (vp->v_type != VREG) {
1125 error = (vp->v_type == VDIR) ? EISDIR : EACCES;
1128 error = nfsrv_access(vp, VWRITE, cred, rdonly, 1);
1132 nfsm_reply(NFSX_WCCDATA(v3));
1134 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1140 ivp = malloc(cnt * sizeof (struct iovec), M_TEMP,
1142 uiop->uio_iov = iv = ivp;
1143 uiop->uio_iovcnt = cnt;
1146 if (mp->m_len > 0) {
1147 ivp->iov_base = mtod(mp, caddr_t);
1148 ivp->iov_len = mp->m_len;
1156 * The IO_METASYNC flag indicates that all metadata (and not just
1157 * enough to ensure data integrity) mus be written to stable storage
1159 * (IO_METASYNC is not yet implemented in 4.4BSD-Lite.)
1161 if (stable == NFSV3WRITE_UNSTABLE)
1162 ioflags = IO_NODELOCKED;
1163 else if (stable == NFSV3WRITE_DATASYNC)
1164 ioflags = (IO_SYNC | IO_NODELOCKED);
1166 ioflags = (IO_METASYNC | IO_SYNC | IO_NODELOCKED);
1167 uiop->uio_resid = len;
1168 uiop->uio_rw = UIO_WRITE;
1169 uiop->uio_segflg = UIO_SYSSPACE;
1170 uiop->uio_td = NULL;
1171 uiop->uio_offset = off;
1172 error = VOP_WRITE(vp, uiop, ioflags, cred);
1173 /* Unlocked write. */
1174 nfsrvstats.srvvop_writes++;
1175 free((caddr_t)iv, M_TEMP);
1177 aftat_ret = VOP_GETATTR(vp, vap, cred);
1183 nfsm_reply(NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) +
1184 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(v3));
1186 nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
1191 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
1192 *tl++ = txdr_unsigned(retlen);
1194 * If nfs_async is set, then pretend the write was FILESYNC.
1196 if (stable == NFSV3WRITE_UNSTABLE && !nfs_async)
1197 *tl++ = txdr_unsigned(stable);
1199 *tl++ = txdr_unsigned(NFSV3WRITE_FILESYNC);
1201 * Actually, there is no need to txdr these fields,
1202 * but it may make the values more human readable,
1203 * for debugging purposes.
1205 if (nfsver.tv_sec == 0)
1207 *tl++ = txdr_unsigned(nfsver.tv_sec);
1208 *tl = txdr_unsigned(nfsver.tv_usec);
1209 } else if (!error) {
1210 /* v2 non-error case. */
1211 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
1212 nfsm_srvfillattr(vap, fp);
1218 vn_finished_write(mntp);
1219 VFS_UNLOCK_GIANT(vfslocked);
1224 * nfs create service
1225 * now does a truncate to 0 length via. setattr if it already exists
1228 nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1231 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1232 struct sockaddr *nam = nfsd->nd_nam;
1233 caddr_t dpos = nfsd->nd_dpos;
1234 struct ucred *cred = nfsd->nd_cr;
1235 struct nfs_fattr *fp;
1236 struct vattr va, dirfor, diraft;
1237 struct vattr *vap = &va;
1238 struct nfsv2_sattr *sp;
1240 struct nameidata nd;
1242 int error = 0, rdev, len, tsize, dirfor_ret = 1, diraft_ret = 1;
1243 int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0;
1244 struct mbuf *mb, *mreq;
1245 struct vnode *dirp = NULL;
1249 struct timespec cverf;
1250 struct mount *mp = NULL;
1254 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1261 fhp = &nfh.fh_generic;
1263 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1267 vfslocked = VFS_LOCK_GIANT(mp);
1268 (void) vn_start_write(NULL, &mp, V_WAIT);
1269 vfs_rel(mp); /* The write holds a ref. */
1270 nfsm_srvnamesiz(len);
1272 nd.ni_cnd.cn_cred = cred;
1273 nd.ni_cnd.cn_nameiop = CREATE;
1274 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE;
1277 * Call namei and do initial cleanup to get a few things
1278 * out of the way. If we get an initial error we cleanup
1279 * and return here to avoid special-casing the invalid nd
1280 * structure through the rest of the case. dirp may be
1281 * set even if an error occurs, but the nd structure will not
1282 * be valid at all if an error occurs so we have to invalidate it
1283 * prior to calling nfsm_reply ( which might goto nfsmout ).
1285 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
1286 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
1287 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1293 nfsm_reply(NFSX_WCCDATA(v3));
1295 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1301 * No error. Continue. State:
1303 * startdir is valid ( we release this immediately )
1305 * nd.ni_vp may be valid
1306 * nd.ni_dvp is valid
1308 * The error state is set through the code and we may also do some
1309 * opportunistic releasing of vnodes to avoid holding locks through
1310 * NFS I/O. The cleanup at the end is a catch-all
1315 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
1316 how = fxdr_unsigned(int, *tl);
1318 case NFSV3CREATE_GUARDED:
1324 case NFSV3CREATE_UNCHECKED:
1327 case NFSV3CREATE_EXCLUSIVE:
1328 tl = nfsm_dissect_nonblock(u_int32_t *,
1330 /* Unique bytes, endianness is not important. */
1331 cverf.tv_sec = (int32_t)tl[0];
1332 cverf.tv_nsec = tl[1];
1336 vap->va_type = VREG;
1338 sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
1339 vap->va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode));
1340 if (vap->va_type == VNON)
1341 vap->va_type = VREG;
1342 vap->va_mode = nfstov_mode(sp->sa_mode);
1343 switch (vap->va_type) {
1345 tsize = fxdr_unsigned(int32_t, sp->sa_size);
1347 vap->va_size = (u_quad_t)tsize;
1352 rdev = fxdr_unsigned(long, sp->sa_size);
1360 * Iff doesn't exist, create it
1361 * otherwise just truncate to 0 length
1362 * should I set the mode too ?
1364 * The only possible error we can have at this point is EEXIST.
1365 * nd.ni_vp will also be non-NULL in that case.
1367 if (nd.ni_vp == NULL) {
1368 if (vap->va_mode == (mode_t)VNOVAL)
1370 if (vap->va_type == VREG || vap->va_type == VSOCK) {
1371 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1373 NDFREE(&nd, NDF_ONLY_PNBUF);
1375 if (exclusive_flag) {
1378 vap->va_atime = cverf;
1379 error = VOP_SETATTR(nd.ni_vp, vap,
1383 } else if (vap->va_type == VCHR || vap->va_type == VBLK ||
1384 vap->va_type == VFIFO) {
1386 * NFSv2-specific code for creating device nodes
1389 * Handle SysV FIFO node special cases. All other
1390 * devices require super user to access.
1392 if (vap->va_type == VCHR && rdev == 0xffffffff)
1393 vap->va_type = VFIFO;
1394 if (vap->va_type != VFIFO &&
1395 (error = priv_check_cred(cred, PRIV_VFS_MKNOD_DEV,
1399 vap->va_rdev = rdev;
1400 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1402 NDFREE(&nd, NDF_ONLY_PNBUF);
1409 * release dvp prior to lookup
1416 * Even though LOCKPARENT was cleared, ni_dvp may
1419 nd.ni_cnd.cn_nameiop = LOOKUP;
1420 nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
1421 nd.ni_cnd.cn_thread = curthread;
1422 nd.ni_cnd.cn_cred = cred;
1423 tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
1425 nd.ni_cnd.cn_flags |= GIANTHELD;
1426 error = lookup(&nd);
1428 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1429 nd.ni_cnd.cn_flags &= ~GIANTHELD;
1433 if (nd.ni_cnd.cn_flags & ISSYMLINK) {
1441 if (vap->va_size != -1) {
1442 error = nfsrv_access(nd.ni_vp, VWRITE,
1443 cred, (nd.ni_cnd.cn_flags & RDONLY), 0);
1445 tempsize = vap->va_size;
1447 vap->va_size = tempsize;
1448 error = VOP_SETATTR(nd.ni_vp, vap, cred);
1454 bzero((caddr_t)fhp, sizeof(nfh));
1455 fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
1456 error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
1458 error = VOP_GETATTR(nd.ni_vp, vap, cred);
1461 if (exclusive_flag && !error &&
1462 bcmp(&cverf, &vap->va_atime, sizeof (cverf)))
1464 if (dirp == nd.ni_dvp)
1465 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1467 /* Drop the other locks to avoid deadlock. */
1469 if (nd.ni_dvp == nd.ni_vp)
1479 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
1480 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1481 VOP_UNLOCK(dirp, 0);
1485 nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
1488 nfsm_srvpostop_fh(fhp);
1489 nfsm_srvpostop_attr(0, vap);
1491 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1492 } else if (!error) {
1493 /* v2 non-error case. */
1494 nfsm_srvfhtom(fhp, v3);
1495 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
1496 nfsm_srvfillattr(vap, fp);
1502 if (nd.ni_dvp == nd.ni_vp)
1509 if (nd.ni_startdir) {
1510 vrele(nd.ni_startdir);
1511 nd.ni_startdir = NULL;
1515 NDFREE(&nd, NDF_ONLY_PNBUF);
1516 vn_finished_write(mp);
1517 VFS_UNLOCK_GIANT(vfslocked);
1522 * nfs v3 mknod service
1525 nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1528 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1529 struct sockaddr *nam = nfsd->nd_nam;
1530 caddr_t dpos = nfsd->nd_dpos;
1531 struct ucred *cred = nfsd->nd_cr;
1532 struct vattr va, dirfor, diraft;
1533 struct vattr *vap = &va;
1534 struct thread *td = curthread;
1536 struct nameidata nd;
1538 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1539 u_int32_t major, minor;
1541 struct mbuf *mb, *mreq;
1542 struct vnode *vp, *dirp = NULL;
1545 struct mount *mp = NULL;
1546 int v3 = (nfsd->nd_flag & ND_NFSV3);
1550 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1553 panic("nfsrv_mknod: v3 proc called on a v2 connection");
1556 fhp = &nfh.fh_generic;
1558 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1562 vfslocked = VFS_LOCK_GIANT(mp);
1563 (void) vn_start_write(NULL, &mp, V_WAIT);
1564 vfs_rel(mp); /* The write holds a ref. */
1565 nfsm_srvnamesiz(len);
1567 nd.ni_cnd.cn_cred = cred;
1568 nd.ni_cnd.cn_nameiop = CREATE;
1569 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE;
1572 * Handle nfs_namei() call. If an error occurs, the nd structure
1573 * is not valid. However, nfsm_*() routines may still jump to
1577 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
1578 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
1579 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1581 nfsm_reply(NFSX_WCCDATA(1));
1582 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1586 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
1587 vtyp = nfsv3tov_type(*tl);
1588 if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
1589 error = NFSERR_BADTYPE;
1594 if (vtyp == VCHR || vtyp == VBLK) {
1595 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
1596 major = fxdr_unsigned(u_int32_t, *tl++);
1597 minor = fxdr_unsigned(u_int32_t, *tl);
1598 vap->va_rdev = makedev(major, minor);
1602 * Iff doesn't exist, create it.
1608 vap->va_type = vtyp;
1609 if (vap->va_mode == (mode_t)VNOVAL)
1611 if (vtyp == VSOCK) {
1612 vrele(nd.ni_startdir);
1613 nd.ni_startdir = NULL;
1614 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1616 NDFREE(&nd, NDF_ONLY_PNBUF);
1618 if (vtyp != VFIFO && (error = priv_check_cred(cred,
1619 PRIV_VFS_MKNOD_DEV, 0)))
1621 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
1623 NDFREE(&nd, NDF_ONLY_PNBUF);
1630 * Release dvp prior to lookup
1635 nd.ni_cnd.cn_nameiop = LOOKUP;
1636 nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
1637 nd.ni_cnd.cn_thread = td;
1638 nd.ni_cnd.cn_cred = td->td_ucred;
1639 tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
1641 nd.ni_cnd.cn_flags |= GIANTHELD;
1642 error = lookup(&nd);
1644 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1645 nd.ni_cnd.cn_flags &= ~GIANTHELD;
1649 if (nd.ni_cnd.cn_flags & ISSYMLINK)
1654 * send response, cleanup, return.
1659 bzero((caddr_t)fhp, sizeof(nfh));
1660 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
1661 error = VOP_VPTOFH(vp, &fhp->fh_fid);
1663 error = VOP_GETATTR(vp, vap, cred);
1666 if (nd.ni_dvp == nd.ni_vp)
1677 if (nd.ni_startdir) {
1678 vrele(nd.ni_startdir);
1679 nd.ni_startdir = NULL;
1681 NDFREE(&nd, NDF_ONLY_PNBUF);
1683 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
1684 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1688 nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
1691 nfsm_srvpostop_fh(fhp);
1692 nfsm_srvpostop_attr(0, vap);
1694 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1696 vn_finished_write(mp);
1697 VFS_UNLOCK_GIANT(vfslocked);
1701 if (nd.ni_dvp == nd.ni_vp)
1711 vrele(nd.ni_startdir);
1712 NDFREE(&nd, NDF_ONLY_PNBUF);
1713 vn_finished_write(mp);
1714 VFS_UNLOCK_GIANT(vfslocked);
1719 * nfs remove service
1722 nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1725 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1726 struct sockaddr *nam = nfsd->nd_nam;
1727 caddr_t dpos = nfsd->nd_dpos;
1728 struct ucred *cred = nfsd->nd_cr;
1729 struct nameidata nd;
1731 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1732 int v3 = (nfsd->nd_flag & ND_NFSV3);
1733 struct mbuf *mb, *mreq;
1735 struct vattr dirfor, diraft;
1738 struct mount *mp = NULL;
1741 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1745 fhp = &nfh.fh_generic;
1747 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
1751 vfslocked = VFS_LOCK_GIANT(mp);
1752 (void) vn_start_write(NULL, &mp, V_WAIT);
1753 vfs_rel(mp); /* The write holds a ref. */
1754 nfsm_srvnamesiz(len);
1756 nd.ni_cnd.cn_cred = cred;
1757 nd.ni_cnd.cn_nameiop = DELETE;
1758 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | MPSAFE;
1759 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
1760 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
1761 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
1767 if (nd.ni_vp->v_type == VDIR) {
1768 error = EPERM; /* POSIX */
1772 * The root of a mounted filesystem cannot be deleted.
1774 if (nd.ni_vp->v_vflag & VV_ROOT) {
1780 error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
1781 NDFREE(&nd, NDF_ONLY_PNBUF);
1785 if (dirp == nd.ni_dvp)
1786 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1788 /* Drop the other locks to avoid deadlock. */
1790 if (nd.ni_dvp == nd.ni_vp)
1800 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
1801 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
1802 VOP_UNLOCK(dirp, 0);
1808 nfsm_reply(NFSX_WCCDATA(v3));
1810 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
1813 NDFREE(&nd, NDF_ONLY_PNBUF);
1815 if (nd.ni_dvp == nd.ni_vp)
1822 vn_finished_write(mp);
1823 VFS_UNLOCK_GIANT(vfslocked);
1828 * nfs rename service
1831 nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1834 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
1835 struct sockaddr *nam = nfsd->nd_nam;
1836 caddr_t dpos = nfsd->nd_dpos;
1837 struct ucred *cred = nfsd->nd_cr;
1839 int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
1840 int tdirfor_ret = 1, tdiraft_ret = 1;
1841 int v3 = (nfsd->nd_flag & ND_NFSV3);
1842 struct mbuf *mb, *mreq;
1843 struct nameidata fromnd, tond;
1844 struct vnode *fvp, *tvp, *tdvp, *fdirp = NULL;
1845 struct vnode *tdirp = NULL;
1846 struct vattr fdirfor, fdiraft, tdirfor, tdiraft;
1848 fhandle_t *ffhp, *tfhp;
1850 struct mount *mp = NULL;
1853 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
1858 ffhp = &fnfh.fh_generic;
1859 tfhp = &tnfh.fh_generic;
1862 * Clear fields incase goto nfsmout occurs from macro.
1868 nfsm_srvmtofh(ffhp);
1869 if ((mp = vfs_getvfs(&ffhp->fh_fsid)) == NULL) {
1873 vfslocked = VFS_LOCK_GIANT(mp);
1874 (void) vn_start_write(NULL, &mp, V_WAIT);
1875 vfs_rel(mp); /* The write holds a ref. */
1876 nfsm_srvnamesiz(len);
1878 * Remember our original uid so that we can reset cr_uid before
1879 * the second nfs_namei() call, in case it is remapped.
1881 saved_uid = cred->cr_uid;
1882 fromnd.ni_cnd.cn_cred = cred;
1883 fromnd.ni_cnd.cn_nameiop = DELETE;
1884 fromnd.ni_cnd.cn_flags = WANTPARENT | SAVESTART | MPSAFE;
1885 error = nfs_namei(&fromnd, nfsd, ffhp, len, slp, nam, &md,
1886 &dpos, &fdirp, v3, &fdirfor, &fdirfor_ret, FALSE);
1887 vfslocked = nfsrv_lockedpair_nd(vfslocked, &fromnd);
1893 nfsm_reply(2 * NFSX_WCCDATA(v3));
1895 nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
1896 nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
1902 nfsm_srvmtofh(tfhp);
1903 nfsm_srvnamesiz(len2);
1904 cred->cr_uid = saved_uid;
1905 tond.ni_cnd.cn_cred = cred;
1906 tond.ni_cnd.cn_nameiop = RENAME;
1907 tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | MPSAFE;
1908 error = nfs_namei(&tond, nfsd, tfhp, len2, slp, nam, &md,
1909 &dpos, &tdirp, v3, &tdirfor, &tdirfor_ret, FALSE);
1910 vfslocked = nfsrv_lockedpair_nd(vfslocked, &tond);
1921 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
1927 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
1934 if (tvp->v_type == VDIR && tvp->v_mountedhere) {
1942 if (fvp->v_type == VDIR && fvp->v_mountedhere) {
1949 if (fvp->v_mount != tdvp->v_mount) {
1963 * If source is the same as the destination (that is the
1964 * same vnode with the same name in the same directory),
1965 * then there is nothing to do.
1967 if (fvp == tvp && fromnd.ni_dvp == tdvp &&
1968 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
1969 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
1970 fromnd.ni_cnd.cn_namelen))
1975 * The VOP_RENAME function releases all vnode references &
1976 * locks prior to returning so we need to clear the pointers
1977 * to bypass cleanup code later on.
1979 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
1980 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
1981 fromnd.ni_dvp = NULL;
1982 fromnd.ni_vp = NULL;
1986 NDFREE(&fromnd, NDF_ONLY_PNBUF);
1987 NDFREE(&tond, NDF_ONLY_PNBUF);
1995 nfsm_reply(2 * NFSX_WCCDATA(v3));
1997 /* Release existing locks to prevent deadlock. */
1999 if (tond.ni_dvp == tond.ni_vp)
2010 vn_lock(fdirp, LK_EXCLUSIVE | LK_RETRY);
2011 fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred);
2012 VOP_UNLOCK(fdirp, 0);
2015 vn_lock(tdirp, LK_EXCLUSIVE | LK_RETRY);
2016 tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred);
2017 VOP_UNLOCK(tdirp, 0);
2019 nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
2020 nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
2027 * Clear out tond related fields
2030 if (tond.ni_dvp == tond.ni_vp)
2039 if (tond.ni_startdir)
2040 vrele(tond.ni_startdir);
2041 NDFREE(&tond, NDF_ONLY_PNBUF);
2043 * Clear out fromnd related fields
2047 if (fromnd.ni_startdir)
2048 vrele(fromnd.ni_startdir);
2049 NDFREE(&fromnd, NDF_ONLY_PNBUF);
2051 vrele(fromnd.ni_dvp);
2053 vrele(fromnd.ni_vp);
2055 vn_finished_write(mp);
2056 VFS_UNLOCK_GIANT(vfslocked);
2064 nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2067 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2068 struct sockaddr *nam = nfsd->nd_nam;
2069 caddr_t dpos = nfsd->nd_dpos;
2070 struct ucred *cred = nfsd->nd_cr;
2071 struct nameidata nd;
2073 int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
2074 int getret = 1, v3 = (nfsd->nd_flag & ND_NFSV3);
2075 struct mbuf *mb, *mreq;
2076 struct vnode *vp = NULL, *xp, *dirp = NULL;
2077 struct vattr dirfor, diraft, at;
2079 fhandle_t *fhp, *dfhp;
2080 struct mount *mp = NULL;
2084 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2088 fhp = &nfh.fh_generic;
2089 dfhp = &dnfh.fh_generic;
2091 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2095 vfslocked = VFS_LOCK_GIANT(mp);
2096 (void) vn_start_write(NULL, &mp, V_WAIT);
2097 vfs_rel(mp); /* The write holds a ref. */
2098 nfsm_srvmtofh(dfhp);
2099 nfsm_srvnamesiz(len);
2101 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
2102 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
2104 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2106 nfsm_srvpostop_attr(getret, &at);
2107 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2114 getret = VOP_GETATTR(vp, &at, cred);
2115 if (vp->v_type == VDIR) {
2116 error = EPERM; /* POSIX */
2120 nd.ni_cnd.cn_cred = cred;
2121 nd.ni_cnd.cn_nameiop = CREATE;
2122 nd.ni_cnd.cn_flags = LOCKPARENT | MPSAFE | MPSAFE;
2123 error = nfs_namei(&nd, nfsd, dfhp, len, slp, nam, &md, &dpos,
2124 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2125 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2143 if (vp->v_mount != xp->v_mount) {
2149 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2150 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
2151 NDFREE(&nd, NDF_ONLY_PNBUF);
2156 getret = VOP_GETATTR(vp, &at, cred);
2159 if (dirp == nd.ni_dvp)
2160 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2162 /* Release existing locks to prevent deadlock. */
2164 if (nd.ni_dvp == nd.ni_vp)
2174 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2175 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2176 VOP_UNLOCK(dirp, 0);
2180 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2182 nfsm_srvpostop_attr(getret, &at);
2183 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2189 NDFREE(&nd, NDF_ONLY_PNBUF);
2193 if (nd.ni_dvp == nd.ni_vp)
2202 vn_finished_write(mp);
2203 VFS_UNLOCK_GIANT(vfslocked);
2208 * nfs symbolic link service
2211 nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2214 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2215 struct sockaddr *nam = nfsd->nd_nam;
2216 caddr_t dpos = nfsd->nd_dpos;
2217 struct ucred *cred = nfsd->nd_cr;
2218 struct vattr va, dirfor, diraft;
2219 struct nameidata nd;
2220 struct vattr *vap = &va;
2221 struct nfsv2_sattr *sp;
2222 char *bpos, *pathcp = NULL;
2225 int error = 0, len, len2, dirfor_ret = 1, diraft_ret = 1;
2226 int v3 = (nfsd->nd_flag & ND_NFSV3);
2227 struct mbuf *mb, *mreq;
2228 struct vnode *dirp = NULL;
2231 struct mount *mp = NULL;
2235 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2239 fhp = &nfh.fh_generic;
2241 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2245 vfslocked = VFS_LOCK_GIANT(mp);
2246 (void) vn_start_write(NULL, &mp, V_WAIT);
2247 vfs_rel(mp); /* The write holds a ref. */
2248 nfsm_srvnamesiz(len);
2249 nd.ni_cnd.cn_cred = cred;
2250 nd.ni_cnd.cn_nameiop = CREATE;
2251 nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART | MPSAFE;
2252 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
2253 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2254 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2259 nfsm_srvpathsiz(len2);
2267 pathcp = malloc(len2 + 1, M_TEMP, M_WAITOK);
2268 iv.iov_base = pathcp;
2270 io.uio_resid = len2;
2274 io.uio_segflg = UIO_SYSSPACE;
2275 io.uio_rw = UIO_READ;
2277 nfsm_mtouio(&io, len2);
2279 sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
2280 vap->va_mode = nfstov_mode(sp->sa_mode);
2282 *(pathcp + len2) = '\0';
2289 * issue symlink op. SAVESTART is set so the underlying path component
2290 * is only freed by the VOP if an error occurs.
2292 if (vap->va_mode == (mode_t)VNOVAL)
2294 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp);
2296 NDFREE(&nd, NDF_ONLY_PNBUF);
2301 * releases directory prior to potential lookup op.
2309 * Issue lookup. Leave SAVESTART set so we can easily free
2310 * the name buffer later on.
2312 * since LOCKPARENT is not set, ni_dvp will be garbage on
2313 * return whether an error occurs or not.
2315 nd.ni_cnd.cn_nameiop = LOOKUP;
2316 nd.ni_cnd.cn_flags &= ~(LOCKPARENT | FOLLOW);
2317 nd.ni_cnd.cn_flags |= (NOFOLLOW | LOCKLEAF);
2318 nd.ni_cnd.cn_thread = curthread;
2319 nd.ni_cnd.cn_cred = cred;
2320 tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
2322 nd.ni_cnd.cn_flags |= GIANTHELD;
2323 error = lookup(&nd);
2325 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2326 nd.ni_cnd.cn_flags &= ~GIANTHELD;
2329 bzero((caddr_t)fhp, sizeof(nfh));
2330 fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
2331 error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
2333 error = VOP_GETATTR(nd.ni_vp, vap, cred);
2341 * These releases aren't strictly required, does even doing them
2342 * make any sense? XXX can nfsm_reply() block?
2345 free(pathcp, M_TEMP);
2349 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2350 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2351 VOP_UNLOCK(dirp, 0);
2353 if (nd.ni_startdir) {
2354 vrele(nd.ni_startdir);
2355 nd.ni_startdir = NULL;
2357 nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2360 nfsm_srvpostop_fh(fhp);
2361 nfsm_srvpostop_attr(0, vap);
2363 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2369 NDFREE(&nd, NDF_ONLY_PNBUF);
2371 if (nd.ni_dvp == nd.ni_vp)
2379 vrele(nd.ni_startdir);
2383 free(pathcp, M_TEMP);
2385 vn_finished_write(mp);
2386 VFS_UNLOCK_GIANT(vfslocked);
2394 nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2397 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2398 struct sockaddr *nam = nfsd->nd_nam;
2399 caddr_t dpos = nfsd->nd_dpos;
2400 struct ucred *cred = nfsd->nd_cr;
2401 struct vattr va, dirfor, diraft;
2402 struct vattr *vap = &va;
2403 struct nfs_fattr *fp;
2404 struct nameidata nd;
2407 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
2408 int v3 = (nfsd->nd_flag & ND_NFSV3);
2409 struct mbuf *mb, *mreq;
2410 struct vnode *dirp = NULL;
2414 struct mount *mp = NULL;
2417 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2421 fhp = &nfh.fh_generic;
2423 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2427 vfslocked = VFS_LOCK_GIANT(mp);
2428 (void) vn_start_write(NULL, &mp, V_WAIT);
2429 vfs_rel(mp); /* The write holds a ref. */
2430 nfsm_srvnamesiz(len);
2431 nd.ni_cnd.cn_cred = cred;
2432 nd.ni_cnd.cn_nameiop = CREATE;
2433 nd.ni_cnd.cn_flags = LOCKPARENT | MPSAFE;
2435 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
2436 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2437 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2443 nfsm_reply(NFSX_WCCDATA(v3));
2445 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2453 tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
2454 vap->va_mode = nfstov_mode(*tl++);
2458 * At this point nd.ni_dvp is referenced and exclusively locked and
2459 * nd.ni_vp, if it exists, is referenced but not locked.
2462 vap->va_type = VDIR;
2463 if (nd.ni_vp != NULL) {
2464 NDFREE(&nd, NDF_ONLY_PNBUF);
2470 * Issue mkdir op. Since SAVESTART is not set, the pathname
2471 * component is freed by the VOP call. This will fill-in
2472 * nd.ni_vp, reference, and exclusively lock it.
2474 if (vap->va_mode == (mode_t)VNOVAL)
2476 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
2477 NDFREE(&nd, NDF_ONLY_PNBUF);
2484 bzero((caddr_t)fhp, sizeof(nfh));
2485 fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
2486 error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
2488 error = VOP_GETATTR(nd.ni_vp, vap, cred);
2492 if (dirp == nd.ni_dvp) {
2493 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2495 /* Release existing locks to prevent deadlock. */
2497 NDFREE(&nd, NDF_ONLY_PNBUF);
2498 if (nd.ni_dvp == nd.ni_vp && vpexcl)
2511 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2512 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2513 VOP_UNLOCK(dirp, 0);
2516 nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
2519 nfsm_srvpostop_fh(fhp);
2520 nfsm_srvpostop_attr(0, vap);
2522 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2523 } else if (!error) {
2524 /* v2 non-error case. */
2525 nfsm_srvfhtom(fhp, v3);
2526 fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
2527 nfsm_srvfillattr(vap, fp);
2534 NDFREE(&nd, NDF_ONLY_PNBUF);
2535 if (nd.ni_dvp == nd.ni_vp && vpexcl)
2548 vn_finished_write(mp);
2549 VFS_UNLOCK_GIANT(vfslocked);
2557 nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2560 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2561 struct sockaddr *nam = nfsd->nd_nam;
2562 caddr_t dpos = nfsd->nd_dpos;
2563 struct ucred *cred = nfsd->nd_cr;
2565 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
2566 int v3 = (nfsd->nd_flag & ND_NFSV3);
2567 struct mbuf *mb, *mreq;
2568 struct vnode *vp, *dirp = NULL;
2569 struct vattr dirfor, diraft;
2572 struct nameidata nd;
2573 struct mount *mp = NULL;
2576 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2580 fhp = &nfh.fh_generic;
2582 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
2586 vfslocked = VFS_LOCK_GIANT(mp);
2587 (void) vn_start_write(NULL, &mp, V_WAIT);
2588 vfs_rel(mp); /* The write holds a ref. */
2589 nfsm_srvnamesiz(len);
2590 nd.ni_cnd.cn_cred = cred;
2591 nd.ni_cnd.cn_nameiop = DELETE;
2592 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | MPSAFE;
2593 error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
2594 &dirp, v3, &dirfor, &dirfor_ret, FALSE);
2595 vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
2601 nfsm_reply(NFSX_WCCDATA(v3));
2603 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2608 if (vp->v_type != VDIR) {
2613 * No rmdir "." please.
2615 if (nd.ni_dvp == vp) {
2620 * The root of a mounted filesystem cannot be deleted.
2622 if (vp->v_vflag & VV_ROOT)
2626 * Issue or abort op. Since SAVESTART is not set, path name
2627 * component is freed by the VOP after either.
2630 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
2631 NDFREE(&nd, NDF_ONLY_PNBUF);
2634 if (dirp == nd.ni_dvp)
2635 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2637 /* Release existing locks to prevent deadlock. */
2639 if (nd.ni_dvp == nd.ni_vp)
2648 vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
2649 diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
2650 VOP_UNLOCK(dirp, 0);
2653 nfsm_reply(NFSX_WCCDATA(v3));
2656 nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
2660 NDFREE(&nd, NDF_ONLY_PNBUF);
2662 if (nd.ni_dvp == nd.ni_vp)
2672 vn_finished_write(mp);
2673 VFS_UNLOCK_GIANT(vfslocked);
2678 * nfs readdir service
2679 * - mallocs what it thinks is enough to read
2680 * count rounded up to a multiple of NFS_DIRBLKSIZ <= NFS_MAXREADDIR
2681 * - calls VOP_READDIR()
2682 * - loops around building the reply
2683 * if the output generated exceeds count break out of loop
2684 * The nfsm_clget macro is used here so that the reply will be packed
2685 * tightly in mbuf clusters.
2686 * - it only knows that it has encountered eof when the VOP_READDIR()
2688 * - as such one readdir rpc will return eof false although you are there
2689 * and then the next will return eof
2690 * - it trims out records with d_fileno == 0
2691 * this doesn't matter for Unix clients, but they might confuse clients
2693 * NB: It is tempting to set eof to true if the VOP_READDIR() reads less
2694 * than requested, but this may not apply to all filesystems. For
2695 * example, client NFS does not { although it is never remote mounted
2697 * The alternate call nfsrv_readdirplus() does lookups as well.
2698 * PS: The NFS protocol spec. does not clarify what the "count" byte
2699 * argument is a count of.. just name strings and file id's or the
2700 * entire reply rpc or ...
2701 * I tried just file name and id sizes and it confused the Sun client,
2702 * so I am using the full rpc size now. The "paranoia.." comment refers
2703 * to including the status longwords that are not a part of the dir.
2704 * "entry" structures, but are in the rpc.
2708 u_int32_t fl_postopok;
2709 u_int32_t fl_fattr[NFSX_V3FATTR / sizeof (u_int32_t)];
2711 u_int32_t fl_fhsize;
2712 u_int32_t fl_nfh[NFSX_V3FH / sizeof (u_int32_t)];
2716 nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2719 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
2720 struct sockaddr *nam = nfsd->nd_nam;
2721 caddr_t dpos = nfsd->nd_dpos;
2722 struct ucred *cred = nfsd->nd_cr;
2729 struct mbuf *mb, *mreq;
2730 char *cpos, *cend, *rbuf;
2731 struct vnode *vp = NULL;
2737 int len, nlen, rem, xfer, tsiz, i, error = 0, getret = 1;
2738 int siz, cnt, fullsiz, eofflag, rdonly, ncookies;
2739 int v3 = (nfsd->nd_flag & ND_NFSV3);
2740 u_quad_t off, toff, verf;
2741 u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
2742 int vfslocked, not_zfs;
2744 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
2746 fhp = &nfh.fh_generic;
2749 tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED);
2750 toff = fxdr_hyper(tl);
2752 verf = fxdr_hyper(tl);
2755 tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
2756 toff = fxdr_unsigned(u_quad_t, *tl++);
2757 verf = 0; /* shut up gcc */
2760 cnt = fxdr_unsigned(int, *tl);
2761 siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
2762 xfer = NFS_SRVMAXDATA(nfsd);
2768 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
2769 if (!error && vp->v_type != VDIR) {
2775 nfsm_reply(NFSX_UNSIGNED);
2777 nfsm_srvpostop_attr(getret, &at);
2783 * Obtain lock on vnode for this section of the code
2786 error = getret = VOP_GETATTR(vp, &at, cred);
2789 * XXX This check may be too strict for Solaris 2.5 clients.
2791 if (!error && toff && verf && verf != at.va_filerev)
2792 error = NFSERR_BAD_COOKIE;
2796 error = nfsrv_access(vp, VEXEC, cred, rdonly, 0);
2800 nfsm_reply(NFSX_POSTOPATTR(v3));
2802 nfsm_srvpostop_attr(getret, &at);
2806 not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
2810 * end section. Allocate rbuf and continue
2812 rbuf = malloc(siz, M_TEMP, M_WAITOK);
2815 iv.iov_len = fullsiz;
2818 io.uio_offset = (off_t)off;
2819 io.uio_resid = fullsiz;
2820 io.uio_segflg = UIO_SYSSPACE;
2821 io.uio_rw = UIO_READ;
2825 free((caddr_t)cookies, M_TEMP);
2828 vn_lock(vp, LK_SHARED | LK_RETRY);
2829 error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
2830 off = (off_t)io.uio_offset;
2831 if (!cookies && !error)
2832 error = NFSERR_PERM;
2834 getret = VOP_GETATTR(vp, &at, cred);
2842 free((caddr_t)rbuf, M_TEMP);
2844 free((caddr_t)cookies, M_TEMP);
2845 nfsm_reply(NFSX_POSTOPATTR(v3));
2847 nfsm_srvpostop_attr(getret, &at);
2852 siz -= io.uio_resid;
2855 * If nothing read, return eof
2861 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) +
2864 nfsm_srvpostop_attr(getret, &at);
2865 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
2866 txdr_hyper(at.va_filerev, tl);
2869 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
2870 *tl++ = nfsrv_nfs_false;
2871 *tl = nfsrv_nfs_true;
2872 free((caddr_t)rbuf, M_TEMP);
2873 free((caddr_t)cookies, M_TEMP);
2880 * Check for degenerate cases of nothing useful read.
2881 * If so go try again
2885 dp = (struct dirent *)cpos;
2888 * For some reason FreeBSD's ufs_readdir() chooses to back the
2889 * directory offset up to a block boundary, so it is necessary to
2890 * skip over the records that precede the requested offset. This
2891 * requires the assumption that file offset cookies monotonically
2893 * Since the offset cookies don't monotonically increase for ZFS,
2894 * this is not done when ZFS is the file system.
2896 while (cpos < cend && ncookies > 0 &&
2897 (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
2898 (not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
2899 cpos += dp->d_reclen;
2900 dp = (struct dirent *)cpos;
2904 if (cpos >= cend || ncookies == 0) {
2910 len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */
2911 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + siz);
2913 nfsm_srvpostop_attr(getret, &at);
2914 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
2915 txdr_hyper(at.va_filerev, tl);
2919 be = bp + M_TRAILINGSPACE(mp);
2921 /* Loop through the records and build reply */
2922 while (cpos < cend && ncookies > 0) {
2923 if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
2924 nlen = dp->d_namlen;
2925 rem = nfsm_rndup(nlen) - nlen;
2926 len += (4 * NFSX_UNSIGNED + nlen + rem);
2928 len += 2 * NFSX_UNSIGNED;
2934 * Build the directory record xdr from
2938 *tl = nfsrv_nfs_true;
2939 bp += NFSX_UNSIGNED;
2943 bp += NFSX_UNSIGNED;
2946 *tl = txdr_unsigned(dp->d_fileno);
2947 bp += NFSX_UNSIGNED;
2949 *tl = txdr_unsigned(nlen);
2950 bp += NFSX_UNSIGNED;
2952 /* And loop around copying the name */
2961 bcopy(cp, bp, tsiz);
2967 /* And null pad to an int32_t boundary. */
2968 for (i = 0; i < rem; i++)
2972 /* Finish off the record */
2975 bp += NFSX_UNSIGNED;
2978 *tl = txdr_unsigned(*cookiep);
2979 bp += NFSX_UNSIGNED;
2981 cpos += dp->d_reclen;
2982 dp = (struct dirent *)cpos;
2989 *tl = nfsrv_nfs_false;
2990 bp += NFSX_UNSIGNED;
2993 *tl = nfsrv_nfs_true;
2995 *tl = nfsrv_nfs_false;
2996 bp += NFSX_UNSIGNED;
2999 mp->m_len = bp - mtod(mp, caddr_t);
3001 mp->m_len += bp - bpos;
3002 free((caddr_t)rbuf, M_TEMP);
3003 free((caddr_t)cookies, M_TEMP);
3008 VFS_UNLOCK_GIANT(vfslocked);
3013 nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3016 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3017 struct sockaddr *nam = nfsd->nd_nam;
3018 caddr_t dpos = nfsd->nd_dpos;
3019 struct ucred *cred = nfsd->nd_cr;
3026 struct mbuf *mb, *mreq;
3027 char *cpos, *cend, *rbuf;
3028 struct vnode *vp = NULL, *nvp;
3031 fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh;
3034 struct vattr va, at, *vap = &va;
3035 struct nfs_fattr *fp;
3036 int len, nlen, rem, xfer, tsiz, i, error = 0, error1, getret = 1;
3038 int siz, cnt, fullsiz, eofflag, rdonly, dirlen, ncookies;
3039 u_quad_t off, toff, verf;
3040 u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
3041 int v3 = (nfsd->nd_flag & ND_NFSV3);
3042 int usevget = 1, vfslocked;
3043 struct componentname cn;
3044 struct mount *mntp = NULL;
3047 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3051 panic("nfsrv_readdirplus: v3 proc called on a v2 connection");
3052 fhp = &nfh.fh_generic;
3054 tl = nfsm_dissect_nonblock(u_int32_t *, 6 * NFSX_UNSIGNED);
3055 toff = fxdr_hyper(tl);
3057 verf = fxdr_hyper(tl);
3059 siz = fxdr_unsigned(int, *tl++);
3060 cnt = fxdr_unsigned(int, *tl);
3062 siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
3063 xfer = NFS_SRVMAXDATA(nfsd);
3069 error = nfsrv_fhtovp(fhp, NFSRV_FLAG_BUSY, &vp, &vfslocked, nfsd, slp,
3074 if (vp->v_type != VDIR) {
3082 nfsm_reply(NFSX_UNSIGNED);
3083 nfsm_srvpostop_attr(getret, &at);
3087 error = getret = VOP_GETATTR(vp, &at, cred);
3090 * XXX This check may be too strict for Solaris 2.5 clients.
3092 if (!error && toff && verf && verf != at.va_filerev)
3093 error = NFSERR_BAD_COOKIE;
3096 error = nfsrv_access(vp, VEXEC, cred, rdonly, 0);
3101 nfsm_reply(NFSX_V3POSTOPATTR);
3102 nfsm_srvpostop_attr(getret, &at);
3106 not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
3109 rbuf = malloc(siz, M_TEMP, M_WAITOK);
3112 iv.iov_len = fullsiz;
3115 io.uio_offset = (off_t)off;
3116 io.uio_resid = fullsiz;
3117 io.uio_segflg = UIO_SYSSPACE;
3118 io.uio_rw = UIO_READ;
3123 free((caddr_t)cookies, M_TEMP);
3126 vn_lock(vp, LK_SHARED | LK_RETRY);
3127 error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
3128 off = (u_quad_t)io.uio_offset;
3129 getret = VOP_GETATTR(vp, &at, cred);
3132 if (!cookies && !error)
3133 error = NFSERR_PERM;
3140 free((caddr_t)cookies, M_TEMP);
3141 free((caddr_t)rbuf, M_TEMP);
3142 nfsm_reply(NFSX_V3POSTOPATTR);
3143 nfsm_srvpostop_attr(getret, &at);
3148 siz -= io.uio_resid;
3151 * If nothing read, return eof
3157 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
3159 nfsm_srvpostop_attr(getret, &at);
3160 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
3161 txdr_hyper(at.va_filerev, tl);
3163 *tl++ = nfsrv_nfs_false;
3164 *tl = nfsrv_nfs_true;
3165 free((caddr_t)cookies, M_TEMP);
3166 free((caddr_t)rbuf, M_TEMP);
3173 * Check for degenerate cases of nothing useful read.
3174 * If so go try again
3178 dp = (struct dirent *)cpos;
3181 * For some reason FreeBSD's ufs_readdir() chooses to back the
3182 * directory offset up to a block boundary, so it is necessary to
3183 * skip over the records that precede the requested offset. This
3184 * requires the assumption that file offset cookies monotonically
3186 * Since the offset cookies don't monotonically increase for ZFS,
3187 * this is not done when ZFS is the file system.
3189 while (cpos < cend && ncookies > 0 &&
3190 (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
3191 (not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
3192 cpos += dp->d_reclen;
3193 dp = (struct dirent *)cpos;
3197 if (cpos >= cend || ncookies == 0) {
3203 dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
3206 nfsm_srvpostop_attr(getret, &at);
3207 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
3208 txdr_hyper(at.va_filerev, tl);
3211 be = bp + M_TRAILINGSPACE(mp);
3213 /* Loop through the records and build reply */
3214 while (cpos < cend && ncookies > 0) {
3215 if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
3216 nlen = dp->d_namlen;
3217 rem = nfsm_rndup(nlen)-nlen;
3221 * For readdir_and_lookup get the vnode using
3224 error = VFS_VGET(mntp, dp->d_fileno, LK_SHARED,
3226 if (error != 0 && error != EOPNOTSUPP) {
3229 } else if (error == EOPNOTSUPP) {
3231 * VFS_VGET() not supported?
3232 * Let's switch to VOP_LOOKUP().
3236 cn.cn_nameiop = LOOKUP;
3237 cn.cn_flags = ISLASTCN | NOFOLLOW | \
3238 LOCKSHARED | LOCKLEAF | MPSAFE;
3239 cn.cn_lkflags = LK_SHARED | LK_RETRY;
3241 cn.cn_thread = curthread;
3245 cn.cn_nameptr = dp->d_name;
3246 cn.cn_namelen = dp->d_namlen;
3247 if (dp->d_namlen == 2 &&
3248 dp->d_name[0] == '.' &&
3249 dp->d_name[1] == '.') {
3250 cn.cn_flags |= ISDOTDOT;
3252 cn.cn_flags &= ~ISDOTDOT;
3255 vn_lock(vp, LK_SHARED | LK_RETRY);
3258 if ((vp->v_vflag & VV_ROOT) != 0 &&
3259 (cn.cn_flags & ISDOTDOT) != 0) {
3262 } else if (VOP_LOOKUP(vp, &nvp, &cn) != 0)
3266 bzero((caddr_t)nfhp, NFSX_V3FH);
3267 nfhp->fh_fsid = nvp->v_mount->mnt_stat.f_fsid;
3268 if ((error1 = VOP_VPTOFH(nvp, &nfhp->fh_fid)) == 0)
3269 error1 = VOP_GETATTR(nvp, vap, cred);
3270 if (!usevget && vp == nvp)
3279 * If either the dircount or maxcount will be
3280 * exceeded, get out now. Both of these lengths
3281 * are calculated conservatively, including all
3284 len += (8 * NFSX_UNSIGNED + nlen + rem + NFSX_V3FH +
3286 dirlen += (6 * NFSX_UNSIGNED + nlen + rem);
3287 if (len > cnt || dirlen > fullsiz) {
3293 * Build the directory record xdr from
3296 fp = (struct nfs_fattr *)&fl.fl_fattr;
3297 nfsm_srvfillattr(vap, fp);
3298 fl.fl_fhsize = txdr_unsigned(NFSX_V3FH);
3299 fl.fl_fhok = nfsrv_nfs_true;
3300 fl.fl_postopok = nfsrv_nfs_true;
3301 fl.fl_off.nfsuquad[0] = 0;
3302 fl.fl_off.nfsuquad[1] = txdr_unsigned(*cookiep);
3305 *tl = nfsrv_nfs_true;
3306 bp += NFSX_UNSIGNED;
3309 bp += NFSX_UNSIGNED;
3311 *tl = txdr_unsigned(dp->d_fileno);
3312 bp += NFSX_UNSIGNED;
3314 *tl = txdr_unsigned(nlen);
3315 bp += NFSX_UNSIGNED;
3317 /* And loop around copying the name */
3322 if ((bp + xfer) > be)
3326 bcopy(cp, bp, tsiz);
3332 /* And null pad to an int32_t boundary. */
3333 for (i = 0; i < rem; i++)
3337 * Now copy the flrep structure out.
3339 xfer = sizeof (struct flrep);
3343 if ((bp + xfer) > be)
3347 bcopy(cp, bp, tsiz);
3355 cpos += dp->d_reclen;
3356 dp = (struct dirent *)cpos;
3360 if (!usevget && vp_locked)
3366 *tl = nfsrv_nfs_false;
3367 bp += NFSX_UNSIGNED;
3370 *tl = nfsrv_nfs_true;
3372 *tl = nfsrv_nfs_false;
3373 bp += NFSX_UNSIGNED;
3376 mp->m_len = bp - mtod(mp, caddr_t);
3378 mp->m_len += bp - bpos;
3379 free((caddr_t)cookies, M_TEMP);
3380 free((caddr_t)rbuf, M_TEMP);
3386 VFS_UNLOCK_GIANT(vfslocked);
3391 * nfs commit service
3394 nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3397 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3398 struct sockaddr *nam = nfsd->nd_nam;
3399 caddr_t dpos = nfsd->nd_dpos;
3400 struct ucred *cred = nfsd->nd_cr;
3401 struct vattr bfor, aft;
3402 struct vnode *vp = NULL;
3407 int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt;
3408 struct mbuf *mb, *mreq;
3410 struct mount *mp = NULL;
3411 int v3 = (nfsd->nd_flag & ND_NFSV3);
3415 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3418 panic("nfsrv_commit: v3 proc called on a v2 connection");
3419 fhp = &nfh.fh_generic;
3421 if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
3425 vfslocked = VFS_LOCK_GIANT(mp);
3426 (void) vn_start_write(NULL, &mp, V_WAIT);
3427 vfs_rel(mp); /* The write holds a ref. */
3428 tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED);
3431 * XXX At this time VOP_FSYNC() does not accept offset and byte
3432 * count parameters, so these arguments are useless (someday maybe).
3434 off = fxdr_hyper(tl);
3436 cnt = fxdr_unsigned(int, *tl);
3437 error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
3438 vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
3440 nfsm_reply(2 * NFSX_UNSIGNED);
3441 nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
3445 for_ret = VOP_GETATTR(vp, &bfor, cred);
3447 if (cnt > MAX_COMMIT_COUNT) {
3449 * Give up and do the whole thing
3452 (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) {
3453 VM_OBJECT_LOCK(vp->v_object);
3454 vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC);
3455 VM_OBJECT_UNLOCK(vp->v_object);
3457 error = VOP_FSYNC(vp, MNT_WAIT, curthread);
3460 * Locate and synchronously write any buffers that fall
3461 * into the requested range. Note: we are assuming that
3462 * f_iosize is a power of 2.
3464 int iosize = vp->v_mount->mnt_stat.f_iosize;
3465 int iomask = iosize - 1;
3470 * Align to iosize boundry, super-align to page boundry.
3473 cnt += off & iomask;
3474 off &= ~(u_quad_t)iomask;
3476 if (off & PAGE_MASK) {
3477 cnt += off & PAGE_MASK;
3478 off &= ~(u_quad_t)PAGE_MASK;
3480 lblkno = off / iosize;
3483 (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) {
3484 VM_OBJECT_LOCK(vp->v_object);
3485 vm_object_page_clean(vp->v_object, off, off + cnt,
3487 VM_OBJECT_UNLOCK(vp->v_object);
3496 * If we have a buffer and it is marked B_DELWRI we
3497 * have to lock and write it. Otherwise the prior
3498 * write is assumed to have already been committed.
3500 * gbincore() can return invalid buffers now so we
3501 * have to check that bit as well (though B_DELWRI
3502 * should not be set if B_INVAL is set there could be
3503 * a race here since we haven't locked the buffer).
3505 if ((bp = gbincore(&vp->v_bufobj, lblkno)) != NULL) {
3506 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL |
3507 LK_INTERLOCK, BO_MTX(bo)) == ENOLCK) {
3509 continue; /* retry */
3511 if ((bp->b_flags & (B_DELWRI|B_INVAL)) ==
3514 bp->b_flags &= ~B_ASYNC;
3530 aft_ret = VOP_GETATTR(vp, &aft, cred);
3534 nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF);
3535 nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
3537 tl = nfsm_build(u_int32_t *, NFSX_V3WRITEVERF);
3538 if (nfsver.tv_sec == 0)
3540 *tl++ = txdr_unsigned(nfsver.tv_sec);
3541 *tl = txdr_unsigned(nfsver.tv_usec);
3548 vn_finished_write(mp);
3549 VFS_UNLOCK_GIANT(vfslocked);
3554 * nfs statfs service
3557 nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3560 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3561 struct sockaddr *nam = nfsd->nd_nam;
3562 caddr_t dpos = nfsd->nd_dpos;
3563 struct ucred *cred = nfsd->nd_cr;
3565 struct nfs_statfs *sfp;
3567 int error = 0, rdonly, getret = 1;
3568 int v3 = (nfsd->nd_flag & ND_NFSV3);
3569 struct mbuf *mb, *mreq;
3570 struct vnode *vp = NULL;
3574 struct statfs statfs;
3578 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3580 fhp = &nfh.fh_generic;
3582 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
3584 nfsm_reply(NFSX_UNSIGNED);
3586 nfsm_srvpostop_attr(getret, &at);
3591 error = VFS_STATFS(vp->v_mount, sf);
3592 getret = VOP_GETATTR(vp, &at, cred);
3595 nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_STATFS(v3));
3597 nfsm_srvpostop_attr(getret, &at);
3602 sfp = nfsm_build(struct nfs_statfs *, NFSX_STATFS(v3));
3604 tval = (u_quad_t)sf->f_blocks;
3605 tval *= (u_quad_t)sf->f_bsize;
3606 txdr_hyper(tval, &sfp->sf_tbytes);
3607 tval = (u_quad_t)sf->f_bfree;
3608 tval *= (u_quad_t)sf->f_bsize;
3609 txdr_hyper(tval, &sfp->sf_fbytes);
3611 * Don't send negative values for available space,
3612 * since this field is unsigned in the NFS protocol.
3613 * Otherwise, the client would see absurdly high
3614 * numbers for free space.
3616 if (sf->f_bavail < 0)
3619 tval = (u_quad_t)sf->f_bavail;
3620 tval *= (u_quad_t)sf->f_bsize;
3621 txdr_hyper(tval, &sfp->sf_abytes);
3622 sfp->sf_tfiles.nfsuquad[0] = 0;
3623 sfp->sf_tfiles.nfsuquad[1] = txdr_unsigned(sf->f_files);
3624 sfp->sf_ffiles.nfsuquad[0] = 0;
3625 sfp->sf_ffiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
3626 sfp->sf_afiles.nfsuquad[0] = 0;
3627 sfp->sf_afiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
3628 sfp->sf_invarsec = 0;
3630 sfp->sf_tsize = txdr_unsigned(NFS_MAXDGRAMDATA);
3631 sfp->sf_bsize = txdr_unsigned(sf->f_bsize);
3632 sfp->sf_blocks = txdr_unsigned(sf->f_blocks);
3633 sfp->sf_bfree = txdr_unsigned(sf->f_bfree);
3634 if (sf->f_bavail < 0)
3637 sfp->sf_bavail = txdr_unsigned(sf->f_bavail);
3642 VFS_UNLOCK_GIANT(vfslocked);
3647 * nfs fsinfo service
3650 nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3653 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3654 struct sockaddr *nam = nfsd->nd_nam;
3655 caddr_t dpos = nfsd->nd_dpos;
3656 struct ucred *cred = nfsd->nd_cr;
3657 struct nfsv3_fsinfo *sip;
3659 int error = 0, rdonly, getret = 1, pref;
3660 struct mbuf *mb, *mreq;
3661 struct vnode *vp = NULL;
3667 int v3 = (nfsd->nd_flag & ND_NFSV3);
3670 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3672 panic("nfsrv_fsinfo: v3 proc called on a v2 connection");
3673 fhp = &nfh.fh_generic;
3676 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
3678 nfsm_reply(NFSX_UNSIGNED);
3679 nfsm_srvpostop_attr(getret, &at);
3684 /* XXX Try to make a guess on the max file size. */
3685 VFS_STATFS(vp->v_mount, &sb);
3686 maxfsize = (u_quad_t)0x80000000 * sb.f_bsize - 1;
3688 getret = VOP_GETATTR(vp, &at, cred);
3691 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO);
3692 nfsm_srvpostop_attr(getret, &at);
3693 sip = nfsm_build(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
3697 * There should be filesystem VFS OP(s) to get this information.
3698 * For now, assume ufs.
3700 pref = NFS_SRVMAXDATA(nfsd);
3701 sip->fs_rtmax = txdr_unsigned(pref);
3702 sip->fs_rtpref = txdr_unsigned(pref);
3703 sip->fs_rtmult = txdr_unsigned(NFS_FABLKSIZE);
3704 sip->fs_wtmax = txdr_unsigned(pref);
3705 sip->fs_wtpref = txdr_unsigned(pref);
3706 sip->fs_wtmult = txdr_unsigned(NFS_FABLKSIZE);
3707 sip->fs_dtpref = txdr_unsigned(pref);
3708 txdr_hyper(maxfsize, &sip->fs_maxfilesize);
3709 sip->fs_timedelta.nfsv3_sec = 0;
3710 sip->fs_timedelta.nfsv3_nsec = txdr_unsigned(1);
3711 sip->fs_properties = txdr_unsigned(NFSV3FSINFO_LINK |
3712 NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS |
3713 NFSV3FSINFO_CANSETTIME);
3717 VFS_UNLOCK_GIANT(vfslocked);
3722 * nfs pathconf service
3725 nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3728 struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
3729 struct sockaddr *nam = nfsd->nd_nam;
3730 caddr_t dpos = nfsd->nd_dpos;
3731 struct ucred *cred = nfsd->nd_cr;
3732 struct nfsv3_pathconf *pc;
3734 int error = 0, rdonly, getret = 1;
3735 register_t linkmax, namemax, chownres, notrunc;
3736 struct mbuf *mb, *mreq;
3737 struct vnode *vp = NULL;
3741 int v3 = (nfsd->nd_flag & ND_NFSV3);
3744 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3746 panic("nfsrv_pathconf: v3 proc called on a v2 connection");
3748 fhp = &nfh.fh_generic;
3750 error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
3752 nfsm_reply(NFSX_UNSIGNED);
3753 nfsm_srvpostop_attr(getret, &at);
3757 error = VOP_PATHCONF(vp, _PC_LINK_MAX, &linkmax);
3759 error = VOP_PATHCONF(vp, _PC_NAME_MAX, &namemax);
3761 error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &chownres);
3763 error = VOP_PATHCONF(vp, _PC_NO_TRUNC, ¬runc);
3764 getret = VOP_GETATTR(vp, &at, cred);
3767 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF);
3768 nfsm_srvpostop_attr(getret, &at);
3773 pc = nfsm_build(struct nfsv3_pathconf *, NFSX_V3PATHCONF);
3775 pc->pc_linkmax = txdr_unsigned(linkmax);
3776 pc->pc_namemax = txdr_unsigned(namemax);
3777 pc->pc_notrunc = txdr_unsigned(notrunc);
3778 pc->pc_chownrestricted = txdr_unsigned(chownres);
3781 * These should probably be supported by VOP_PATHCONF(), but
3782 * until msdosfs is exportable (why would you want to?), the
3783 * Unix defaults should be ok.
3785 pc->pc_caseinsensitive = nfsrv_nfs_false;
3786 pc->pc_casepreserving = nfsrv_nfs_true;
3790 VFS_UNLOCK_GIANT(vfslocked);
3795 * Null operation, used by clients to ping server
3799 nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3802 struct mbuf *mrep = nfsd->nd_mrep;
3804 int error = NFSERR_RETVOID;
3805 struct mbuf *mb, *mreq;
3807 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3814 * No operation, used for obsolete procedures
3818 nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
3821 struct mbuf *mrep = nfsd->nd_mrep;
3824 struct mbuf *mb, *mreq;
3826 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3827 if (nfsd->nd_repstat)
3828 error = nfsd->nd_repstat;
3830 error = EPROCUNAVAIL;
3838 * Perform access checking for vnodes obtained from file handles that would
3839 * refer to files already opened by a Unix client. You cannot just use
3840 * vn_writechk() and VOP_ACCESS() for two reasons.
3841 * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write
3843 * 2 - The owner is to be given access irrespective of mode bits for some
3844 * operations, so that processes that chmod after opening a file don't
3845 * break. I don't like this because it opens a security hole, but since
3846 * the nfs server opens a security hole the size of a barn door anyhow,
3849 * The exception to rule 2 is EPERM. If a file is IMMUTABLE, VOP_ACCESS()
3850 * will return EPERM instead of EACCES. EPERM is always an error.
3853 nfsrv_access(struct vnode *vp, accmode_t accmode, struct ucred *cred,
3854 int rdonly, int override)
3859 VFS_ASSERT_GIANT(vp->v_mount);
3861 nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
3863 if (accmode & VWRITE) {
3864 /* Just vn_writechk() changed to check rdonly */
3866 * Disallow write attempts on read-only filesystems;
3867 * unless the file is a socket or a block or character
3868 * device resident on the filesystem.
3870 if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
3871 switch (vp->v_type) {
3881 * If there's shared text associated with
3882 * the inode, we can't allow writing.
3884 if (vp->v_vflag & VV_TEXT)
3888 error = VOP_GETATTR(vp, &vattr, cred);
3891 error = VOP_ACCESS(vp, accmode, cred, curthread);
3893 * Allow certain operations for the owner (reads and writes
3894 * on files that are already open).
3896 if (override && error == EACCES && cred->cr_uid == vattr.va_uid)