1*c10f8b50Spgoyette /* $NetBSD: nfs_nfsdsocket.c,v 1.2 2016/12/13 21:50:32 pgoyette Exp $ */
26ca35587Sdholland /*-
36ca35587Sdholland * Copyright (c) 1989, 1993
46ca35587Sdholland * The Regents of the University of California. All rights reserved.
56ca35587Sdholland *
66ca35587Sdholland * This code is derived from software contributed to Berkeley by
76ca35587Sdholland * Rick Macklem at The University of Guelph.
86ca35587Sdholland *
96ca35587Sdholland * Redistribution and use in source and binary forms, with or without
106ca35587Sdholland * modification, are permitted provided that the following conditions
116ca35587Sdholland * are met:
126ca35587Sdholland * 1. Redistributions of source code must retain the above copyright
136ca35587Sdholland * notice, this list of conditions and the following disclaimer.
146ca35587Sdholland * 2. Redistributions in binary form must reproduce the above copyright
156ca35587Sdholland * notice, this list of conditions and the following disclaimer in the
166ca35587Sdholland * documentation and/or other materials provided with the distribution.
176ca35587Sdholland * 4. Neither the name of the University nor the names of its contributors
186ca35587Sdholland * may be used to endorse or promote products derived from this software
196ca35587Sdholland * without specific prior written permission.
206ca35587Sdholland *
216ca35587Sdholland * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
226ca35587Sdholland * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
236ca35587Sdholland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
246ca35587Sdholland * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
256ca35587Sdholland * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
266ca35587Sdholland * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
276ca35587Sdholland * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
286ca35587Sdholland * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
296ca35587Sdholland * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
306ca35587Sdholland * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
316ca35587Sdholland * SUCH DAMAGE.
326ca35587Sdholland *
336ca35587Sdholland */
346ca35587Sdholland
356ca35587Sdholland #include <sys/cdefs.h>
36e81f0ea2Spgoyette /* __FBSDID("FreeBSD: head/sys/fs/nfsserver/nfs_nfsdsocket.c 304026 2016-08-12 22:44:59Z rmacklem "); */
37*c10f8b50Spgoyette __RCSID("$NetBSD: nfs_nfsdsocket.c,v 1.2 2016/12/13 21:50:32 pgoyette Exp $");
386ca35587Sdholland
396ca35587Sdholland /*
406ca35587Sdholland * Socket operations for use by the nfs server.
416ca35587Sdholland */
426ca35587Sdholland
436ca35587Sdholland #ifndef APPLEKEXT
44*c10f8b50Spgoyette #include <fs/nfs/common/nfsport.h>
456ca35587Sdholland
46e81f0ea2Spgoyette extern struct nfsstatsv1 nfsstatsv1;
476ca35587Sdholland extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
486ca35587Sdholland extern int nfs_pubfhset, nfs_rootfhset;
496ca35587Sdholland extern struct nfsv4lock nfsv4rootfs_lock;
506ca35587Sdholland extern struct nfsrv_stablefirst nfsrv_stablefirst;
51e81f0ea2Spgoyette extern struct nfsclienthashhead *nfsclienthash;
52e81f0ea2Spgoyette extern int nfsrv_clienthashsize;
536ca35587Sdholland extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
54e81f0ea2Spgoyette extern int nfsd_debuglevel;
556ca35587Sdholland NFSV4ROOTLOCKMUTEX;
566ca35587Sdholland NFSSTATESPINLOCK;
576ca35587Sdholland
586ca35587Sdholland int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *,
596ca35587Sdholland int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
606ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
616ca35587Sdholland nfsrvd_getattr,
626ca35587Sdholland nfsrvd_setattr,
636ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
646ca35587Sdholland nfsrvd_access,
656ca35587Sdholland nfsrvd_readlink,
666ca35587Sdholland nfsrvd_read,
676ca35587Sdholland nfsrvd_write,
686ca35587Sdholland nfsrvd_create,
696ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
706ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
716ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
726ca35587Sdholland nfsrvd_remove,
736ca35587Sdholland nfsrvd_remove,
746ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
756ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
766ca35587Sdholland nfsrvd_readdir,
776ca35587Sdholland nfsrvd_readdirplus,
786ca35587Sdholland nfsrvd_statfs,
796ca35587Sdholland nfsrvd_fsinfo,
806ca35587Sdholland nfsrvd_pathconf,
816ca35587Sdholland nfsrvd_commit,
826ca35587Sdholland };
836ca35587Sdholland
846ca35587Sdholland int (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *,
856ca35587Sdholland int, vnode_t , vnode_t *, fhandle_t *,
866ca35587Sdholland NFSPROC_T *, struct nfsexstuff *) = {
876ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
886ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
896ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
906ca35587Sdholland nfsrvd_lookup,
916ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
926ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
936ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
946ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
956ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
966ca35587Sdholland nfsrvd_mkdir,
976ca35587Sdholland nfsrvd_symlink,
986ca35587Sdholland nfsrvd_mknod,
996ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1006ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1016ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1026ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1036ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1046ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1056ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1066ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1076ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1086ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
1096ca35587Sdholland };
1106ca35587Sdholland
1116ca35587Sdholland int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *,
1126ca35587Sdholland int, vnode_t , vnode_t , NFSPROC_T *,
1136ca35587Sdholland struct nfsexstuff *, struct nfsexstuff *) = {
1146ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1156ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1166ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1176ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1186ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1196ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1206ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1216ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1226ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1236ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1246ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1256ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1266ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1276ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1286ca35587Sdholland nfsrvd_rename,
1296ca35587Sdholland nfsrvd_link,
1306ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1316ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1326ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1336ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1346ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1356ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
1366ca35587Sdholland };
1376ca35587Sdholland
138e81f0ea2Spgoyette int (*nfsrv4_ops0[NFSV41_NOPS])(struct nfsrv_descript *,
1396ca35587Sdholland int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
1406ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1416ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1426ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1436ca35587Sdholland nfsrvd_access,
1446ca35587Sdholland nfsrvd_close,
1456ca35587Sdholland nfsrvd_commit,
1466ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1476ca35587Sdholland nfsrvd_delegpurge,
1486ca35587Sdholland nfsrvd_delegreturn,
1496ca35587Sdholland nfsrvd_getattr,
1506ca35587Sdholland nfsrvd_getfh,
1516ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1526ca35587Sdholland nfsrvd_lock,
1536ca35587Sdholland nfsrvd_lockt,
1546ca35587Sdholland nfsrvd_locku,
1556ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1566ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1576ca35587Sdholland nfsrvd_verify,
1586ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1596ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1606ca35587Sdholland nfsrvd_openconfirm,
1616ca35587Sdholland nfsrvd_opendowngrade,
1626ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1636ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1646ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1656ca35587Sdholland nfsrvd_read,
1666ca35587Sdholland nfsrvd_readdirplus,
1676ca35587Sdholland nfsrvd_readlink,
1686ca35587Sdholland nfsrvd_remove,
1696ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1706ca35587Sdholland nfsrvd_renew,
1716ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1726ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
1736ca35587Sdholland nfsrvd_secinfo,
1746ca35587Sdholland nfsrvd_setattr,
1756ca35587Sdholland nfsrvd_setclientid,
1766ca35587Sdholland nfsrvd_setclientidcfrm,
1776ca35587Sdholland nfsrvd_verify,
1786ca35587Sdholland nfsrvd_write,
1796ca35587Sdholland nfsrvd_releaselckown,
180e81f0ea2Spgoyette nfsrvd_notsupp,
181e81f0ea2Spgoyette nfsrvd_notsupp,
182e81f0ea2Spgoyette nfsrvd_exchangeid,
183e81f0ea2Spgoyette nfsrvd_createsession,
184e81f0ea2Spgoyette nfsrvd_destroysession,
185e81f0ea2Spgoyette nfsrvd_freestateid,
186e81f0ea2Spgoyette nfsrvd_notsupp,
187e81f0ea2Spgoyette nfsrvd_notsupp,
188e81f0ea2Spgoyette nfsrvd_notsupp,
189e81f0ea2Spgoyette nfsrvd_notsupp,
190e81f0ea2Spgoyette nfsrvd_notsupp,
191e81f0ea2Spgoyette nfsrvd_notsupp,
192e81f0ea2Spgoyette nfsrvd_notsupp,
193e81f0ea2Spgoyette nfsrvd_sequence,
194e81f0ea2Spgoyette nfsrvd_notsupp,
195e81f0ea2Spgoyette nfsrvd_notsupp,
196e81f0ea2Spgoyette nfsrvd_notsupp,
197e81f0ea2Spgoyette nfsrvd_destroyclientid,
198e81f0ea2Spgoyette nfsrvd_reclaimcomplete,
1996ca35587Sdholland };
2006ca35587Sdholland
201e81f0ea2Spgoyette int (*nfsrv4_ops1[NFSV41_NOPS])(struct nfsrv_descript *,
2026ca35587Sdholland int, vnode_t , vnode_t *, fhandle_t *,
2036ca35587Sdholland NFSPROC_T *, struct nfsexstuff *) = {
2046ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2056ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2066ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2076ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2086ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2096ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2106ca35587Sdholland nfsrvd_mknod,
2116ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2126ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2136ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2146ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2156ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2166ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2176ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2186ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2196ca35587Sdholland nfsrvd_lookup,
2206ca35587Sdholland nfsrvd_lookup,
2216ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2226ca35587Sdholland nfsrvd_open,
2236ca35587Sdholland nfsrvd_openattr,
2246ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2256ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2266ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2276ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2286ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2296ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2306ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2316ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2326ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2336ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2346ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2356ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2366ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2376ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2386ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2396ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2406ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2416ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2426ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2436ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
244e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
245e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
246e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
247e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
248e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
249e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
250e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
251e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
252e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
253e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
254e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
255e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
256e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
257e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
258e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
259e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
260e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
261e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
262e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
2636ca35587Sdholland };
2646ca35587Sdholland
265e81f0ea2Spgoyette int (*nfsrv4_ops2[NFSV41_NOPS])(struct nfsrv_descript *,
2666ca35587Sdholland int, vnode_t , vnode_t , NFSPROC_T *,
2676ca35587Sdholland struct nfsexstuff *, struct nfsexstuff *) = {
2686ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2696ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2706ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2716ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2726ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2736ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2746ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2756ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2766ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2776ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2786ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2796ca35587Sdholland nfsrvd_link,
2806ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2816ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2826ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2836ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2846ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2856ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2866ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2876ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2886ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2896ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2906ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2916ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2926ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2936ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2946ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2956ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2966ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2976ca35587Sdholland nfsrvd_rename,
2986ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
2996ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3006ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3016ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3026ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3036ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3046ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3056ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3066ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3076ca35587Sdholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
308e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
309e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
310e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
311e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
312e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
313e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
314e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
315e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
316e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
317e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
318e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
319e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
320e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
321e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
322e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
323e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
324e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
325e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
326e81f0ea2Spgoyette (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
3276ca35587Sdholland };
3286ca35587Sdholland #endif /* !APPLEKEXT */
3296ca35587Sdholland
3306ca35587Sdholland /*
3316ca35587Sdholland * Static array that defines which nfs rpc's are nonidempotent
3326ca35587Sdholland */
3336ca35587Sdholland static int nfsrv_nonidempotent[NFS_V3NPROCS] = {
3346ca35587Sdholland FALSE,
3356ca35587Sdholland FALSE,
3366ca35587Sdholland TRUE,
3376ca35587Sdholland FALSE,
3386ca35587Sdholland FALSE,
3396ca35587Sdholland FALSE,
3406ca35587Sdholland FALSE,
3416ca35587Sdholland TRUE,
3426ca35587Sdholland TRUE,
3436ca35587Sdholland TRUE,
3446ca35587Sdholland TRUE,
3456ca35587Sdholland TRUE,
3466ca35587Sdholland TRUE,
3476ca35587Sdholland TRUE,
3486ca35587Sdholland TRUE,
3496ca35587Sdholland TRUE,
3506ca35587Sdholland FALSE,
3516ca35587Sdholland FALSE,
3526ca35587Sdholland FALSE,
3536ca35587Sdholland FALSE,
3546ca35587Sdholland FALSE,
3556ca35587Sdholland FALSE,
3566ca35587Sdholland };
3576ca35587Sdholland
3586ca35587Sdholland /*
3596ca35587Sdholland * This static array indicates whether or not the RPC modifies the
3606ca35587Sdholland * file system.
3616ca35587Sdholland */
3626ca35587Sdholland static int nfs_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0,
3636ca35587Sdholland 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
3646ca35587Sdholland 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
3656ca35587Sdholland
3666ca35587Sdholland /* local functions */
3676ca35587Sdholland static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
368e81f0ea2Spgoyette u_char *tag, int taglen, u_int32_t minorvers, NFSPROC_T *p);
3696ca35587Sdholland
3706ca35587Sdholland
3716ca35587Sdholland /*
3726ca35587Sdholland * This static array indicates which server procedures require the extra
3736ca35587Sdholland * arguments to return the current file handle for V2, 3.
3746ca35587Sdholland */
3756ca35587Sdholland static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
3766ca35587Sdholland 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
3776ca35587Sdholland
378e81f0ea2Spgoyette extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
3796ca35587Sdholland
3806ca35587Sdholland static int nfsv3to4op[NFS_V3NPROCS] = {
3816ca35587Sdholland NFSPROC_NULL,
3826ca35587Sdholland NFSV4OP_GETATTR,
3836ca35587Sdholland NFSV4OP_SETATTR,
3846ca35587Sdholland NFSV4OP_LOOKUP,
3856ca35587Sdholland NFSV4OP_ACCESS,
3866ca35587Sdholland NFSV4OP_READLINK,
3876ca35587Sdholland NFSV4OP_READ,
3886ca35587Sdholland NFSV4OP_WRITE,
3896ca35587Sdholland NFSV4OP_V3CREATE,
3906ca35587Sdholland NFSV4OP_MKDIR,
3916ca35587Sdholland NFSV4OP_SYMLINK,
3926ca35587Sdholland NFSV4OP_MKNOD,
3936ca35587Sdholland NFSV4OP_REMOVE,
3946ca35587Sdholland NFSV4OP_RMDIR,
3956ca35587Sdholland NFSV4OP_RENAME,
3966ca35587Sdholland NFSV4OP_LINK,
3976ca35587Sdholland NFSV4OP_READDIR,
3986ca35587Sdholland NFSV4OP_READDIRPLUS,
3996ca35587Sdholland NFSV4OP_FSSTAT,
4006ca35587Sdholland NFSV4OP_FSINFO,
4016ca35587Sdholland NFSV4OP_PATHCONF,
4026ca35587Sdholland NFSV4OP_COMMIT,
4036ca35587Sdholland };
4046ca35587Sdholland
405e81f0ea2Spgoyette static struct mtx nfsrvd_statmtx;
406e81f0ea2Spgoyette MTX_SYSINIT(nfsst, &nfsrvd_statmtx, "NFSstat", MTX_DEF);
407e81f0ea2Spgoyette
408e81f0ea2Spgoyette static void
nfsrvd_statstart(int op,struct bintime * now)409e81f0ea2Spgoyette nfsrvd_statstart(int op, struct bintime *now)
410e81f0ea2Spgoyette {
411e81f0ea2Spgoyette if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) {
412e81f0ea2Spgoyette printf("%s: op %d invalid\n", __func__, op);
413e81f0ea2Spgoyette return;
414e81f0ea2Spgoyette }
415e81f0ea2Spgoyette
416e81f0ea2Spgoyette mtx_lock(&nfsrvd_statmtx);
417e81f0ea2Spgoyette if (nfsstatsv1.srvstartcnt == nfsstatsv1.srvdonecnt) {
418e81f0ea2Spgoyette if (now != NULL)
419e81f0ea2Spgoyette nfsstatsv1.busyfrom = *now;
420e81f0ea2Spgoyette else
421e81f0ea2Spgoyette binuptime(&nfsstatsv1.busyfrom);
422e81f0ea2Spgoyette
423e81f0ea2Spgoyette }
424e81f0ea2Spgoyette nfsstatsv1.srvrpccnt[op]++;
425e81f0ea2Spgoyette nfsstatsv1.srvstartcnt++;
426e81f0ea2Spgoyette mtx_unlock(&nfsrvd_statmtx);
427e81f0ea2Spgoyette
428e81f0ea2Spgoyette }
429e81f0ea2Spgoyette
430e81f0ea2Spgoyette static void
nfsrvd_statend(int op,uint64_t bytes,struct bintime * now,struct bintime * then)431e81f0ea2Spgoyette nfsrvd_statend(int op, uint64_t bytes, struct bintime *now,
432e81f0ea2Spgoyette struct bintime *then)
433e81f0ea2Spgoyette {
434e81f0ea2Spgoyette struct bintime dt, lnow;
435e81f0ea2Spgoyette
436e81f0ea2Spgoyette if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) {
437e81f0ea2Spgoyette printf("%s: op %d invalid\n", __func__, op);
438e81f0ea2Spgoyette return;
439e81f0ea2Spgoyette }
440e81f0ea2Spgoyette
441e81f0ea2Spgoyette if (now == NULL) {
442e81f0ea2Spgoyette now = &lnow;
443e81f0ea2Spgoyette binuptime(now);
444e81f0ea2Spgoyette }
445e81f0ea2Spgoyette
446e81f0ea2Spgoyette mtx_lock(&nfsrvd_statmtx);
447e81f0ea2Spgoyette
448e81f0ea2Spgoyette nfsstatsv1.srvbytes[op] += bytes;
449e81f0ea2Spgoyette nfsstatsv1.srvops[op]++;
450e81f0ea2Spgoyette
451e81f0ea2Spgoyette if (then != NULL) {
452e81f0ea2Spgoyette dt = *now;
453e81f0ea2Spgoyette bintime_sub(&dt, then);
454e81f0ea2Spgoyette bintime_add(&nfsstatsv1.srvduration[op], &dt);
455e81f0ea2Spgoyette }
456e81f0ea2Spgoyette
457e81f0ea2Spgoyette dt = *now;
458e81f0ea2Spgoyette bintime_sub(&dt, &nfsstatsv1.busyfrom);
459e81f0ea2Spgoyette bintime_add(&nfsstatsv1.busytime, &dt);
460e81f0ea2Spgoyette nfsstatsv1.busyfrom = *now;
461e81f0ea2Spgoyette
462e81f0ea2Spgoyette nfsstatsv1.srvdonecnt++;
463e81f0ea2Spgoyette
464e81f0ea2Spgoyette mtx_unlock(&nfsrvd_statmtx);
465e81f0ea2Spgoyette }
466e81f0ea2Spgoyette
4676ca35587Sdholland /*
4686ca35587Sdholland * Do an RPC. Basically, get the file handles translated to vnode pointers
4696ca35587Sdholland * and then call the appropriate server routine. The server routines are
4706ca35587Sdholland * split into groups, based on whether they use a file handle or file
4716ca35587Sdholland * handle plus name or ...
4726ca35587Sdholland * The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
4736ca35587Sdholland */
4746ca35587Sdholland APPLESTATIC void
nfsrvd_dorpc(struct nfsrv_descript * nd,int isdgram,u_char * tag,int taglen,u_int32_t minorvers,NFSPROC_T * p)475e81f0ea2Spgoyette nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
476e81f0ea2Spgoyette u_int32_t minorvers, NFSPROC_T *p)
4776ca35587Sdholland {
4786ca35587Sdholland int error = 0, lktype;
4796ca35587Sdholland vnode_t vp;
4806ca35587Sdholland mount_t mp = NULL;
4816ca35587Sdholland struct nfsrvfh fh;
4826ca35587Sdholland struct nfsexstuff nes;
4836ca35587Sdholland
4846ca35587Sdholland /*
4856ca35587Sdholland * Get a locked vnode for the first file handle
4866ca35587Sdholland */
4876ca35587Sdholland if (!(nd->nd_flag & ND_NFSV4)) {
4886ca35587Sdholland KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc"));
4896ca35587Sdholland /*
4906ca35587Sdholland * For NFSv3, if the malloc/mget allocation is near limits,
4916ca35587Sdholland * return NFSERR_DELAY.
4926ca35587Sdholland */
4936ca35587Sdholland if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) {
4946ca35587Sdholland nd->nd_repstat = NFSERR_DELAY;
4956ca35587Sdholland vp = NULL;
4966ca35587Sdholland } else {
4976ca35587Sdholland error = nfsrv_mtofh(nd, &fh);
4986ca35587Sdholland if (error) {
4996ca35587Sdholland if (error != EBADRPC)
5006ca35587Sdholland printf("nfs dorpc err1=%d\n", error);
5016ca35587Sdholland nd->nd_repstat = NFSERR_GARBAGE;
5026ca35587Sdholland goto out;
5036ca35587Sdholland }
5046ca35587Sdholland if (nd->nd_procnum == NFSPROC_READ ||
5056ca35587Sdholland nd->nd_procnum == NFSPROC_WRITE ||
5066ca35587Sdholland nd->nd_procnum == NFSPROC_READDIR ||
507e81f0ea2Spgoyette nd->nd_procnum == NFSPROC_READDIRPLUS ||
5086ca35587Sdholland nd->nd_procnum == NFSPROC_READLINK ||
5096ca35587Sdholland nd->nd_procnum == NFSPROC_GETATTR ||
510e81f0ea2Spgoyette nd->nd_procnum == NFSPROC_ACCESS ||
511e81f0ea2Spgoyette nd->nd_procnum == NFSPROC_FSSTAT ||
512e81f0ea2Spgoyette nd->nd_procnum == NFSPROC_FSINFO)
5136ca35587Sdholland lktype = LK_SHARED;
5146ca35587Sdholland else
5156ca35587Sdholland lktype = LK_EXCLUSIVE;
5166ca35587Sdholland if (nd->nd_flag & ND_PUBLOOKUP)
5176ca35587Sdholland nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
5186ca35587Sdholland &mp, nfs_writerpc[nd->nd_procnum], p);
5196ca35587Sdholland else
5206ca35587Sdholland nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
5216ca35587Sdholland &mp, nfs_writerpc[nd->nd_procnum], p);
5226ca35587Sdholland if (nd->nd_repstat == NFSERR_PROGNOTV4)
5236ca35587Sdholland goto out;
5246ca35587Sdholland }
5256ca35587Sdholland }
5266ca35587Sdholland
5276ca35587Sdholland /*
5286ca35587Sdholland * For V2 and 3, set the ND_SAVEREPLY flag for the recent request
5296ca35587Sdholland * cache, as required.
5306ca35587Sdholland * For V4, nfsrvd_compound() does this.
5316ca35587Sdholland */
5326ca35587Sdholland if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum])
5336ca35587Sdholland nd->nd_flag |= ND_SAVEREPLY;
5346ca35587Sdholland
5356ca35587Sdholland nfsrvd_rephead(nd);
5366ca35587Sdholland /*
5376ca35587Sdholland * If nd_repstat is non-zero, just fill in the reply status
5386ca35587Sdholland * to complete the RPC reply for V2. Otherwise, you must do
5396ca35587Sdholland * the RPC.
5406ca35587Sdholland */
5416ca35587Sdholland if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
5426ca35587Sdholland *nd->nd_errp = nfsd_errmap(nd);
543e81f0ea2Spgoyette nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], /*now*/ NULL);
544e81f0ea2Spgoyette nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
545e81f0ea2Spgoyette /*now*/ NULL, /*then*/ NULL);
5466ca35587Sdholland if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
5476ca35587Sdholland vn_finished_write(mp);
5486ca35587Sdholland goto out;
5496ca35587Sdholland }
5506ca35587Sdholland
5516ca35587Sdholland /*
5526ca35587Sdholland * Now the procedure can be performed. For V4, nfsrvd_compound()
5536ca35587Sdholland * works through the sub-rpcs, otherwise just call the procedure.
5546ca35587Sdholland * The procedures are in three groups with different arguments.
5556ca35587Sdholland * The group is indicated by the value in nfs_retfh[].
5566ca35587Sdholland */
5576ca35587Sdholland if (nd->nd_flag & ND_NFSV4) {
558e81f0ea2Spgoyette nfsrvd_compound(nd, isdgram, tag, taglen, minorvers, p);
5596ca35587Sdholland } else {
560e81f0ea2Spgoyette struct bintime start_time;
561e81f0ea2Spgoyette
562e81f0ea2Spgoyette binuptime(&start_time);
563e81f0ea2Spgoyette nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], &start_time);
564e81f0ea2Spgoyette
5656ca35587Sdholland if (nfs_retfh[nd->nd_procnum] == 1) {
5666ca35587Sdholland if (vp)
5676ca35587Sdholland NFSVOPUNLOCK(vp, 0);
5686ca35587Sdholland error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram,
5696ca35587Sdholland vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes);
5706ca35587Sdholland } else if (nfs_retfh[nd->nd_procnum] == 2) {
5716ca35587Sdholland error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram,
5726ca35587Sdholland vp, NULL, p, &nes, NULL);
5736ca35587Sdholland } else {
5746ca35587Sdholland error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
5756ca35587Sdholland vp, p, &nes);
5766ca35587Sdholland }
5776ca35587Sdholland if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
5786ca35587Sdholland vn_finished_write(mp);
579e81f0ea2Spgoyette
580e81f0ea2Spgoyette nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
581e81f0ea2Spgoyette /*now*/ NULL, /*then*/ &start_time);
5826ca35587Sdholland }
5836ca35587Sdholland if (error) {
5846ca35587Sdholland if (error != EBADRPC)
5856ca35587Sdholland printf("nfs dorpc err2=%d\n", error);
5866ca35587Sdholland nd->nd_repstat = NFSERR_GARBAGE;
5876ca35587Sdholland }
5886ca35587Sdholland *nd->nd_errp = nfsd_errmap(nd);
5896ca35587Sdholland
5906ca35587Sdholland /*
5916ca35587Sdholland * Don't cache certain reply status values.
5926ca35587Sdholland */
5936ca35587Sdholland if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) &&
5946ca35587Sdholland (nd->nd_repstat == NFSERR_GARBAGE ||
5956ca35587Sdholland nd->nd_repstat == NFSERR_BADXDR ||
5966ca35587Sdholland nd->nd_repstat == NFSERR_MOVED ||
5976ca35587Sdholland nd->nd_repstat == NFSERR_DELAY ||
5986ca35587Sdholland nd->nd_repstat == NFSERR_BADSEQID ||
5996ca35587Sdholland nd->nd_repstat == NFSERR_RESOURCE ||
6006ca35587Sdholland nd->nd_repstat == NFSERR_SERVERFAULT ||
6016ca35587Sdholland nd->nd_repstat == NFSERR_STALECLIENTID ||
6026ca35587Sdholland nd->nd_repstat == NFSERR_STALESTATEID ||
6036ca35587Sdholland nd->nd_repstat == NFSERR_OLDSTATEID ||
6046ca35587Sdholland nd->nd_repstat == NFSERR_BADSTATEID ||
6056ca35587Sdholland nd->nd_repstat == NFSERR_GRACE ||
6066ca35587Sdholland nd->nd_repstat == NFSERR_NOGRACE))
6076ca35587Sdholland nd->nd_flag &= ~ND_SAVEREPLY;
6086ca35587Sdholland
6096ca35587Sdholland out:
6106ca35587Sdholland NFSEXITCODE2(0, nd);
6116ca35587Sdholland }
6126ca35587Sdholland
6136ca35587Sdholland /*
6146ca35587Sdholland * Breaks down a compound RPC request and calls the server routines for
6156ca35587Sdholland * the subprocedures.
6166ca35587Sdholland * Some suboperations are performed directly here to simplify file handle<-->
6176ca35587Sdholland * vnode pointer handling.
6186ca35587Sdholland */
6196ca35587Sdholland static void
nfsrvd_compound(struct nfsrv_descript * nd,int isdgram,u_char * tag,int taglen,u_int32_t minorvers,NFSPROC_T * p)620e81f0ea2Spgoyette nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
621e81f0ea2Spgoyette int taglen, u_int32_t minorvers, NFSPROC_T *p)
6226ca35587Sdholland {
623e81f0ea2Spgoyette int i, lktype, op, op0 = 0, statsinprog = 0;
6246ca35587Sdholland u_int32_t *tl;
6256ca35587Sdholland struct nfsclient *clp, *nclp;
626e81f0ea2Spgoyette int numops, error = 0, igotlock;
627e81f0ea2Spgoyette u_int32_t retops = 0, *retopsp = NULL, *repp;
6286ca35587Sdholland vnode_t vp, nvp, savevp;
6296ca35587Sdholland struct nfsrvfh fh;
6306ca35587Sdholland mount_t new_mp, temp_mp = NULL;
6316ca35587Sdholland struct ucred *credanon;
6326ca35587Sdholland struct nfsexstuff nes, vpnes, savevpnes;
6336ca35587Sdholland fsid_t cur_fsid, save_fsid;
6346ca35587Sdholland static u_int64_t compref = 0;
635e81f0ea2Spgoyette struct bintime start_time;
6366ca35587Sdholland
6376ca35587Sdholland NFSVNO_EXINIT(&vpnes);
6386ca35587Sdholland NFSVNO_EXINIT(&savevpnes);
6396ca35587Sdholland /*
6406ca35587Sdholland * Put the seq# of the current compound RPC in nfsrv_descript.
6416ca35587Sdholland * (This is used by nfsrv_checkgetattr(), to see if the write
6426ca35587Sdholland * delegation was created by the same compound RPC as the one
6436ca35587Sdholland * with that Getattr in it.)
6446ca35587Sdholland * Don't worry about the 64bit number wrapping around. It ain't
6456ca35587Sdholland * gonna happen before this server gets shut down/rebooted.
6466ca35587Sdholland */
6476ca35587Sdholland nd->nd_compref = compref++;
6486ca35587Sdholland
6496ca35587Sdholland /*
6506ca35587Sdholland * Check for and optionally get a lock on the root. This lock means that
6516ca35587Sdholland * no nfsd will be fiddling with the V4 file system and state stuff. It
6526ca35587Sdholland * is required when the V4 root is being changed, the stable storage
6536ca35587Sdholland * restart file is being updated, or callbacks are being done.
6546ca35587Sdholland * When any of the nfsd are processing an NFSv4 compound RPC, they must
6556ca35587Sdholland * either hold a reference count (nfs_usecnt) or the lock. When
6566ca35587Sdholland * nfsrv_unlock() is called to release the lock, it can optionally
6576ca35587Sdholland * also get a reference count, which saves the need for a call to
6586ca35587Sdholland * nfsrv_getref() after nfsrv_unlock().
6596ca35587Sdholland */
6606ca35587Sdholland /*
6616ca35587Sdholland * First, check to see if we need to wait for an update lock.
6626ca35587Sdholland */
6636ca35587Sdholland igotlock = 0;
6646ca35587Sdholland NFSLOCKV4ROOTMUTEX();
6656ca35587Sdholland if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
6666ca35587Sdholland igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
6676ca35587Sdholland NFSV4ROOTLOCKMUTEXPTR, NULL);
6686ca35587Sdholland else
6696ca35587Sdholland igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
6706ca35587Sdholland NFSV4ROOTLOCKMUTEXPTR, NULL);
6716ca35587Sdholland NFSUNLOCKV4ROOTMUTEX();
6726ca35587Sdholland if (igotlock) {
6736ca35587Sdholland /*
6746ca35587Sdholland * If I got the lock, I can update the stable storage file.
6756ca35587Sdholland * Done when the grace period is over or a client has long
6766ca35587Sdholland * since expired.
6776ca35587Sdholland */
6786ca35587Sdholland nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
6796ca35587Sdholland if ((nfsrv_stablefirst.nsf_flags &
6806ca35587Sdholland (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
6816ca35587Sdholland nfsrv_updatestable(p);
6826ca35587Sdholland
6836ca35587Sdholland /*
6846ca35587Sdholland * If at least one client has long since expired, search
6856ca35587Sdholland * the client list for them, write a REVOKE record on the
6866ca35587Sdholland * stable storage file and then remove them from the client
6876ca35587Sdholland * list.
6886ca35587Sdholland */
6896ca35587Sdholland if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
6906ca35587Sdholland nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
691e81f0ea2Spgoyette for (i = 0; i < nfsrv_clienthashsize; i++) {
6926ca35587Sdholland LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
6936ca35587Sdholland nclp) {
6946ca35587Sdholland if (clp->lc_flags & LCL_EXPIREIT) {
6956ca35587Sdholland if (!LIST_EMPTY(&clp->lc_open) ||
6966ca35587Sdholland !LIST_EMPTY(&clp->lc_deleg))
6976ca35587Sdholland nfsrv_writestable(clp->lc_id,
6986ca35587Sdholland clp->lc_idlen, NFSNST_REVOKE, p);
6996ca35587Sdholland nfsrv_cleanclient(clp, p);
7006ca35587Sdholland nfsrv_freedeleglist(&clp->lc_deleg);
7016ca35587Sdholland nfsrv_freedeleglist(&clp->lc_olddeleg);
7026ca35587Sdholland LIST_REMOVE(clp, lc_hash);
7036ca35587Sdholland nfsrv_zapclient(clp, p);
7046ca35587Sdholland }
7056ca35587Sdholland }
7066ca35587Sdholland }
7076ca35587Sdholland }
7086ca35587Sdholland NFSLOCKV4ROOTMUTEX();
7096ca35587Sdholland nfsv4_unlock(&nfsv4rootfs_lock, 1);
7106ca35587Sdholland NFSUNLOCKV4ROOTMUTEX();
7116ca35587Sdholland } else {
7126ca35587Sdholland /*
7136ca35587Sdholland * If we didn't get the lock, we need to get a refcnt,
7146ca35587Sdholland * which also checks for and waits for the lock.
7156ca35587Sdholland */
7166ca35587Sdholland NFSLOCKV4ROOTMUTEX();
7176ca35587Sdholland nfsv4_getref(&nfsv4rootfs_lock, NULL,
7186ca35587Sdholland NFSV4ROOTLOCKMUTEXPTR, NULL);
7196ca35587Sdholland NFSUNLOCKV4ROOTMUTEX();
7206ca35587Sdholland }
7216ca35587Sdholland
7226ca35587Sdholland /*
7236ca35587Sdholland * If flagged, search for open owners that haven't had any opens
7246ca35587Sdholland * for a long time.
7256ca35587Sdholland */
7266ca35587Sdholland if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
7276ca35587Sdholland nfsrv_throwawayopens(p);
7286ca35587Sdholland }
7296ca35587Sdholland
7306ca35587Sdholland savevp = vp = NULL;
7316ca35587Sdholland save_fsid.val[0] = save_fsid.val[1] = 0;
7326ca35587Sdholland cur_fsid.val[0] = cur_fsid.val[1] = 0;
733e81f0ea2Spgoyette
734e81f0ea2Spgoyette /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */
7356ca35587Sdholland if (taglen < 0) {
7366ca35587Sdholland error = EBADRPC;
7376ca35587Sdholland goto nfsmout;
7386ca35587Sdholland }
739e81f0ea2Spgoyette
7406ca35587Sdholland (void) nfsm_strtom(nd, tag, taglen);
7416ca35587Sdholland NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
742e81f0ea2Spgoyette NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
743e81f0ea2Spgoyette if (minorvers != NFSV4_MINORVERSION && minorvers != NFSV41_MINORVERSION)
7446ca35587Sdholland nd->nd_repstat = NFSERR_MINORVERMISMATCH;
7456ca35587Sdholland if (nd->nd_repstat)
7466ca35587Sdholland numops = 0;
7476ca35587Sdholland else
7486ca35587Sdholland numops = fxdr_unsigned(int, *tl);
7496ca35587Sdholland /*
7506ca35587Sdholland * Loop around doing the sub ops.
7516ca35587Sdholland * vp - is an unlocked vnode pointer for the CFH
7526ca35587Sdholland * savevp - is an unlocked vnode pointer for the SAVEDFH
7536ca35587Sdholland * (at some future date, it might turn out to be more appropriate
7546ca35587Sdholland * to keep the file handles instead of vnode pointers?)
7556ca35587Sdholland * savevpnes and vpnes - are the export flags for the above.
7566ca35587Sdholland */
7576ca35587Sdholland for (i = 0; i < numops; i++) {
7586ca35587Sdholland NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
7596ca35587Sdholland NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
7606ca35587Sdholland *repp = *tl;
7616ca35587Sdholland op = fxdr_unsigned(int, *tl);
762e81f0ea2Spgoyette NFSD_DEBUG(4, "op=%d\n", op);
763e81f0ea2Spgoyette
764e81f0ea2Spgoyette binuptime(&start_time);
765e81f0ea2Spgoyette nfsrvd_statstart(op, &start_time);
766e81f0ea2Spgoyette statsinprog = 1;
767e81f0ea2Spgoyette
768e81f0ea2Spgoyette if (op < NFSV4OP_ACCESS ||
769e81f0ea2Spgoyette (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) ||
770e81f0ea2Spgoyette (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV41) != 0)) {
7716ca35587Sdholland nd->nd_repstat = NFSERR_OPILLEGAL;
7726ca35587Sdholland *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
7736ca35587Sdholland *repp = nfsd_errmap(nd);
7746ca35587Sdholland retops++;
7756ca35587Sdholland break;
7766ca35587Sdholland } else {
7776ca35587Sdholland repp++;
7786ca35587Sdholland }
779e81f0ea2Spgoyette if (i == 0)
780e81f0ea2Spgoyette op0 = op;
781e81f0ea2Spgoyette if (i == numops - 1)
782e81f0ea2Spgoyette nd->nd_flag |= ND_LASTOP;
7836ca35587Sdholland
7846ca35587Sdholland /*
7856ca35587Sdholland * Check for a referral on the current FH and, if so, return
7866ca35587Sdholland * NFSERR_MOVED for all ops that allow it, except Getattr.
7876ca35587Sdholland */
7886ca35587Sdholland if (vp != NULL && op != NFSV4OP_GETATTR &&
7896ca35587Sdholland nfsv4root_getreferral(vp, NULL, 0) != NULL &&
7906ca35587Sdholland nfsrv_errmoved(op)) {
7916ca35587Sdholland nd->nd_repstat = NFSERR_MOVED;
7926ca35587Sdholland *repp = nfsd_errmap(nd);
7936ca35587Sdholland retops++;
7946ca35587Sdholland break;
7956ca35587Sdholland }
7966ca35587Sdholland
797e81f0ea2Spgoyette /*
798e81f0ea2Spgoyette * For NFSv4.1, check for a Sequence Operation being first
799e81f0ea2Spgoyette * or one of the other allowed operations by itself.
800e81f0ea2Spgoyette */
801e81f0ea2Spgoyette if ((nd->nd_flag & ND_NFSV41) != 0) {
802e81f0ea2Spgoyette if (i != 0 && op == NFSV4OP_SEQUENCE)
803e81f0ea2Spgoyette nd->nd_repstat = NFSERR_SEQUENCEPOS;
804e81f0ea2Spgoyette else if (i == 0 && op != NFSV4OP_SEQUENCE &&
805e81f0ea2Spgoyette op != NFSV4OP_EXCHANGEID &&
806e81f0ea2Spgoyette op != NFSV4OP_CREATESESSION &&
807e81f0ea2Spgoyette op != NFSV4OP_BINDCONNTOSESS &&
808e81f0ea2Spgoyette op != NFSV4OP_DESTROYCLIENTID &&
809e81f0ea2Spgoyette op != NFSV4OP_DESTROYSESSION)
810e81f0ea2Spgoyette nd->nd_repstat = NFSERR_OPNOTINSESS;
811e81f0ea2Spgoyette else if (i != 0 && op0 != NFSV4OP_SEQUENCE)
812e81f0ea2Spgoyette nd->nd_repstat = NFSERR_NOTONLYOP;
813e81f0ea2Spgoyette if (nd->nd_repstat != 0) {
814e81f0ea2Spgoyette *repp = nfsd_errmap(nd);
815e81f0ea2Spgoyette retops++;
816e81f0ea2Spgoyette break;
817e81f0ea2Spgoyette }
818e81f0ea2Spgoyette }
819e81f0ea2Spgoyette
8206ca35587Sdholland nd->nd_procnum = op;
8216ca35587Sdholland /*
8226ca35587Sdholland * If over flood level, reply NFSERR_RESOURCE, if at the first
8236ca35587Sdholland * Op. (Since a client recovery from NFSERR_RESOURCE can get
8246ca35587Sdholland * really nasty for certain Op sequences, I'll play it safe
8256ca35587Sdholland * and only return the error at the beginning.) The cache
8266ca35587Sdholland * will still function over flood level, but uses lots of
8276ca35587Sdholland * mbufs.)
8286ca35587Sdholland * If nfsrv_mallocmget_limit() returns True, the system is near
8296ca35587Sdholland * to its limit for memory that malloc()/mget() can allocate.
8306ca35587Sdholland */
831e81f0ea2Spgoyette if (i == 0 && (nd->nd_rp == NULL ||
832e81f0ea2Spgoyette nd->nd_rp->rc_refcnt == 0) &&
8336ca35587Sdholland (nfsrv_mallocmget_limit() ||
8346ca35587Sdholland nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
835e81f0ea2Spgoyette if (nfsrc_tcpsavedreplies > nfsrc_floodlevel)
836e81f0ea2Spgoyette printf("nfsd server cache flooded, try "
837e81f0ea2Spgoyette "increasing vfs.nfsd.tcphighwater\n");
8386ca35587Sdholland nd->nd_repstat = NFSERR_RESOURCE;
8396ca35587Sdholland *repp = nfsd_errmap(nd);
8406ca35587Sdholland if (op == NFSV4OP_SETATTR) {
8416ca35587Sdholland /*
8426ca35587Sdholland * Setattr replies require a bitmap.
8436ca35587Sdholland * even for errors like these.
8446ca35587Sdholland */
8456ca35587Sdholland NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
8466ca35587Sdholland *tl = 0;
8476ca35587Sdholland }
8486ca35587Sdholland retops++;
8496ca35587Sdholland break;
8506ca35587Sdholland }
8516ca35587Sdholland if (nfsv4_opflag[op].savereply)
8526ca35587Sdholland nd->nd_flag |= ND_SAVEREPLY;
8536ca35587Sdholland switch (op) {
8546ca35587Sdholland case NFSV4OP_PUTFH:
8556ca35587Sdholland error = nfsrv_mtofh(nd, &fh);
8566ca35587Sdholland if (error)
8576ca35587Sdholland goto nfsmout;
8586ca35587Sdholland if (!nd->nd_repstat)
8596ca35587Sdholland nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
8606ca35587Sdholland NULL, 0, p);
8616ca35587Sdholland /* For now, allow this for non-export FHs */
8626ca35587Sdholland if (!nd->nd_repstat) {
8636ca35587Sdholland if (vp)
8646ca35587Sdholland vrele(vp);
8656ca35587Sdholland vp = nvp;
8666ca35587Sdholland cur_fsid = vp->v_mount->mnt_stat.f_fsid;
8676ca35587Sdholland NFSVOPUNLOCK(vp, 0);
8686ca35587Sdholland vpnes = nes;
8696ca35587Sdholland }
8706ca35587Sdholland break;
8716ca35587Sdholland case NFSV4OP_PUTPUBFH:
8726ca35587Sdholland if (nfs_pubfhset)
8736ca35587Sdholland nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
8746ca35587Sdholland &nes, NULL, 0, p);
8756ca35587Sdholland else
8766ca35587Sdholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
8776ca35587Sdholland if (!nd->nd_repstat) {
8786ca35587Sdholland if (vp)
8796ca35587Sdholland vrele(vp);
8806ca35587Sdholland vp = nvp;
8816ca35587Sdholland cur_fsid = vp->v_mount->mnt_stat.f_fsid;
8826ca35587Sdholland NFSVOPUNLOCK(vp, 0);
8836ca35587Sdholland vpnes = nes;
8846ca35587Sdholland }
8856ca35587Sdholland break;
8866ca35587Sdholland case NFSV4OP_PUTROOTFH:
8876ca35587Sdholland if (nfs_rootfhset) {
8886ca35587Sdholland nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
8896ca35587Sdholland &nes, NULL, 0, p);
8906ca35587Sdholland if (!nd->nd_repstat) {
8916ca35587Sdholland if (vp)
8926ca35587Sdholland vrele(vp);
8936ca35587Sdholland vp = nvp;
8946ca35587Sdholland cur_fsid = vp->v_mount->mnt_stat.f_fsid;
8956ca35587Sdholland NFSVOPUNLOCK(vp, 0);
8966ca35587Sdholland vpnes = nes;
8976ca35587Sdholland }
8986ca35587Sdholland } else
8996ca35587Sdholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
9006ca35587Sdholland break;
9016ca35587Sdholland case NFSV4OP_SAVEFH:
9026ca35587Sdholland if (vp && NFSVNO_EXPORTED(&vpnes)) {
9036ca35587Sdholland nd->nd_repstat = 0;
9046ca35587Sdholland /* If vp == savevp, a no-op */
9056ca35587Sdholland if (vp != savevp) {
9066ca35587Sdholland if (savevp)
9076ca35587Sdholland vrele(savevp);
9086ca35587Sdholland VREF(vp);
9096ca35587Sdholland savevp = vp;
9106ca35587Sdholland savevpnes = vpnes;
9116ca35587Sdholland save_fsid = cur_fsid;
9126ca35587Sdholland }
9136ca35587Sdholland } else {
9146ca35587Sdholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
9156ca35587Sdholland }
9166ca35587Sdholland break;
9176ca35587Sdholland case NFSV4OP_RESTOREFH:
9186ca35587Sdholland if (savevp) {
9196ca35587Sdholland nd->nd_repstat = 0;
9206ca35587Sdholland /* If vp == savevp, a no-op */
9216ca35587Sdholland if (vp != savevp) {
9226ca35587Sdholland VREF(savevp);
9236ca35587Sdholland vrele(vp);
9246ca35587Sdholland vp = savevp;
9256ca35587Sdholland vpnes = savevpnes;
9266ca35587Sdholland cur_fsid = save_fsid;
9276ca35587Sdholland }
9286ca35587Sdholland } else {
9296ca35587Sdholland nd->nd_repstat = NFSERR_RESTOREFH;
9306ca35587Sdholland }
9316ca35587Sdholland break;
9326ca35587Sdholland default:
9336ca35587Sdholland /*
9346ca35587Sdholland * Allow a Lookup, Getattr, GetFH, Secinfo on an
9356ca35587Sdholland * non-exported directory if
9366ca35587Sdholland * nfs_rootfhset. Do I need to allow any other Ops?
9376ca35587Sdholland * (You can only have a non-exported vpnes if
9386ca35587Sdholland * nfs_rootfhset is true. See nfsd_fhtovp())
9396ca35587Sdholland * Allow AUTH_SYS to be used for file systems
9406ca35587Sdholland * exported GSS only for certain Ops, to allow
9416ca35587Sdholland * clients to do mounts more easily.
9426ca35587Sdholland */
9436ca35587Sdholland if (nfsv4_opflag[op].needscfh && vp) {
9446ca35587Sdholland if (!NFSVNO_EXPORTED(&vpnes) &&
9456ca35587Sdholland op != NFSV4OP_LOOKUP &&
9466ca35587Sdholland op != NFSV4OP_GETATTR &&
9476ca35587Sdholland op != NFSV4OP_GETFH &&
9486ca35587Sdholland op != NFSV4OP_ACCESS &&
9496ca35587Sdholland op != NFSV4OP_READLINK &&
9506ca35587Sdholland op != NFSV4OP_SECINFO)
9516ca35587Sdholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
9526ca35587Sdholland else if (nfsvno_testexp(nd, &vpnes) &&
9536ca35587Sdholland op != NFSV4OP_LOOKUP &&
9546ca35587Sdholland op != NFSV4OP_GETFH &&
9556ca35587Sdholland op != NFSV4OP_GETATTR &&
9566ca35587Sdholland op != NFSV4OP_SECINFO)
9576ca35587Sdholland nd->nd_repstat = NFSERR_WRONGSEC;
9586ca35587Sdholland if (nd->nd_repstat) {
9596ca35587Sdholland if (op == NFSV4OP_SETATTR) {
9606ca35587Sdholland /*
9616ca35587Sdholland * Setattr reply requires a bitmap
9626ca35587Sdholland * even for errors like these.
9636ca35587Sdholland */
9646ca35587Sdholland NFSM_BUILD(tl, u_int32_t *,
9656ca35587Sdholland NFSX_UNSIGNED);
9666ca35587Sdholland *tl = 0;
9676ca35587Sdholland }
9686ca35587Sdholland break;
9696ca35587Sdholland }
9706ca35587Sdholland }
9716ca35587Sdholland if (nfsv4_opflag[op].retfh == 1) {
9726ca35587Sdholland if (!vp) {
9736ca35587Sdholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
9746ca35587Sdholland break;
9756ca35587Sdholland }
9766ca35587Sdholland VREF(vp);
9776ca35587Sdholland if (nfsv4_opflag[op].modifyfs)
9786ca35587Sdholland vn_start_write(vp, &temp_mp, V_WAIT);
9796ca35587Sdholland error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
9806ca35587Sdholland &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
9816ca35587Sdholland if (!error && !nd->nd_repstat) {
9826ca35587Sdholland if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
9836ca35587Sdholland new_mp = nvp->v_mount;
9846ca35587Sdholland if (cur_fsid.val[0] !=
9856ca35587Sdholland new_mp->mnt_stat.f_fsid.val[0] ||
9866ca35587Sdholland cur_fsid.val[1] !=
9876ca35587Sdholland new_mp->mnt_stat.f_fsid.val[1]) {
9886ca35587Sdholland /* crossed a server mount point */
9896ca35587Sdholland nd->nd_repstat = nfsvno_checkexp(new_mp,
9906ca35587Sdholland nd->nd_nam, &nes, &credanon);
9916ca35587Sdholland if (!nd->nd_repstat)
9926ca35587Sdholland nd->nd_repstat = nfsd_excred(nd,
9936ca35587Sdholland &nes, credanon);
9946ca35587Sdholland if (credanon != NULL)
9956ca35587Sdholland crfree(credanon);
9966ca35587Sdholland if (!nd->nd_repstat) {
9976ca35587Sdholland vpnes = nes;
9986ca35587Sdholland cur_fsid = new_mp->mnt_stat.f_fsid;
9996ca35587Sdholland }
10006ca35587Sdholland }
10016ca35587Sdholland /* Lookup ops return a locked vnode */
10026ca35587Sdholland NFSVOPUNLOCK(nvp, 0);
10036ca35587Sdholland }
10046ca35587Sdholland if (!nd->nd_repstat) {
10056ca35587Sdholland vrele(vp);
10066ca35587Sdholland vp = nvp;
10076ca35587Sdholland } else
10086ca35587Sdholland vrele(nvp);
10096ca35587Sdholland }
10106ca35587Sdholland if (nfsv4_opflag[op].modifyfs)
10116ca35587Sdholland vn_finished_write(temp_mp);
10126ca35587Sdholland } else if (nfsv4_opflag[op].retfh == 2) {
10136ca35587Sdholland if (vp == NULL || savevp == NULL) {
10146ca35587Sdholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
10156ca35587Sdholland break;
10166ca35587Sdholland } else if (cur_fsid.val[0] != save_fsid.val[0] ||
10176ca35587Sdholland cur_fsid.val[1] != save_fsid.val[1]) {
10186ca35587Sdholland nd->nd_repstat = NFSERR_XDEV;
10196ca35587Sdholland break;
10206ca35587Sdholland }
10216ca35587Sdholland if (nfsv4_opflag[op].modifyfs)
10226ca35587Sdholland vn_start_write(savevp, &temp_mp, V_WAIT);
10236ca35587Sdholland if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
10246ca35587Sdholland VREF(vp);
10256ca35587Sdholland VREF(savevp);
10266ca35587Sdholland error = (*(nfsrv4_ops2[op]))(nd, isdgram,
10276ca35587Sdholland savevp, vp, p, &savevpnes, &vpnes);
10286ca35587Sdholland } else
10296ca35587Sdholland nd->nd_repstat = NFSERR_PERM;
10306ca35587Sdholland if (nfsv4_opflag[op].modifyfs)
10316ca35587Sdholland vn_finished_write(temp_mp);
10326ca35587Sdholland } else {
10336ca35587Sdholland if (nfsv4_opflag[op].retfh != 0)
10346ca35587Sdholland panic("nfsrvd_compound");
10356ca35587Sdholland if (nfsv4_opflag[op].needscfh) {
10366ca35587Sdholland if (vp != NULL) {
1037e81f0ea2Spgoyette lktype = nfsv4_opflag[op].lktype;
1038e81f0ea2Spgoyette if (nfsv4_opflag[op].modifyfs) {
10396ca35587Sdholland vn_start_write(vp, &temp_mp,
10406ca35587Sdholland V_WAIT);
1041e81f0ea2Spgoyette if (op == NFSV4OP_WRITE &&
1042e81f0ea2Spgoyette MNT_SHARED_WRITES(temp_mp))
1043e81f0ea2Spgoyette lktype = LK_SHARED;
1044e81f0ea2Spgoyette }
1045e81f0ea2Spgoyette if (NFSVOPLOCK(vp, lktype) == 0)
10466ca35587Sdholland VREF(vp);
10476ca35587Sdholland else
10486ca35587Sdholland nd->nd_repstat = NFSERR_PERM;
10496ca35587Sdholland } else {
10506ca35587Sdholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
10516ca35587Sdholland if (op == NFSV4OP_SETATTR) {
10526ca35587Sdholland /*
10536ca35587Sdholland * Setattr reply requires a
10546ca35587Sdholland * bitmap even for errors like
10556ca35587Sdholland * these.
10566ca35587Sdholland */
10576ca35587Sdholland NFSM_BUILD(tl, u_int32_t *,
10586ca35587Sdholland NFSX_UNSIGNED);
10596ca35587Sdholland *tl = 0;
10606ca35587Sdholland }
10616ca35587Sdholland break;
10626ca35587Sdholland }
10636ca35587Sdholland if (nd->nd_repstat == 0)
10646ca35587Sdholland error = (*(nfsrv4_ops0[op]))(nd,
10656ca35587Sdholland isdgram, vp, p, &vpnes);
10666ca35587Sdholland if (nfsv4_opflag[op].modifyfs)
10676ca35587Sdholland vn_finished_write(temp_mp);
10686ca35587Sdholland } else {
10696ca35587Sdholland error = (*(nfsrv4_ops0[op]))(nd, isdgram,
10706ca35587Sdholland NULL, p, &vpnes);
10716ca35587Sdholland }
10726ca35587Sdholland }
1073e81f0ea2Spgoyette }
10746ca35587Sdholland if (error) {
10756ca35587Sdholland if (error == EBADRPC || error == NFSERR_BADXDR) {
10766ca35587Sdholland nd->nd_repstat = NFSERR_BADXDR;
10776ca35587Sdholland } else {
10786ca35587Sdholland nd->nd_repstat = error;
10796ca35587Sdholland printf("nfsv4 comperr0=%d\n", error);
10806ca35587Sdholland }
10816ca35587Sdholland error = 0;
10826ca35587Sdholland }
1083e81f0ea2Spgoyette
1084e81f0ea2Spgoyette if (statsinprog != 0) {
1085e81f0ea2Spgoyette nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
1086e81f0ea2Spgoyette /*then*/ &start_time);
1087e81f0ea2Spgoyette statsinprog = 0;
1088e81f0ea2Spgoyette }
1089e81f0ea2Spgoyette
10906ca35587Sdholland retops++;
10916ca35587Sdholland if (nd->nd_repstat) {
10926ca35587Sdholland *repp = nfsd_errmap(nd);
10936ca35587Sdholland break;
10946ca35587Sdholland } else {
10956ca35587Sdholland *repp = 0; /* NFS4_OK */
10966ca35587Sdholland }
10976ca35587Sdholland }
10986ca35587Sdholland nfsmout:
1099e81f0ea2Spgoyette if (statsinprog != 0) {
1100e81f0ea2Spgoyette nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
1101e81f0ea2Spgoyette /*then*/ &start_time);
1102e81f0ea2Spgoyette statsinprog = 0;
1103e81f0ea2Spgoyette }
11046ca35587Sdholland if (error) {
11056ca35587Sdholland if (error == EBADRPC || error == NFSERR_BADXDR)
11066ca35587Sdholland nd->nd_repstat = NFSERR_BADXDR;
11076ca35587Sdholland else
11086ca35587Sdholland printf("nfsv4 comperr1=%d\n", error);
11096ca35587Sdholland }
11106ca35587Sdholland if (taglen == -1) {
11116ca35587Sdholland NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
11126ca35587Sdholland *tl++ = 0;
11136ca35587Sdholland *tl = 0;
11146ca35587Sdholland } else {
11156ca35587Sdholland *retopsp = txdr_unsigned(retops);
11166ca35587Sdholland }
11176ca35587Sdholland if (vp)
11186ca35587Sdholland vrele(vp);
11196ca35587Sdholland if (savevp)
11206ca35587Sdholland vrele(savevp);
11216ca35587Sdholland NFSLOCKV4ROOTMUTEX();
11226ca35587Sdholland nfsv4_relref(&nfsv4rootfs_lock);
11236ca35587Sdholland NFSUNLOCKV4ROOTMUTEX();
11246ca35587Sdholland
11256ca35587Sdholland NFSEXITCODE2(0, nd);
11266ca35587Sdholland }
1127