code:
/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/fs/nfs/nfs_var.h 224078 2011-07-16 08:05:17Z zack $
 */

/*
 * XXX needs <nfs/rpcv2.h> and <nfs/nfs.h> because of typedefs
 */

struct uio;
struct ucred;
struct nfscred;
NFSPROC_T;
struct buf;
struct sockaddr_in;
struct nfs_dlmount;
struct file;
struct nfsmount;
struct socket;
struct nfsreq;
struct nfssockreq;
struct vattr;
struct nameidata;
struct nfsnode;
struct nfsfh;
struct sillyrename;
struct componentname;
struct nfsd_srvargs;
struct nfsrv_descript;
struct nfs_fattr;
union nethostaddr;
struct nfsstate;
struct nfslock;
struct nfsclient;
struct nfslockconflict;
struct nfsd_idargs;
struct nfsd_clid;
struct nfsusrgrp;
struct nfsclowner;
struct nfsclopen;
struct nfsclopenhead;
struct nfsclclient;
struct nfscllockowner;
struct nfscllock;
struct nfscldeleg;
struct nfsv4lock;
struct nfsvattr;
struct nfs_vattr;
struct NFSSVCARGS;
#ifdef __FreeBSD__
NFS_ACCESS_ARGS;
NFS_OPEN_ARGS;
NFS_GETATTR_ARGS;
NFS_LOOKUP_ARGS;
NFS_READDIR_ARGS;
#endif

/* nfs_nfsdstate.c */
int nfsrv_setclient(struct nfsrv_descript *, struct nfsclient **,
    nfsquad_t *, nfsquad_t *, NFSPROC_T *);
int nfsrv_getclient(nfsquad_t, int, struct nfsclient **, nfsquad_t,
    struct nfsrv_descript *, NFSPROC_T *);
int nfsrv_adminrevoke(struct nfsd_clid *, NFSPROC_T *);
void nfsrv_dumpclients(struct nfsd_dumpclients *, int);
void nfsrv_dumplocks(vnode_t, struct nfsd_dumplocks *, int, NFSPROC_T *);
int nfsrv_lockctrl(vnode_t, struct nfsstate **,
    struct nfslock **, struct nfslockconflict *, nfsquad_t, nfsv4stateid_t *,
    struct nfsexstuff *, struct nfsrv_descript *, NFSPROC_T *);
int nfsrv_openctrl(struct nfsrv_descript *, vnode_t,
    struct nfsstate **, nfsquad_t, nfsv4stateid_t *, nfsv4stateid_t *,
    u_int32_t *, struct nfsexstuff *, NFSPROC_T *, u_quad_t);
int nfsrv_opencheck(nfsquad_t, nfsv4stateid_t *, struct nfsstate *,
    vnode_t, struct nfsrv_descript *, NFSPROC_T *, int);
int nfsrv_openupdate(vnode_t, struct nfsstate *, nfsquad_t,
    nfsv4stateid_t *, struct nfsrv_descript *, NFSPROC_T *);
int nfsrv_delegupdate(nfsquad_t, nfsv4stateid_t *, vnode_t, int,
    struct ucred *, NFSPROC_T *);
int nfsrv_releaselckown(struct nfsstate *, nfsquad_t, NFSPROC_T *);
void nfsrv_zapclient(struct nfsclient *, NFSPROC_T *);
int nfssvc_idname(struct nfsd_idargs *);
void nfsrv_servertimer(void);
int nfsrv_getclientipaddr(struct nfsrv_descript *, struct nfsclient *);
void nfsrv_setupstable(NFSPROC_T *);
void nfsrv_updatestable(NFSPROC_T *);
void nfsrv_writestable(u_char *, int, int, NFSPROC_T *);
void nfsrv_throwawayopens(NFSPROC_T *);
int nfsrv_checkremove(vnode_t, int, NFSPROC_T *);
void nfsd_recalldelegation(vnode_t, NFSPROC_T *);
void nfsd_disabledelegation(vnode_t, NFSPROC_T *);
int nfsrv_checksetattr(vnode_t, struct nfsrv_descript *,
    nfsv4stateid_t *, struct nfsvattr *, nfsattrbit_t *, struct nfsexstuff *,
    NFSPROC_T *);
int nfsrv_checkgetattr(struct nfsrv_descript *, vnode_t,
    struct nfsvattr *, nfsattrbit_t *, struct ucred *, NFSPROC_T *);
int nfsrv_nfsuserdport(u_short, NFSPROC_T *);
void nfsrv_nfsuserddelport(void);
void nfsrv_throwawayallstate(NFSPROC_T *);

/* nfs_nfsdserv.c */
int nfsrvd_access(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_getattr(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_setattr(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_lookup(struct nfsrv_descript *, int,
    vnode_t, vnode_t *, fhandle_t *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsrvd_readlink(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_read(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_write(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_create(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_mknod(struct nfsrv_descript *, int,
    vnode_t, vnode_t *, fhandle_t *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsrvd_remove(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_rename(struct nfsrv_descript *, int,
    vnode_t, vnode_t, NFSPROC_T *, struct nfsexstuff *,
    struct nfsexstuff *);
int nfsrvd_link(struct nfsrv_descript *, int,
    vnode_t, vnode_t, NFSPROC_T *, struct nfsexstuff *,
    struct nfsexstuff *);
int nfsrvd_symlink(struct nfsrv_descript *, int,
    vnode_t, vnode_t *, fhandle_t *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsrvd_mkdir(struct nfsrv_descript *, int,
    vnode_t, vnode_t *, fhandle_t *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsrvd_readdir(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_readdirplus(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_commit(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_statfs(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_fsinfo(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_close(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_delegpurge(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_delegreturn(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_getfh(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_lock(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_lockt(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_locku(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_openconfirm(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_opendowngrade(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_renew(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_secinfo(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_setclientid(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_setclientidcfrm(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_verify(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_open(struct nfsrv_descript *, int,
    vnode_t, vnode_t *, fhandle_t *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsrvd_openattr(struct nfsrv_descript *, int,
    vnode_t, vnode_t *, fhandle_t *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsrvd_releaselckown(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_pathconf(struct nfsrv_descript *, int,
    vnode_t, NFSPROC_T *, struct nfsexstuff *);

/* nfs_nfsdsocket.c */
void nfsrvd_rephead(struct nfsrv_descript *);
void nfsrvd_dorpc(struct nfsrv_descript *, int, NFSPROC_T *);

/* nfs_nfsdcache.c */
void nfsrvd_initcache(void);
int nfsrvd_getcache(struct nfsrv_descript *, struct socket *);
struct nfsrvcache *nfsrvd_updatecache(struct nfsrv_descript *,
    struct socket *);
void nfsrvd_sentcache(struct nfsrvcache *, struct socket *, int);
void nfsrvd_cleancache(void);
void nfsrvd_refcache(struct nfsrvcache *);
void nfsrvd_derefcache(struct nfsrvcache *);
void nfsrvd_delcache(struct nfsrvcache *);

/* nfs_commonsubs.c */
void newnfs_init(void);
int nfsaddr_match(int, union nethostaddr *, NFSSOCKADDR_T);
int nfsaddr2_match(NFSSOCKADDR_T, NFSSOCKADDR_T);
int nfsm_strtom(struct nfsrv_descript *, const char *, int);
int nfsm_mbufuio(struct nfsrv_descript *, struct uio *, int);
int nfsm_fhtom(struct nfsrv_descript *, u_int8_t *, int, int);
int nfsm_advance(struct nfsrv_descript *, int, int);
void *nfsm_dissct(struct nfsrv_descript *, int);
void newnfs_trimleading(struct nfsrv_descript *);
void newnfs_trimtrailing(struct nfsrv_descript *, mbuf_t,
    caddr_t);
void newnfs_copycred(struct nfscred *, struct ucred *);
void newnfs_copyincred(struct ucred *, struct nfscred *);
int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, int *,
    int *, NFSPROC_T *);
int nfsrv_getattrbits(struct nfsrv_descript *, nfsattrbit_t *, int *,
    int *);
int nfsv4_loadattr(struct nfsrv_descript *, vnode_t,
    struct nfsvattr *, struct nfsfh **, fhandle_t *, int,
    struct nfsv3_pathconf *, struct statfs *, struct nfsstatfs *,
    struct nfsfsinfo *, NFSACL_T *,
    int, int *, u_int32_t *, u_int32_t *, NFSPROC_T *, struct ucred *);
int nfsv4_lock(struct nfsv4lock *, int, int *, void *, struct mount *);
void nfsv4_unlock(struct nfsv4lock *, int);
void nfsv4_relref(struct nfsv4lock *);
void nfsv4_getref(struct nfsv4lock *, int *, void *, struct mount *);
int nfsv4_getref_nonblock(struct nfsv4lock *);
int nfsv4_testlock(struct nfsv4lock *);
int nfsrv_mtostr(struct nfsrv_descript *, char *, int);
int nfsrv_checkutf8(u_int8_t *, int);
int newnfs_sndlock(int *);
void newnfs_sndunlock(int *);

/* nfs_clcomsubs.c */
void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int);
void nfscl_reqstart(struct nfsrv_descript *, int, struct nfsmount *,
    u_int8_t *, int, u_int32_t **);
nfsuint64 *nfscl_getcookie(struct nfsnode *, off_t off, int);
void nfscl_fillsattr(struct nfsrv_descript *, struct vattr *,
      vnode_t, int, u_int32_t);
u_int8_t *nfscl_getmyip(struct nfsmount *, int *);
int nfsm_getfh(struct nfsrv_descript *, struct nfsfh **);
int nfscl_mtofh(struct nfsrv_descript *, struct nfsfh **,
        struct nfsvattr *, int *);
int nfscl_postop_attr(struct nfsrv_descript *, struct nfsvattr *, int *,
    void *);
int nfscl_wcc_data(struct nfsrv_descript *, vnode_t,
    struct nfsvattr *, int *, int *, void *);
int nfsm_loadattr(struct nfsrv_descript *, struct nfsvattr *);
int nfscl_request(struct nfsrv_descript *, vnode_t,
         NFSPROC_T *, struct ucred *, void *);
void nfsm_stateidtom(struct nfsrv_descript *, nfsv4stateid_t *, int);

/* nfs_nfsdsubs.c */
void nfsd_fhtovp(struct nfsrv_descript *, struct nfsrvfh *, int,
    vnode_t *, struct nfsexstuff *,
    mount_t *, int, NFSPROC_T *);
int nfsd_excred(struct nfsrv_descript *, struct nfsexstuff *, struct ucred *);
int nfsrv_mtofh(struct nfsrv_descript *, struct nfsrvfh *);
int nfsrv_putattrbit(struct nfsrv_descript *, nfsattrbit_t *);
void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int,
    struct nfsvattr *);
int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *,
    struct vattr *, fhandle_t *, int, nfsattrbit_t *,
    struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t);
void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *);
void nfsrv_adj(mbuf_t, int, int);
void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *);
int nfsd_errmap(struct nfsrv_descript *);
void nfsv4_uidtostr(uid_t, u_char **, int *, NFSPROC_T *);
int nfsv4_strtouid(u_char *, int, uid_t *, NFSPROC_T *);
void nfsv4_gidtostr(gid_t, u_char **, int *, NFSPROC_T *);
int nfsv4_strtogid(u_char *, int, gid_t *, NFSPROC_T *);
int nfsrv_checkuidgid(struct nfsrv_descript *, struct nfsvattr *);
void nfsrv_fixattr(struct nfsrv_descript *, vnode_t,
    struct nfsvattr *, NFSACL_T *, NFSPROC_T *, nfsattrbit_t *,
    struct nfsexstuff *);
int nfsrv_errmoved(int);
int nfsrv_putreferralattr(struct nfsrv_descript *, nfsattrbit_t *,
    struct nfsreferral *, int, int *);
int nfsrv_parsename(struct nfsrv_descript *, char *, u_long *,
    NFSPATHLEN_T *);
void nfsd_init(void);
int nfsd_checkrootexp(struct nfsrv_descript *);

/* nfs_clvfsops.c */

/* nfs_commonport.c */
int nfsrv_checksockseqnum(struct socket *, tcp_seq);
int nfsrv_getsockseqnum(struct socket *, tcp_seq *);
int nfsrv_getsocksndseq(struct socket *, tcp_seq *, tcp_seq *);
int nfsrv_lookupfilename(struct nameidata *, char *, NFSPROC_T *);
void nfsrv_object_create(vnode_t, NFSPROC_T *);
int nfsrv_mallocmget_limit(void);
int nfsvno_v4rootexport(struct nfsrv_descript *);
void newnfs_portinit(void);
struct ucred *newnfs_getcred(void);
void newnfs_setroot(struct ucred *);
int nfs_catnap(int, int, const char *);
struct nfsreferral *nfsv4root_getreferral(vnode_t, vnode_t, u_int32_t);
int nfsvno_pathconf(vnode_t, int, register_t *, struct ucred *,
    NFSPROC_T *);
int nfsrv_atroot(vnode_t, long *);
void newnfs_timer(void *);
int nfs_supportsnfsv4acls(vnode_t);

/* nfs_commonacl.c */
int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *,
    int *, int *, NFSPROC_T *);
int nfsrv_buildacl(struct nfsrv_descript *, NFSACL_T *, enum vtype,
    NFSPROC_T *);
int nfsrv_setacl(vnode_t, NFSACL_T *, struct ucred *,
    NFSPROC_T *);
int nfsrv_compareacl(NFSACL_T *, NFSACL_T *);

/* nfs_clrpcops.c */
int nfsrpc_null(vnode_t, struct ucred *, NFSPROC_T *);
int nfsrpc_access(vnode_t, int, struct ucred *, NFSPROC_T *,
    struct nfsvattr *, int *);
int nfsrpc_accessrpc(vnode_t, u_int32_t, struct ucred *,
    NFSPROC_T *, struct nfsvattr *, int *, u_int32_t *, void *);
int nfsrpc_open(vnode_t, int, struct ucred *, NFSPROC_T *);
int nfsrpc_openrpc(struct nfsmount *, vnode_t, u_int8_t *, int, u_int8_t *, int,
    u_int32_t, struct nfsclopen *, u_int8_t *, int, struct nfscldeleg **, int,
    u_int32_t, struct ucred *, NFSPROC_T *, int, int);
int nfsrpc_opendowngrade(vnode_t, u_int32_t, struct nfsclopen *,
    struct ucred *, NFSPROC_T *);
int nfsrpc_close(vnode_t, int, NFSPROC_T *);
int nfsrpc_closerpc(struct nfsrv_descript *, struct nfsmount *,
    struct nfsclopen *, struct ucred *, NFSPROC_T *, int);
int nfsrpc_openconfirm(vnode_t, u_int8_t *, int, struct nfsclopen *,
    struct ucred *, NFSPROC_T *);
int nfsrpc_setclient(struct nfsmount *, struct nfsclclient *,
    struct ucred *, NFSPROC_T *);
int nfsrpc_getattr(vnode_t, struct ucred *, NFSPROC_T *,
    struct nfsvattr *, void *);
int nfsrpc_getattrnovp(struct nfsmount *, u_int8_t *, int, int,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, u_int64_t *);
int nfsrpc_setattr(vnode_t, struct vattr *, NFSACL_T *, struct ucred *,
    NFSPROC_T *, struct nfsvattr *, int *, void *);
int nfsrpc_lookup(vnode_t, char *, int, struct ucred *, NFSPROC_T *,
    struct nfsvattr *, struct nfsvattr *, struct nfsfh **, int *, int *,
    void *);
int nfsrpc_readlink(vnode_t, struct uio *, struct ucred *,
    NFSPROC_T *, struct nfsvattr *, int *, void *);
int nfsrpc_read(vnode_t, struct uio *, struct ucred *, NFSPROC_T *,
    struct nfsvattr *, int *, void *);
int nfsrpc_write(vnode_t, struct uio *, int *, int *,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *, int);
int nfsrpc_mknod(vnode_t, char *, int, struct vattr *, u_int32_t,
    enum vtype, struct ucred *, NFSPROC_T *, struct nfsvattr *,
    struct nfsvattr *, struct nfsfh **, int *, int *, void *);
int nfsrpc_create(vnode_t, char *, int, struct vattr *, nfsquad_t,
    int, struct ucred *, NFSPROC_T *, struct nfsvattr *, struct nfsvattr *,
    struct nfsfh **, int *, int *, void *);
int nfsrpc_remove(vnode_t, char *, int, vnode_t, struct ucred *, NFSPROC_T *,
    struct nfsvattr *, int *, void *);
int nfsrpc_rename(vnode_t, vnode_t, char *, int, vnode_t, vnode_t, char *, int,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, struct nfsvattr *,
    int *, int *, void *, void *);
int nfsrpc_link(vnode_t, vnode_t, char *, int,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, struct nfsvattr *,
    int *, int *, void *);
int nfsrpc_symlink(vnode_t, char *, int, char *, struct vattr *,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, struct nfsvattr *,
    struct nfsfh **, int *, int *, void *);
int nfsrpc_mkdir(vnode_t, char *, int, struct vattr *,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, struct nfsvattr *,
    struct nfsfh **, int *, int *, void *);
int nfsrpc_rmdir(vnode_t, char *, int, struct ucred *, NFSPROC_T *,
    struct nfsvattr *, int *, void *);
int nfsrpc_readdir(vnode_t, struct uio *, nfsuint64 *, struct ucred *,
    NFSPROC_T *, struct nfsvattr *, int *, int *, void *);
int nfsrpc_readdirplus(vnode_t, struct uio *, nfsuint64 *,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, int *, void *);
int nfsrpc_commit(vnode_t, u_quad_t, int, struct ucred *,
    NFSPROC_T *, u_char *, struct nfsvattr *, int *, void *);
int nfsrpc_advlock(vnode_t, off_t, int, struct flock *, int,
    struct ucred *, NFSPROC_T *, void *, int);
int nfsrpc_lockt(struct nfsrv_descript *, vnode_t,
    struct nfsclclient *, u_int64_t, u_int64_t, struct flock *,
    struct ucred *, NFSPROC_T *, void *, int);
int nfsrpc_lock(struct nfsrv_descript *, struct nfsmount *, vnode_t,
    u_int8_t *, int, struct nfscllockowner *, int, int, u_int64_t,
    u_int64_t, short, struct ucred *, NFSPROC_T *, int);
int nfsrpc_statfs(vnode_t, struct nfsstatfs *, struct nfsfsinfo *,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *);
int nfsrpc_fsinfo(vnode_t, struct nfsfsinfo *, struct ucred *,
    NFSPROC_T *, struct nfsvattr *, int *, void *);
int nfsrpc_pathconf(vnode_t, struct nfsv3_pathconf *,
    struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *);
int nfsrpc_renew(struct nfsclclient *, struct ucred *,
    NFSPROC_T *);
int nfsrpc_rellockown(struct nfsmount *, struct nfscllockowner *,
    struct ucred *, NFSPROC_T *);
int nfsrpc_getdirpath(struct nfsmount *, u_char *, struct ucred *,
    NFSPROC_T *);
int nfsrpc_delegreturn(struct nfscldeleg *, struct ucred *,
    struct nfsmount *, NFSPROC_T *, int);
int nfsrpc_getacl(vnode_t, struct ucred *, NFSPROC_T *, NFSACL_T *, void *);
int nfsrpc_setacl(vnode_t, struct ucred *, NFSPROC_T *, NFSACL_T *, void *);

/* nfs_clstate.c */
int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int,
    struct ucred *, NFSPROC_T *, struct nfsclowner **, struct nfsclopen **,
    int *, int *, int);
int nfscl_getstateid(vnode_t, u_int8_t *, int, u_int32_t, struct ucred *,
    NFSPROC_T *, nfsv4stateid_t *, void **);
void nfscl_ownerrelease(struct nfsclowner *, int, int, int);
void nfscl_openrelease(struct nfsclopen *, int, int);
int nfscl_getcl(vnode_t, struct ucred *, NFSPROC_T *,
    struct nfsclclient **);
struct nfsclclient *nfscl_findcl(struct nfsmount *);
void nfscl_clientrelease(struct nfsclclient *);
void nfscl_freelock(struct nfscllock *, int);
void nfscl_freelockowner(struct nfscllockowner *, int);
int nfscl_getbytelock(vnode_t, u_int64_t, u_int64_t, short,
    struct ucred *, NFSPROC_T *, struct nfsclclient *, int, void *, int,
    u_int8_t *, u_int8_t *, struct nfscllockowner **, int *, int *);
int nfscl_relbytelock(vnode_t, u_int64_t, u_int64_t,
    struct ucred *, NFSPROC_T *, int, struct nfsclclient *,
    void *, int, struct nfscllockowner **, int *);
int nfscl_checkwritelocked(vnode_t, struct flock *,
    struct ucred *, NFSPROC_T *, void *, int);
void nfscl_lockrelease(struct nfscllockowner *, int, int);
void nfscl_fillclid(u_int64_t, char *, u_int8_t *, u_int16_t);
void nfscl_filllockowner(void *, u_int8_t *, int);
void nfscl_freeopen(struct nfsclopen *, int);
void nfscl_umount(struct nfsmount *, NFSPROC_T *);
void nfscl_renewthread(struct nfsclclient *, NFSPROC_T *);
void nfscl_initiate_recovery(struct nfsclclient *);
int nfscl_hasexpired(struct nfsclclient *, u_int32_t, NFSPROC_T *);
void nfscl_dumpstate(struct nfsmount *, int, int, int, int);
void nfscl_dupopen(vnode_t, int);
int nfscl_getclose(vnode_t, struct nfsclclient **);
int nfscl_doclose(vnode_t, struct nfsclclient **, NFSPROC_T *);
void nfsrpc_doclose(struct nfsmount *, struct nfsclopen *, NFSPROC_T *);
int nfscl_deleg(mount_t, struct nfsclclient *, u_int8_t *, int,
    struct ucred *, NFSPROC_T *, struct nfscldeleg **);
void nfscl_lockinit(struct nfsv4lock *);
void nfscl_lockexcl(struct nfsv4lock *, void *);
void nfscl_lockunlock(struct nfsv4lock *);
void nfscl_lockderef(struct nfsv4lock *);
void nfscl_docb(struct nfsrv_descript *, NFSPROC_T *);
void nfscl_releasealllocks(struct nfsclclient *, vnode_t, NFSPROC_T *, void *,
    int);
int nfscl_lockt(vnode_t, struct nfsclclient *, u_int64_t,
    u_int64_t, struct flock *, NFSPROC_T *, void *, int);
int nfscl_mustflush(vnode_t);
int nfscl_nodeleg(vnode_t, int);
int nfscl_removedeleg(vnode_t, NFSPROC_T *, nfsv4stateid_t *);
int nfscl_getref(struct nfsmount *);
void nfscl_relref(struct nfsmount *);
int nfscl_renamedeleg(vnode_t, nfsv4stateid_t *, int *, vnode_t,
    nfsv4stateid_t *, int *, NFSPROC_T *);
void nfscl_reclaimnode(vnode_t);
void nfscl_newnode(vnode_t);
void nfscl_delegmodtime(vnode_t);
void nfscl_deleggetmodtime(vnode_t, struct timespec *);
int nfscl_tryclose(struct nfsclopen *, struct ucred *,
    struct nfsmount *, NFSPROC_T *);
void nfscl_cleanup(NFSPROC_T *);

/* nfs_clport.c */
int nfscl_nget(mount_t, vnode_t, struct nfsfh *,
    struct componentname *, NFSPROC_T *, struct nfsnode **, void *, int);
NFSPROC_T *nfscl_getparent(NFSPROC_T *);
void nfscl_start_renewthread(struct nfsclclient *);
void nfscl_loadsbinfo(struct nfsmount *, struct nfsstatfs *, void *);
void nfscl_loadfsinfo (struct nfsmount *, struct nfsfsinfo *);
void nfscl_delegreturn(struct nfscldeleg *, int, struct nfsmount *,
    struct ucred *, NFSPROC_T *);
void nfsrvd_cbinit(int);
int nfscl_checksattr(struct vattr *, struct nfsvattr *);
int nfscl_ngetreopen(mount_t, u_int8_t *, int, NFSPROC_T *,
    struct nfsnode **);
int nfscl_procdoesntexist(u_int8_t *);
int nfscl_maperr(NFSPROC_T *, int, uid_t, gid_t);

/* nfs_clsubs.c */
void nfscl_init(void);

/* nfs_clbio.c */
int ncl_flush(vnode_t, int, struct ucred *, NFSPROC_T *, int, int);

/* nfs_clnode.c */
void ncl_invalcaches(vnode_t);

/* nfs_nfsdport.c */
int nfsvno_getattr(vnode_t, struct nfsvattr *, struct ucred *,
    NFSPROC_T *, int);
int nfsvno_setattr(vnode_t, struct nfsvattr *, struct ucred *,
    NFSPROC_T *, struct nfsexstuff *);
int nfsvno_getfh(vnode_t, fhandle_t *, NFSPROC_T *);
int nfsvno_accchk(vnode_t, accmode_t, struct ucred *,
    struct nfsexstuff *, NFSPROC_T *, int, int, u_int32_t *);
int nfsvno_namei(struct nfsrv_descript *, struct nameidata *,
    vnode_t, int, struct nfsexstuff *, NFSPROC_T *, vnode_t *);
void nfsvno_setpathbuf(struct nameidata *, char **, u_long **);
void nfsvno_relpathbuf(struct nameidata *);
int nfsvno_readlink(vnode_t, struct ucred *, NFSPROC_T *, mbuf_t *,
    mbuf_t *, int *);
int nfsvno_read(vnode_t, off_t, int, struct ucred *, NFSPROC_T *,
    mbuf_t *, mbuf_t *);
int nfsvno_write(vnode_t, off_t, int, int, int, mbuf_t,
    char *, struct ucred *, NFSPROC_T *);
int nfsvno_createsub(struct nfsrv_descript *, struct nameidata *,
    vnode_t *, struct nfsvattr *, int *, int32_t *, NFSDEV_T, NFSPROC_T *,
    struct nfsexstuff *);
int nfsvno_mknod(struct nameidata *, struct nfsvattr *, struct ucred *,
    NFSPROC_T *);
int nfsvno_mkdir(struct nameidata *,
    struct nfsvattr *, uid_t, struct ucred *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsvno_symlink(struct nameidata *, struct nfsvattr *, char *, int, int,
    uid_t, struct ucred *, NFSPROC_T *, struct nfsexstuff *);
int nfsvno_getsymlink(struct nfsrv_descript *, struct nfsvattr *,
    NFSPROC_T *, char **, int *);
int nfsvno_removesub(struct nameidata *, int, struct ucred *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsvno_rmdirsub(struct nameidata *, int, struct ucred *, NFSPROC_T *,
    struct nfsexstuff *);
int nfsvno_rename(struct nameidata *, struct nameidata *, u_int32_t,
    u_int32_t, struct ucred *, NFSPROC_T *);
int nfsvno_link(struct nameidata *, vnode_t, struct ucred *,
    NFSPROC_T *, struct nfsexstuff *);
int nfsvno_fsync(vnode_t, u_int64_t, int, struct ucred *, NFSPROC_T *);
int nfsvno_statfs(vnode_t, struct statfs *);
void nfsvno_getfs(struct nfsfsinfo *, int);
void nfsvno_open(struct nfsrv_descript *, struct nameidata *, nfsquad_t,
    nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, int32_t *,
    int, NFSACL_T *, nfsattrbit_t *, struct ucred *, NFSPROC_T *,
    struct nfsexstuff *, vnode_t *);
void nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *,
    NFSPROC_T *);
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
    struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
    struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t);
int nfsrv_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,
    NFSACL_T *, NFSPROC_T *);
int nfsv4_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,
    NFSACL_T *, NFSPROC_T *);
int nfsvno_checkexp(mount_t, NFSSOCKADDR_T, struct nfsexstuff *,
    struct ucred **);
int nfsvno_fhtovp(mount_t, fhandle_t *, NFSSOCKADDR_T, int,
    vnode_t *, struct nfsexstuff *, struct ucred **);
vnode_t nfsvno_getvp(fhandle_t *);
int nfsvno_advlock(vnode_t, int, u_int64_t, u_int64_t, NFSPROC_T *);
int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *);
int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *);
uint32_t nfsrv_hashfh(fhandle_t *);
void nfsrv_backupstable(void);

/* nfs_commonkrpc.c */
int newnfs_nmcancelreqs(struct nfsmount *);
void newnfs_set_sigmask(struct thread *, sigset_t *);
void newnfs_restore_sigmask(struct thread *, sigset_t *);
int newnfs_msleep(struct thread *, void *, struct mtx *, int, char *, int);
int newnfs_request(struct nfsrv_descript *, struct nfsmount *,
    struct nfsclient *, struct nfssockreq *, vnode_t, NFSPROC_T *,
    struct ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *);
int newnfs_connect(struct nfsmount *, struct nfssockreq *,
    struct ucred *, NFSPROC_T *, int);
void newnfs_disconnect(struct nfssockreq *);
int newnfs_sigintr(struct nfsmount *, NFSPROC_T *);

/* nfs_nfsdkrpc.c */
int nfsrvd_addsock(struct file *);
int nfsrvd_nfsd(NFSPROC_T *, struct nfsd_nfsd_args *);
void nfsrvd_init(int);

/* nfs_clkrpc.c */
int nfscbd_addsock(struct file *);
int nfscbd_nfsd(NFSPROC_T *, struct nfsd_nfscbd_args *);


code:
/*-
 * Copyright (c) 2009 Rick Macklem, University of Guelph
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/fs/nfs/nfscl.h 191783 2009-05-04 15:23:58Z rmacklem $
 */

#ifndef	_NFS_NFSCL_H
#define	_NFS_NFSCL_H

/*
 * Extra stuff for a NFSv4 nfsnode.
 * MALLOC'd to the correct length for the name and file handle.
 * n4_data has the file handle, followed by the file name.
 * The macro NFS4NODENAME() returns a pointer to the start of the
 * name.
 */
struct nfsv4node {
	u_int16_t	n4_fhlen;
	u_int16_t	n4_namelen;
	u_int8_t	n4_data[1];
};

#define	NFS4NODENAME(n)	(&((n)->n4_data[(n)->n4_fhlen]))

/*
 * Just a macro to convert the nfscl_reqstart arguments.
 */
#define	NFSCL_REQSTART(n, p, v) 					\
	nfscl_reqstart((n), (p), VFSTONFS((v)->v_mount), 		\
	    VTONFS(v)->n_fhp->nfh_fh, VTONFS(v)->n_fhp->nfh_len, NULL)

/*
 * These two macros convert between a lease duration and renew interval.
 * For now, just make the renew interval 1/2 the lease duration.
 * (They should be inverse operators.)
 */
#define	NFSCL_RENEW(l)	(((l) < 2) ? 1 : ((l) / 2))
#define	NFSCL_LEASE(r)	((r) * 2)

/*
 * These flag bits are used for the argument to nfscl_fillsattr() to
 * indicate special handling of the attributes.
 */
#define	NFSSATTR_FULL		0x1
#define	NFSSATTR_SIZE0		0x2
#define	NFSSATTR_SIZENEG1	0x4
#define	NFSSATTR_SIZERDEV	0x8

#endif	/* _NFS_NFSCL_H */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Copyright (c) 2009 Rick Macklem, University of Guelph
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/fs/nfs/nfsclstate.h 214406 2010-10-26 23:18:37Z rmacklem $
 */

#ifndef _NFS_NFSCLSTATE_H_
#define	_NFS_NFSCLSTATE_H_

/*
 * Definitions for NFS V4 client state handling.
 */
LIST_HEAD(nfsclopenhead, nfsclopen);
LIST_HEAD(nfscllockownerhead, nfscllockowner);
LIST_HEAD(nfscllockhead, nfscllock);
LIST_HEAD(nfsclhead, nfsclclient);
LIST_HEAD(nfsclownerhead, nfsclowner);
TAILQ_HEAD(nfscldeleghead, nfscldeleg);
LIST_HEAD(nfscldeleghash, nfscldeleg);
#define	NFSCLDELEGHASHSIZE	256
#define	NFSCLDELEGHASH(c, f, l)						\
	(&((c)->nfsc_deleghash[ncl_hash((f), (l)) % NFSCLDELEGHASHSIZE]))

struct nfsclclient {
	LIST_ENTRY(nfsclclient) nfsc_list;
	struct nfsclownerhead	nfsc_owner;
	struct nfscldeleghead	nfsc_deleg;
	struct nfscldeleghash	nfsc_deleghash[NFSCLDELEGHASHSIZE];
	struct nfscllockownerhead nfsc_defunctlockowner;
	struct nfsv4lock nfsc_lock;
	struct proc	*nfsc_renewthread;
	struct nfsmount	*nfsc_nmp;
	nfsquad_t	nfsc_clientid;
	time_t		nfsc_expire;
	u_int32_t	nfsc_clientidrev;
	u_int32_t	nfsc_renew;
	u_int32_t	nfsc_cbident;
	u_int16_t	nfsc_flags;
	u_int16_t	nfsc_idlen;
	u_int8_t	nfsc_id[1];	/* Malloc'd to correct length */
};

/*
 * Bits for nfsc_flags.
 */
#define	NFSCLFLAGS_INITED	0x0001
#define	NFSCLFLAGS_HASCLIENTID	0x0002
#define	NFSCLFLAGS_RECOVER	0x0004
#define	NFSCLFLAGS_UMOUNT	0x0008
#define	NFSCLFLAGS_HASTHREAD	0x0010
#define	NFSCLFLAGS_AFINET6	0x0020
#define	NFSCLFLAGS_EXPIREIT	0x0040
#define	NFSCLFLAGS_FIRSTDELEG	0x0080
#define	NFSCLFLAGS_GOTDELEG	0x0100
#define	NFSCLFLAGS_RECVRINPROG	0x0200

struct nfsclowner {
	LIST_ENTRY(nfsclowner)	nfsow_list;
	struct nfsclopenhead	nfsow_open;
	struct nfsclclient	*nfsow_clp;
	u_int32_t		nfsow_seqid;
	u_int32_t		nfsow_defunct;
	struct nfsv4lock	nfsow_rwlock;
	u_int8_t		nfsow_owner[NFSV4CL_LOCKNAMELEN];
};

/*
 * MALLOC'd to the correct length to accommodate the file handle.
 */
struct nfscldeleg {
	TAILQ_ENTRY(nfscldeleg)	nfsdl_list;
	LIST_ENTRY(nfscldeleg)	nfsdl_hash;
	struct nfsclownerhead	nfsdl_owner;	/* locally issued state */
	struct nfscllockownerhead nfsdl_lock;
	nfsv4stateid_t		nfsdl_stateid;
	struct acl_entry	nfsdl_ace;	/* Delegation ace */
	struct nfsclclient	*nfsdl_clp;
	struct nfsv4lock	nfsdl_rwlock;	/* for active I/O ops */
	struct nfscred		nfsdl_cred;	/* Cred. used for Open */
	time_t			nfsdl_timestamp; /* used for stale cleanup */
	u_int64_t		nfsdl_sizelimit; /* Limit for file growth */
	u_int64_t		nfsdl_size;	/* saved copy of file size */
	u_int64_t		nfsdl_change;	/* and change attribute */
	struct timespec		nfsdl_modtime;	/* local modify time */
	u_int16_t		nfsdl_fhlen;
	u_int8_t		nfsdl_flags;
	u_int8_t		nfsdl_fh[1];	/* must be last */
};

/*
 * nfsdl_flags bits.
 */
#define	NFSCLDL_READ		0x01
#define	NFSCLDL_WRITE		0x02
#define	NFSCLDL_RECALL		0x04
#define	NFSCLDL_NEEDRECLAIM	0x08
#define	NFSCLDL_ZAPPED		0x10
#define	NFSCLDL_MODTIMESET	0x20
#define	NFSCLDL_DELEGRET	0x40

/*
 * MALLOC'd to the correct length to accommodate the file handle.
 */
struct nfsclopen {
	LIST_ENTRY(nfsclopen)	nfso_list;
	struct nfscllockownerhead nfso_lock;
	nfsv4stateid_t		nfso_stateid;
	struct nfsclowner	*nfso_own;
	struct nfscred		nfso_cred;	/* Cred. used for Open */
	u_int32_t		nfso_mode;
	u_int32_t		nfso_opencnt;
	u_int16_t		nfso_fhlen;
	u_int8_t		nfso_posixlock;	/* 1 for POSIX type locking */
	u_int8_t		nfso_fh[1];	/* must be last */
};

/*
 * Return values for nfscl_open(). NFSCLOPEN_OK must == 0.
 */
#define	NFSCLOPEN_OK		0
#define	NFSCLOPEN_DOOPEN	1
#define	NFSCLOPEN_DOOPENDOWNGRADE 2
#define	NFSCLOPEN_SETCRED	3

struct nfscllockowner {
	LIST_ENTRY(nfscllockowner) nfsl_list;
	struct nfscllockhead	nfsl_lock;
	struct nfsclopen	*nfsl_open;
	NFSPROC_T		*nfsl_inprog;
	nfsv4stateid_t		nfsl_stateid;
	u_int32_t		nfsl_seqid;
	u_int32_t		nfsl_defunct;
	struct nfsv4lock	nfsl_rwlock;
	u_int8_t		nfsl_owner[NFSV4CL_LOCKNAMELEN];
	u_int8_t		nfsl_openowner[NFSV4CL_LOCKNAMELEN];
};

/*
 * Byte range entry for the above lock owner.
 */
struct nfscllock {
	LIST_ENTRY(nfscllock)	nfslo_list;
	u_int64_t		nfslo_first;
	u_int64_t		nfslo_end;
	short			nfslo_type;
};

/*
 * Macro for incrementing the seqid#.
 */
#define	NFSCL_INCRSEQID(s, n)	do { 					\
	    if (((n)->nd_flag & ND_INCRSEQID))				\
		(s)++; 							\
	} while (0)

#endif	/* _NFS_NFSCLSTATE_H_ */


code:
/*-
 * Copyright (c) 2009 Rick Macklem, University of Guelph
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/fs/nfs/nfsdport.h 224086 2011-07-16 08:51:09Z zack $
 */

/*
 * These macros handle nfsvattr fields. They look a bit silly here, but
 * are quite different for the Darwin port.
 */
#define	NFSVNO_ATTRINIT(n)		(VATTR_NULL(&((n)->na_vattr)))
#define	NFSVNO_SETATTRVAL(n, f, v)	((n)->na_##f = (v))
#define	NFSVNO_SETACTIVE(n, f)
#define	NFSVNO_UNSET(n, f)		((n)->na_##f = VNOVAL)
#define	NFSVNO_NOTSETMODE(n)		((n)->na_mode == ((mode_t)VNOVAL))
#define	NFSVNO_ISSETMODE(n)		((n)->na_mode != ((mode_t)VNOVAL))
#define	NFSVNO_NOTSETUID(n)		((n)->na_uid == ((uid_t)VNOVAL))
#define	NFSVNO_ISSETUID(n)		((n)->na_uid != ((uid_t)VNOVAL))
#define	NFSVNO_NOTSETGID(n)		((n)->na_gid == ((gid_t)VNOVAL))
#define	NFSVNO_ISSETGID(n)		((n)->na_gid != ((gid_t)VNOVAL))
#define	NFSVNO_NOTSETSIZE(n)		((n)->na_size == VNOVAL)
#define	NFSVNO_ISSETSIZE(n)		((n)->na_size != VNOVAL)
#define	NFSVNO_NOTSETATIME(n)		((n)->na_atime.tv_sec == VNOVAL)
#define	NFSVNO_ISSETATIME(n)		((n)->na_atime.tv_sec != VNOVAL)
#define	NFSVNO_NOTSETMTIME(n)		((n)->na_mtime.tv_sec == VNOVAL)
#define	NFSVNO_ISSETMTIME(n)		((n)->na_mtime.tv_sec != VNOVAL)

/*
 * This structure acts as a "catch-all" for information that
 * needs to be returned by nfsd_fhtovp().
 */
struct nfsexstuff {
	int	nes_exflag;			/* export flags */
	int	nes_numsecflavor;		/* # of security flavors */
	int	nes_secflavors[MAXSECFLAVORS];	/* and the flavors */
};

/*
 * These are NO-OPS for BSD until Isilon upstreams EXITCODE support.
 * EXITCODE is an in-memory ring buffer that holds the routines failing status.
 * This is a valuable tool to use when debugging and analyzing issues.
 * In addition to recording a routine's failing status, it offers
 * logging of routines for call stack tracing.
 * EXITCODE should be used only in routines that return a true errno value, as
 * that value will be formatted to a displayable errno string.  Routines that
 * return regular int status that are not true errno should not set EXITCODE.
 * If you want to log routine tracing, you can add EXITCODE(0) to any routine.
 * NFS extended the EXITCODE with EXITCODE2 to record either the routine's
 * exit errno status or the nd_repstat.
 */
#define	NFSEXITCODE(error)
#define	NFSEXITCODE2(error, nd)

#define	NFSVNO_EXINIT(e)		((e)->nes_exflag = 0)
#define	NFSVNO_EXPORTED(e)		((e)->nes_exflag & MNT_EXPORTED)
#define	NFSVNO_EXRDONLY(e)		((e)->nes_exflag & MNT_EXRDONLY)
#define	NFSVNO_EXPORTANON(e)		((e)->nes_exflag & MNT_EXPORTANON)
#define	NFSVNO_EXSTRICTACCESS(e)	((e)->nes_exflag & MNT_EXSTRICTACCESS)
#define	NFSVNO_EXV4ONLY(e)		((e)->nes_exflag & MNT_EXV4ONLY)

#define	NFSVNO_SETEXRDONLY(e)	((e)->nes_exflag = (MNT_EXPORTED|MNT_EXRDONLY))

#define	NFSVNO_CMPFH(f1, f2)						\
    ((f1)->fh_fsid.val[0] == (f2)->fh_fsid.val[0] &&			\
     (f1)->fh_fsid.val[1] == (f2)->fh_fsid.val[1] &&			\
     bcmp(&(f1)->fh_fid, &(f2)->fh_fid, sizeof(struct fid)) == 0)

#define	NFSLOCKHASH(f) 							\
	(&nfslockhash[nfsrv_hashfh(f) % NFSLOCKHASHSIZE])

#define	NFSFPVNODE(f)	((struct vnode *)((f)->f_data))
#define	NFSFPCRED(f)	((f)->f_cred)
#define	NFSFPFLAG(f)	((f)->f_flag)

int fp_getfvp(NFSPROC_T *, int, struct file **, struct vnode **);

#define	NFSNAMEICNDSET(n, c, o, f)	do {				\
	(n)->cn_cred = (c);						\
	(n)->cn_nameiop = (o);						\
	(n)->cn_flags = (f);						\
    } while (0)

/*
 * A little bit of Darwin vfs kpi.
 */
#define	vnode_mount(v)	((v)->v_mount)
#define	vfs_statfs(m)	(&((m)->mnt_stat))

#define	NFSPATHLEN_T	size_t

/*
 * These are set to the minimum and maximum size of a server file
 * handle.
 */
#define	NFSRV_MINFH	(sizeof (fhandle_t))
#define	NFSRV_MAXFH	(sizeof (fhandle_t))


code:
/*-
 * Copyright (c) 2009 Rick Macklem, University of Guelph
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/fs/nfs/nfskpiport.h 207785 2010-05-08 14:50:12Z rmacklem $
 */

#ifndef _NFS_NFSKPIPORT_H_
#define	_NFS_NFSKPIPORT_H_
/*
 * These definitions are needed since the generic code is now using Darwin8
 * KPI stuff. (I know, seems a bit silly, but I want the code to build on
 * Darwin8 and hopefully subsequent releases from Apple.)
 */
typedef	struct mount *		mount_t;
#define	vfs_statfs(m)		(&((m)->mnt_stat))
#define	vfs_flags(m)		((m)->mnt_flag)

typedef struct vnode *		vnode_t;
#define	vnode_mount(v)		((v)->v_mount)
#define	vnode_vtype(v)		((v)->v_type)

typedef struct mbuf *		mbuf_t;
#define	mbuf_freem(m)		m_freem(m)
#define	mbuf_data(m)		mtod((m), void *)
#define	mbuf_len(m)		((m)->m_len)
#define	mbuf_next(m)		((m)->m_next)
#define	mbuf_setlen(m, l)	((m)->m_len = (l))
#define	mbuf_setnext(m, p)	((m)->m_next = (p))
#define	mbuf_pkthdr_len(m)	((m)->m_pkthdr.len)
#define	mbuf_pkthdr_setlen(m, l) ((m)->m_pkthdr.len = (l))
#define	mbuf_pkthdr_setrcvif(m, p) ((m)->m_pkthdr.rcvif = (p))

/*
 * This stuff is needed by Darwin for handling the uio structure.
 */
#define	CAST_USER_ADDR_T(a)	(a)
#define	CAST_DOWN(c, a)		((c) (a))
#define	uio_uio_resid(p)	((p)->uio_resid)
#define	uio_uio_resid_add(p, v)	((p)->uio_resid += (v))
#define	uio_uio_resid_set(p, v)	((p)->uio_resid = (v))
#define	uio_iov_base(p)		((p)->uio_iov->iov_base)
#define	uio_iov_base_add(p, v)	do {					\
	char *pp;							\
	pp = (char *)(p)->uio_iov->iov_base;				\
	pp += (v);							\
	(p)->uio_iov->iov_base = (void *)pp;				\
    } while (0)
#define	uio_iov_len(p)		((p)->uio_iov->iov_len)
#define	uio_iov_len_add(p, v)	((p)->uio_iov->iov_len += (v))

#endif	/* _NFS_NFSKPIPORT_H */


code:
/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/fs/nfs/nfsm_subs.h 191783 2009-05-04 15:23:58Z rmacklem $
 */

#ifndef _NFS_NFSM_SUBS_H_
#define	_NFS_NFSM_SUBS_H_

/*
 * These macros do strange and peculiar things to mbuf chains for
 * the assistance of the nfs code. To attempt to use them for any
 * other purpose will be dangerous. (they make weird assumptions)
 */

#ifndef APPLE
/*
 * First define what the actual subs. return
 */
#define	M_HASCL(m)	((m)->m_flags & M_EXT)
#define	NFSMINOFF(m) 							\
		if (M_HASCL(m)) 					\
			(m)->m_data = (m)->m_ext.ext_buf; 		\
		else if ((m)->m_flags & M_PKTHDR) 			\
			(m)->m_data = (m)->m_pktdat; 			\
				else 					\
			(m)->m_data = (m)->m_dat
#define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: 			\
				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
#define	NFSM_DATAP(m, s)	(m)->m_data += (s)

/*
 * Now for the macros that do the simple stuff and call the functions
 * for the hard stuff.
 * They use fields in struct nfsrv_descript to handle the mbuf queues.
 * Replace most of the macro with an inline function, to minimize
 * the machine code. The inline functions in lower case can be called
 * directly, bypassing the macro.
 */
static __inline void *
nfsm_build(struct nfsrv_descript *nd, int siz)
{
	void *retp;
	struct mbuf *mb2;

	if (siz > M_TRAILINGSPACE(nd->nd_mb)) {
		NFSMCLGET(mb2, M_DONTWAIT);
		if (siz > MLEN)
			panic("build > MLEN");
		mbuf_setlen(mb2, 0);
		nd->nd_bpos = NFSMTOD(mb2, caddr_t);
		nd->nd_mb->m_next = mb2;
		nd->nd_mb = mb2;
	}
	retp = (void *)(nd->nd_bpos);
	nd->nd_mb->m_len += siz;
	nd->nd_bpos += siz;
	return (retp);
}

#define	NFSM_BUILD(a, c, s)	((a) = (c)nfsm_build(nd, (s)))

static __inline void *
nfsm_dissect(struct nfsrv_descript *nd, int siz)
{
	int tt1;
	void *retp;

	tt1 = NFSMTOD(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos;
	if (tt1 >= siz) {
		retp = (void *)nd->nd_dpos;
		nd->nd_dpos += siz;
	} else {
		retp = nfsm_dissct(nd, siz);
	}
	return (retp);
}

#define	NFSM_DISSECT(a, c, s) 						\
	do {								\
		(a) = (c)nfsm_dissect(nd, (s));	 			\
		if ((a) == NULL) { 					\
			error = EBADRPC; 				\
			goto nfsmout; 					\
		}							\
	} while (0)
#endif	/* !APPLE */

#define	NFSM_STRSIZ(s, m)  						\
	do {								\
		tl = (u_int32_t *)nfsm_dissect(nd, NFSX_UNSIGNED);	\
		if (!tl || ((s) = fxdr_unsigned(int32_t, *tl)) > (m)) { \
			error = EBADRPC; 				\
			goto nfsmout; 					\
		}							\
	} while (0)

#define	NFSM_RNDUP(a)	(((a)+3)&(~0x3))

#endif	/* _NFS_NFSM_SUBS_H_ */


code:
/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/fs/nfs/nfsport.h 224080 2011-07-16 08:05:26Z zack $
 */

#ifndef _NFS_NFSPORT_H_
#define	_NFS_NFSPORT_H_

/*
 * In general, I'm not fond of #includes in .h files, but this seems
 * to be the cleanest way to handle #include files for the ports.
 */
#ifdef _KERNEL
#include <sys/unistd.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/dirent.h>
#include <sys/domain.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/lockf.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/reboot.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/syslog.h>
#include <sys/sysproto.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/vnode.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/acl.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/syscall.h>
#include <sys/priv.h>
#include <sys/kthread.h>
#include <sys/syscallsubr.h>
#include <fs/fifofs/fifo.h>
#include <net/if.h>
#include <net/radix.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <machine/in_cksum.h>
#include <crypto/des/des.h>
#include <sys/md5.h>
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>

/*
 * For Darwin, these functions should be "static" when built in a kext.
 * (This is always defined as nil otherwise.)
 */
#define	APPLESTATIC
#include <ufs/ufs/dir.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/extattr.h>
#include <ufs/ufs/ufsmount.h>
#include <vm/uma.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
#include <nfs/nfssvc.h>
#include "opt_nfs.h"
#include "opt_ufs.h"

/*
 * These types must be defined before the nfs includes.
 */
#define	NFSSOCKADDR_T	struct sockaddr *
#define	NFSPROC_T	struct thread
#define	NFSDEV_T	dev_t
#define	NFSSVCARGS	nfssvc_args
#define	NFSACL_T	struct acl

/*
 * These should be defined as the types used for the corresponding VOP's
 * argument type.
 */
#define	NFS_ACCESS_ARGS		struct vop_access_args
#define	NFS_OPEN_ARGS		struct vop_open_args
#define	NFS_GETATTR_ARGS	struct vop_getattr_args
#define	NFS_LOOKUP_ARGS		struct vop_lookup_args
#define	NFS_READDIR_ARGS	struct vop_readdir_args

/*
 * Allocate mbufs. Must succeed and never set the mbuf ptr to NULL.
 */
#define	NFSMGET(m)	do { 					\
		MGET((m), M_TRYWAIT, MT_DATA); 			\
		while ((m) == NULL ) { 				\
			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
			MGET((m), M_TRYWAIT, MT_DATA); 		\
		} 						\
	} while (0)
#define	NFSMGETHDR(m)	do { 					\
		MGETHDR((m), M_TRYWAIT, MT_DATA);		\
		while ((m) == NULL ) { 				\
			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
			MGETHDR((m), M_TRYWAIT, MT_DATA); 	\
		} 						\
	} while (0)
#define	NFSMCLGET(m, w)	do { 					\
		MGET((m), M_TRYWAIT, MT_DATA); 			\
		while ((m) == NULL ) { 				\
			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
			MGET((m), M_TRYWAIT, MT_DATA); 		\
		} 						\
		MCLGET((m), (w));				\
	} while (0)
#define	NFSMCLGETHDR(m, w) do { 				\
		MGETHDR((m), M_TRYWAIT, MT_DATA);		\
		while ((m) == NULL ) { 				\
			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
			MGETHDR((m), M_TRYWAIT, MT_DATA); 	\
		} 						\
	} while (0)
#define	NFSMTOD	mtod

/*
 * Client side constant for size of a lockowner name.
 */
#define	NFSV4CL_LOCKNAMELEN	12

/*
 * Type for a mutex lock.
 */
#define	NFSMUTEX_T		struct mtx

#endif	/* _KERNEL */

/*
 * NFSv4 Operation numbers.
 */
#define	NFSV4OP_ACCESS		3
#define	NFSV4OP_CLOSE		4
#define	NFSV4OP_COMMIT		5
#define	NFSV4OP_CREATE		6
#define	NFSV4OP_DELEGPURGE	7
#define	NFSV4OP_DELEGRETURN	8
#define	NFSV4OP_GETATTR		9
#define	NFSV4OP_GETFH		10
#define	NFSV4OP_LINK		11
#define	NFSV4OP_LOCK		12
#define	NFSV4OP_LOCKT		13
#define	NFSV4OP_LOCKU		14
#define	NFSV4OP_LOOKUP		15
#define	NFSV4OP_LOOKUPP		16
#define	NFSV4OP_NVERIFY		17
#define	NFSV4OP_OPEN		18
#define	NFSV4OP_OPENATTR	19
#define	NFSV4OP_OPENCONFIRM	20
#define	NFSV4OP_OPENDOWNGRADE	21
#define	NFSV4OP_PUTFH		22
#define	NFSV4OP_PUTPUBFH	23
#define	NFSV4OP_PUTROOTFH	24
#define	NFSV4OP_READ		25
#define	NFSV4OP_READDIR		26
#define	NFSV4OP_READLINK	27
#define	NFSV4OP_REMOVE		28
#define	NFSV4OP_RENAME		29
#define	NFSV4OP_RENEW		30
#define	NFSV4OP_RESTOREFH	31
#define	NFSV4OP_SAVEFH		32
#define	NFSV4OP_SECINFO		33
#define	NFSV4OP_SETATTR		34
#define	NFSV4OP_SETCLIENTID	35
#define	NFSV4OP_SETCLIENTIDCFRM	36
#define	NFSV4OP_VERIFY		37
#define	NFSV4OP_WRITE		38
#define	NFSV4OP_RELEASELCKOWN	39

/*
 * Must be one greater than the last Operation#.
 */
#define	NFSV4OP_NOPS		40

/* Quirky case if the illegal op code */
#define	NFSV4OP_OPILLEGAL	10044

/*
 * Fake NFSV4OP_xxx used for nfsstat. Start at NFSV4OP_NOPS.
 */
#define	NFSV4OP_SYMLINK		(NFSV4OP_NOPS)
#define	NFSV4OP_MKDIR		(NFSV4OP_NOPS + 1)
#define	NFSV4OP_RMDIR		(NFSV4OP_NOPS + 2)
#define	NFSV4OP_READDIRPLUS	(NFSV4OP_NOPS + 3)
#define	NFSV4OP_MKNOD		(NFSV4OP_NOPS + 4)
#define	NFSV4OP_FSSTAT		(NFSV4OP_NOPS + 5)
#define	NFSV4OP_FSINFO		(NFSV4OP_NOPS + 6)
#define	NFSV4OP_PATHCONF	(NFSV4OP_NOPS + 7)
#define	NFSV4OP_V3CREATE	(NFSV4OP_NOPS + 8)

/*
 * This is the count of the fake operations listed above.
 */
#define	NFSV4OP_FAKENOPS	9

/*
 * and the Callback OPs
 */
#define	NFSV4OP_CBGETATTR	3
#define	NFSV4OP_CBRECALL	4

/*
 * Must be one greater than the last Callback Operation#.
 */
#define	NFSV4OP_CBNOPS		5

/*
 * The lower numbers -> 21 are used by NFSv2 and v3. These define higher
 * numbers used by NFSv4.
 * NFS_V3NPROCS is one greater than the last V3 op and NFS_NPROCS is
 * one greater than the last number.
 */
#ifndef	NFS_V3NPROCS
#define	NFS_V3NPROCS		22

#define	NFSPROC_LOOKUPP		22
#define	NFSPROC_SETCLIENTID	23
#define	NFSPROC_SETCLIENTIDCFRM	24
#define	NFSPROC_LOCK		25
#define	NFSPROC_LOCKU		26
#define	NFSPROC_OPEN		27
#define	NFSPROC_CLOSE		28
#define	NFSPROC_OPENCONFIRM	29
#define	NFSPROC_LOCKT		30
#define	NFSPROC_OPENDOWNGRADE	31
#define	NFSPROC_RENEW		32
#define	NFSPROC_PUTROOTFH	33
#define	NFSPROC_RELEASELCKOWN	34
#define	NFSPROC_DELEGRETURN	35
#define	NFSPROC_RETDELEGREMOVE	36
#define	NFSPROC_RETDELEGRENAME1	37
#define	NFSPROC_RETDELEGRENAME2	38
#define	NFSPROC_GETACL		39
#define	NFSPROC_SETACL		40

/*
 * Must be defined as one higher than the last Proc# above.
 */
#define	NFSV4_NPROCS		41
#endif	/* NFS_V3NPROCS */

/*
 * Stats structure
 */
struct ext_nfsstats {
	int	attrcache_hits;
	int	attrcache_misses;
	int	lookupcache_hits;
	int	lookupcache_misses;
	int	direofcache_hits;
	int	direofcache_misses;
	int	accesscache_hits;
	int	accesscache_misses;
	int	biocache_reads;
	int	read_bios;
	int	read_physios;
	int	biocache_writes;
	int	write_bios;
	int	write_physios;
	int	biocache_readlinks;
	int	readlink_bios;
	int	biocache_readdirs;
	int	readdir_bios;
	int	rpccnt[NFSV4_NPROCS];
	int	rpcretries;
	int	srvrpccnt[NFSV4OP_NOPS + NFSV4OP_FAKENOPS];
	int	srvrpc_errs;
	int	srv_errs;
	int	rpcrequests;
	int	rpctimeouts;
	int	rpcunexpected;
	int	rpcinvalid;
	int	srvcache_inproghits;
	int	srvcache_idemdonehits;
	int	srvcache_nonidemdonehits;
	int	srvcache_misses;
	int	srvcache_tcppeak;
	int	srvcache_size;
	int	srvclients;
	int	srvopenowners;
	int	srvopens;
	int	srvlockowners;
	int	srvlocks;
	int	srvdelegates;
	int	cbrpccnt[NFSV4OP_CBNOPS];
	int	clopenowners;
	int	clopens;
	int	cllockowners;
	int	cllocks;
	int	cldelegates;
	int	cllocalopenowners;
	int	cllocalopens;
	int	cllocallockowners;
	int	cllocallocks;
};

#ifdef _KERNEL
/*
 * Define the ext_nfsstats as nfsstats for the kernel code.
 */
#define nfsstats	ext_nfsstats

/*
 * Define NFS_NPROCS as NFSV4_NPROCS for the experimental kernel code.
 */
#ifndef	NFS_NPROCS
#define	NFS_NPROCS		NFSV4_NPROCS
#endif

#include <fs/nfs/nfskpiport.h>
#include <fs/nfs/nfsdport.h>
#include <fs/nfs/rpcv2.h>
#include <fs/nfs/nfsproto.h>
#include <fs/nfs/nfs.h>
#include <fs/nfs/nfs_var.h>
#include <fs/nfs/nfsm_subs.h>
#include <fs/nfs/nfsrvcache.h>
#include <fs/nfs/nfsrvstate.h>
#include <fs/nfs/xdr_subs.h>
#include <fs/nfs/nfscl.h>
#include <fs/nfs/nfsclstate.h>
#include <nfsclient/nfsargs.h>
#include <fs/nfsclient/nfsmount.h>

/*
 * Just to keep nfs_var.h happy.
 */
struct nfs_vattr {
	int	junk;
};

struct nfsvattr {
	struct vattr	na_vattr;
	nfsattrbit_t	na_suppattr;
	u_int32_t	na_mntonfileno;
	u_int64_t	na_filesid[2];
};

#define	na_type		na_vattr.va_type
#define	na_mode		na_vattr.va_mode
#define	na_nlink	na_vattr.va_nlink
#define	na_uid		na_vattr.va_uid
#define	na_gid		na_vattr.va_gid
#define	na_fsid		na_vattr.va_fsid
#define	na_fileid	na_vattr.va_fileid
#define	na_size		na_vattr.va_size
#define	na_blocksize	na_vattr.va_blocksize
#define	na_atime	na_vattr.va_atime
#define	na_mtime	na_vattr.va_mtime
#define	na_ctime	na_vattr.va_ctime
#define	na_gen		na_vattr.va_gen
#define	na_flags	na_vattr.va_flags
#define	na_rdev		na_vattr.va_rdev
#define	na_bytes	na_vattr.va_bytes
#define	na_filerev	na_vattr.va_filerev
#define	na_vaflags	na_vattr.va_vaflags

#include <fs/nfsclient/nfsnode.h>

/*
 * This is the header structure used for the lists, etc. (It has the
 * above record in it.
 */
struct nfsrv_stablefirst {
	LIST_HEAD(, nfsrv_stable) nsf_head;	/* Head of nfsrv_stable list */
	time_t		nsf_eograce;	/* Time grace period ends */
	time_t		*nsf_bootvals;	/* Previous boottime values */
	struct file	*nsf_fp;	/* File table pointer */
	u_char		nsf_flags;	/* NFSNSF_ flags */
	struct nfsf_rec	nsf_rec;	/* and above first record */
};
#define	nsf_lease	nsf_rec.lease
#define	nsf_numboots	nsf_rec.numboots

/* NFSNSF_xxx flags */
#define	NFSNSF_UPDATEDONE	0x01
#define	NFSNSF_GRACEOVER	0x02
#define	NFSNSF_NEEDLOCK		0x04
#define	NFSNSF_EXPIREDCLIENT	0x08
#define	NFSNSF_NOOPENS		0x10
#define	NFSNSF_OK		0x20

/*
 * Maximum number of boot times allowed in record. Although there is
 * really no need for a fixed upper bound, this serves as a sanity check
 * for a corrupted file.
 */
#define	NFSNSF_MAXNUMBOOTS	10000

/*
 * This structure defines the other records in the file. The
 * nst_client array is actually the size of the client string name.
 */
struct nfst_rec {
	u_int16_t	len;
	u_char		flag;
	u_char		client[1];
};
/* and the values for flag */
#define	NFSNST_NEWSTATE	0x1
#define	NFSNST_REVOKE		0x2
#define	NFSNST_GOTSTATE		0x4

/*
 * This structure is linked onto nfsrv_stablefirst for the duration of
 * reclaim.
 */
struct nfsrv_stable {
	LIST_ENTRY(nfsrv_stable) nst_list;
	struct nfsclient	*nst_clp;
	struct nfst_rec		nst_rec;
};
#define	nst_timestamp	nst_rec.timestamp
#define	nst_len		nst_rec.len
#define	nst_flag	nst_rec.flag
#define	nst_client	nst_rec.client

/*
 * At some point the server will run out of kernel storage for
 * state structures. For FreeBSD5.2, this results in a panic
 * kmem_map is full. It happens at well over 1000000 opens plus
 * locks on a PIII-800 with 256Mbytes, so that is where I've set
 * the limit. If your server panics due to too many opens/locks,
 * decrease the size of NFSRV_V4STATELIMIT. If you find the server
 * returning NFS4ERR_RESOURCE a lot and have lots of memory, try
 * increasing it.
 */
#define	NFSRV_V4STATELIMIT	500000	/* Max # of Opens + Locks */

/*
 * The type required differs with BSDen (just the second arg).
 */
void nfsrvd_rcv(struct socket *, void *, int);

/*
 * Macros for handling socket addresses. (Hopefully this makes the code
 * more portable, since I've noticed some 'BSD don't have sockaddrs in
 * mbufs any more.)
 */
#define	NFSSOCKADDR(a, t)	((t)(a))
#define	NFSSOCKADDRALLOC(a) 					\
    do {							\
	MALLOC((a), struct sockaddr *, sizeof (struct sockaddr), \
	    M_SONAME, M_WAITOK); 				\
	NFSBZERO((a), sizeof (struct sockaddr)); 		\
    } while (0)
#define	NFSSOCKADDRSIZE(a, s)		((a)->sa_len = (s))
#define	NFSSOCKADDRFREE(a) 					\
	do { 							\
		if (a) 						\
			FREE((caddr_t)(a), M_SONAME); 		\
	} while (0)

/*
 * These should be defined as a process or thread structure, as required
 * for signal handling, etc.
 */
#define	NFSNEWCRED(c)		(crdup(c))
#define	NFSPROCCRED(p)		((p)->td_ucred)
#define	NFSFREECRED(c)		(crfree(c))
#define	NFSUIOPROC(u, p)	((u)->uio_td = NULL)
#define	NFSPROCP(p)		((p)->td_proc)

/*
 * Define these so that cn_hash and its length is ignored.
 */
#define	NFSCNHASHZERO(c)
#define	NFSCNHASH(c, v)
#define	NCHNAMLEN	9999999

/*
 * Define these to use the time of day clock.
 */
#define	NFSGETTIME(t)		(getmicrotime(t))
#define	NFSGETNANOTIME(t)	(getnanotime(t))

/*
 * These macros are defined to initialize and set the timer routine.
 */
#define	NFS_TIMERINIT \
	newnfs_timer(NULL)

/*
 * Handle SMP stuff:
 */
#define	NFSSTATESPINLOCK	extern struct mtx nfs_state_mutex
#define	NFSLOCKSTATE()		mtx_lock(&nfs_state_mutex)
#define	NFSUNLOCKSTATE()	mtx_unlock(&nfs_state_mutex)
#define	NFSSTATEMUTEXPTR	(&nfs_state_mutex)
#define	NFSREQSPINLOCK		extern struct mtx nfs_req_mutex
#define	NFSLOCKREQ()		mtx_lock(&nfs_req_mutex)
#define	NFSUNLOCKREQ()		mtx_unlock(&nfs_req_mutex)
#define	NFSCACHEMUTEX		extern struct mtx nfs_cache_mutex
#define	NFSCACHEMUTEXPTR	(&nfs_cache_mutex)
#define	NFSLOCKCACHE()		mtx_lock(&nfs_cache_mutex)
#define	NFSUNLOCKCACHE()	mtx_unlock(&nfs_cache_mutex)
#define	NFSCACHELOCKREQUIRED()	mtx_assert(&nfs_cache_mutex, MA_OWNED)
#define	NFSSOCKMUTEX		extern struct mtx nfs_slock_mutex
#define	NFSSOCKMUTEXPTR		(&nfs_slock_mutex)
#define	NFSLOCKSOCK()		mtx_lock(&nfs_slock_mutex)
#define	NFSUNLOCKSOCK()		mtx_unlock(&nfs_slock_mutex)
#define	NFSNAMEIDMUTEX		extern struct mtx nfs_nameid_mutex
#define	NFSLOCKNAMEID()		mtx_lock(&nfs_nameid_mutex)
#define	NFSUNLOCKNAMEID()	mtx_unlock(&nfs_nameid_mutex)
#define	NFSNAMEIDREQUIRED()	mtx_assert(&nfs_nameid_mutex, MA_OWNED)
#define	NFSCLSTATEMUTEX		extern struct mtx nfs_clstate_mutex
#define	NFSCLSTATEMUTEXPTR	(&nfs_clstate_mutex)
#define	NFSLOCKCLSTATE()	mtx_lock(&nfs_clstate_mutex)
#define	NFSUNLOCKCLSTATE()	mtx_unlock(&nfs_clstate_mutex)
#define	NFSDLOCKMUTEX		extern struct mtx newnfsd_mtx
#define	NFSDLOCKMUTEXPTR	(&newnfsd_mtx)
#define	NFSD_LOCK()		mtx_lock(&newnfsd_mtx)
#define	NFSD_UNLOCK()		mtx_unlock(&newnfsd_mtx)
#define	NFSD_LOCK_ASSERT()	mtx_assert(&newnfsd_mtx, MA_OWNED)
#define	NFSD_UNLOCK_ASSERT()	mtx_assert(&newnfsd_mtx, MA_NOTOWNED)
#define	NFSV4ROOTLOCKMUTEX	extern struct mtx nfs_v4root_mutex
#define	NFSV4ROOTLOCKMUTEXPTR	(&nfs_v4root_mutex)
#define	NFSLOCKV4ROOTMUTEX()	mtx_lock(&nfs_v4root_mutex)
#define	NFSUNLOCKV4ROOTMUTEX()	mtx_unlock(&nfs_v4root_mutex)
#define	NFSLOCKNODE(n)		mtx_lock(&((n)->n_mtx))
#define	NFSUNLOCKNODE(n)	mtx_unlock(&((n)->n_mtx))
#define	NFSLOCKMNT(m)		mtx_lock(&((m)->nm_mtx))
#define	NFSUNLOCKMNT(m)		mtx_unlock(&((m)->nm_mtx))
#define	NFSLOCKREQUEST(r)	mtx_lock(&((r)->r_mtx))
#define	NFSUNLOCKREQUEST(r)	mtx_unlock(&((r)->r_mtx))
#define	NFSPROCLISTLOCK()	sx_slock(&allproc_lock)
#define	NFSPROCLISTUNLOCK()	sx_sunlock(&allproc_lock)
#define	NFSLOCKSOCKREQ(r)	mtx_lock(&((r)->nr_mtx))
#define	NFSUNLOCKSOCKREQ(r)	mtx_unlock(&((r)->nr_mtx))

/*
 * Use these macros to initialize/free a mutex.
 */
#define	NFSINITSOCKMUTEX(m)	mtx_init((m), "nfssock", NULL, MTX_DEF)
#define	NFSFREEMUTEX(m)		mtx_destroy((m))

int nfsmsleep(void *, void *, int, const char *, struct timespec *);

/*
 * And weird vm stuff in the nfs server.
 */
#define	PDIRUNLOCK	0x0
#define	MAX_COMMIT_COUNT	(1024 * 1024)

/*
 * Define these to handle the type of va_rdev.
 */
#define	NFSMAKEDEV(m, n)	makedev((m), (n))
#define	NFSMAJOR(d)		major(d)
#define	NFSMINOR(d)		minor(d)

/*
 * Define this to be the macro that returns the minimum size required
 * for a directory entry.
 */
#define	DIRENT_SIZE(dp)		GENERIC_DIRSIZ(dp)

/*
 * The vnode tag for nfsv4root.
 */
#define	VT_NFSV4ROOT		"nfsv4root"

/*
 * Define whatever it takes to do a vn_rdwr().
 */
#define	NFSD_RDWR(r, v, b, l, o, s, i, c, a, p) \
	vn_rdwr((r), (v), (b), (l), (o), (s), (i), (c), NULL, (a), (p))

/*
 * Macros for handling memory for different BSDen.
 * NFSBCOPY(src, dst, len) - copies len bytes, non-overlapping
 * NFSOVBCOPY(src, dst, len) - ditto, but data areas might overlap
 * NFSBCMP(cp1, cp2, len) - compare len bytes, return 0 if same
 * NFSBZERO(cp, len) - set len bytes to 0x0
 */
#define	NFSBCOPY(s, d, l)	bcopy((s), (d), (l))
#define	NFSOVBCOPY(s, d, l)	ovbcopy((s), (d), (l))
#define	NFSBCMP(s, d, l)	bcmp((s), (d), (l))
#define	NFSBZERO(s, l)		bzero((s), (l))

/*
 * Some queue.h files don't have these dfined in them.
 */
#define	LIST_END(head)		NULL
#define	SLIST_END(head)		NULL
#define	TAILQ_END(head)		NULL

/*
 * This must be defined to be a global variable that increments once
 * per second, but never stops or goes backwards, even when a "date"
 * command changes the TOD clock. It is used for delta times for
 * leases, etc.
 */
#define	NFSD_MONOSEC		time_uptime

/*
 * Declare the malloc types.
 */
MALLOC_DECLARE(M_NEWNFSRVCACHE);
MALLOC_DECLARE(M_NEWNFSDCLIENT);
MALLOC_DECLARE(M_NEWNFSDSTATE);
MALLOC_DECLARE(M_NEWNFSDLOCK);
MALLOC_DECLARE(M_NEWNFSDLOCKFILE);
MALLOC_DECLARE(M_NEWNFSSTRING);
MALLOC_DECLARE(M_NEWNFSUSERGROUP);
MALLOC_DECLARE(M_NEWNFSDREQ);
MALLOC_DECLARE(M_NEWNFSFH);
MALLOC_DECLARE(M_NEWNFSCLOWNER);
MALLOC_DECLARE(M_NEWNFSCLOPEN);
MALLOC_DECLARE(M_NEWNFSCLDELEG);
MALLOC_DECLARE(M_NEWNFSCLCLIENT);
MALLOC_DECLARE(M_NEWNFSCLLOCKOWNER);
MALLOC_DECLARE(M_NEWNFSCLLOCK);
MALLOC_DECLARE(M_NEWNFSDIROFF);
MALLOC_DECLARE(M_NEWNFSV4NODE);
MALLOC_DECLARE(M_NEWNFSDIRECTIO);
MALLOC_DECLARE(M_NEWNFSMNT);
MALLOC_DECLARE(M_NEWNFSDROLLBACK);
#define	M_NFSRVCACHE	M_NEWNFSRVCACHE
#define	M_NFSDCLIENT	M_NEWNFSDCLIENT
#define	M_NFSDSTATE	M_NEWNFSDSTATE
#define	M_NFSDLOCK	M_NEWNFSDLOCK
#define	M_NFSDLOCKFILE	M_NEWNFSDLOCKFILE
#define	M_NFSSTRING	M_NEWNFSSTRING
#define	M_NFSUSERGROUP	M_NEWNFSUSERGROUP
#define	M_NFSDREQ	M_NEWNFSDREQ
#define	M_NFSFH		M_NEWNFSFH
#define	M_NFSCLOWNER	M_NEWNFSCLOWNER
#define	M_NFSCLOPEN	M_NEWNFSCLOPEN
#define	M_NFSCLDELEG	M_NEWNFSCLDELEG
#define	M_NFSCLCLIENT	M_NEWNFSCLCLIENT
#define	M_NFSCLLOCKOWNER M_NEWNFSCLLOCKOWNER
#define	M_NFSCLLOCK	M_NEWNFSCLLOCK
#define	M_NFSDIROFF	M_NEWNFSDIROFF
#define	M_NFSV4NODE	M_NEWNFSV4NODE
#define	M_NFSDIRECTIO	M_NEWNFSDIRECTIO
#define	M_NFSDROLLBACK	M_NEWNFSDROLLBACK

#define	NFSINT_SIGMASK(set) 						\
	(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) ||	\
	 SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) ||	\
	 SIGISMEMBER(set, SIGQUIT))

/*
 * Convert a quota block count to byte count.
 */
#define	NFSQUOTABLKTOBYTE(q, b)	(q) *= (b)

/*
 * Define this as the largest file size supported. (It should probably
 * be available via a VFS_xxx Op, but it isn't.
 */
#define	NFSRV_MAXFILESIZE	((u_int64_t)0x800000000000)

/*
 * Set this macro to index() or strchr(), whichever is supported.
 */
#define	STRCHR(s, c)	index((s), (c))

/*
 * Set the n_time in the client write rpc, as required.
 */
#define	NFSWRITERPC_SETTIME(w, n, v4)					\
	do {								\
		if (w) {						\
			(n)->n_mtime = (n)->n_vattr.na_vattr.va_mtime; \
			if (v4)						\
			    (n)->n_change = (n)->n_vattr.na_vattr.va_filerev; \
		}							\
	} while (0)

/*
 * Fake value, just to make the client work.
 */
#define	NFS_LATTR_NOSHRINK	1

/*
 * Prototypes for functions where the arguments vary for different ports.
 */
int nfscl_loadattrcache(struct vnode **, struct nfsvattr *, void *, void *,
    int, int);
void newnfs_realign(struct mbuf **);

/*
 * If the port runs on an SMP box that can enforce Atomic ops with low
 * overheads, define these as atomic increments/decrements. If not,
 * don't worry about it, since these are used for stats that can be
 * "out by one" without disastrous consequences.
 */
#define	NFSINCRGLOBAL(a)	((a)++)

/*
 * Assorted funky stuff to make things work under Darwin8.
 */
/*
 * These macros checks for a field in vattr being set.
 */
#define	NFSATTRISSET(t, v, a)	((v)->a != (t)VNOVAL)
#define	NFSATTRISSETTIME(v, a)	((v)->a.tv_sec != VNOVAL)

/*
 * Manipulate mount flags.
 */
#define	NFSSTA_HASWRITEVERF	0x00040000  /* Has write verifier */
#define	NFSSTA_GOTFSINFO	0x00100000  /* Got the fsinfo */
#define	NFSSTA_TIMEO		0x10000000  /* Experiencing a timeout */
#define	NFSSTA_LOCKTIMEO	0x20000000  /* Experiencing a lockd timeout */
#define	NFSSTA_HASSETFSID	0x40000000  /* Has set the fsid */

#define	NFSHASNFSV3(n)		((n)->nm_flag & NFSMNT_NFSV3)
#define	NFSHASNFSV4(n)		((n)->nm_flag & NFSMNT_NFSV4)
#define	NFSHASNFSV3OR4(n)	((n)->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4))
#define	NFSHASGOTFSINFO(n)	((n)->nm_state & NFSSTA_GOTFSINFO)
#define	NFSHASHASSETFSID(n)	((n)->nm_state & NFSSTA_HASSETFSID)
#define	NFSHASSTRICT3530(n)	((n)->nm_flag & NFSMNT_STRICT3530)
#define	NFSHASWRITEVERF(n)	((n)->nm_state & NFSSTA_HASWRITEVERF)
#define	NFSHASINT(n)		((n)->nm_flag & NFSMNT_INT)
#define	NFSHASSOFT(n)		((n)->nm_flag & NFSMNT_SOFT)
#define	NFSHASINTORSOFT(n)	((n)->nm_flag & (NFSMNT_INT | NFSMNT_SOFT))
#define	NFSHASDUMBTIMR(n)	((n)->nm_flag & NFSMNT_DUMBTIMR)
#define	NFSHASNOCONN(n)		((n)->nm_flag & NFSMNT_MNTD)
#define	NFSHASKERB(n)		((n)->nm_flag & NFSMNT_KERB)
#define	NFSHASALLGSSNAME(n)	((n)->nm_flag & NFSMNT_ALLGSSNAME)
#define	NFSHASINTEGRITY(n)	((n)->nm_flag & NFSMNT_INTEGRITY)
#define	NFSHASPRIVACY(n)	((n)->nm_flag & NFSMNT_PRIVACY)
#define	NFSSETWRITEVERF(n)	((n)->nm_state |= NFSSTA_HASWRITEVERF)
#define	NFSSETHASSETFSID(n)	((n)->nm_state |= NFSSTA_HASSETFSID)

/*
 * Gets the stats field out of the mount structure.
 */
#define	vfs_statfs(m)	(&((m)->mnt_stat))

/*
 * Set boottime.
 */
#define	NFSSETBOOTTIME(b)	((b) = boottime)

/*
 * The size of directory blocks in the buffer cache.
 * MUST BE in the range of PAGE_SIZE <= NFS_DIRBLKSIZ <= MAXBSIZE!!
 */
#define	NFS_DIRBLKSIZ	(16 * DIRBLKSIZ) /* Must be a multiple of DIRBLKSIZ */

/*
 * Define these macros to access mnt_flag fields.
 */
#define	NFSMNT_RDONLY(m)	((m)->mnt_flag & MNT_RDONLY)
#endif	/* _KERNEL */

/*
 * Define a structure similar to ufs_args for use in exporting the V4 root.
 */
struct nfsex_args {
	char	*fspec;
	struct export_args	export;
};

/*
 * These export flags should be defined, but there are no bits left.
 * Maybe a separate mnt_exflag field could be added or the mnt_flag
 * field increased to 64 bits?
 */
#ifndef	MNT_EXSTRICTACCESS
#define	MNT_EXSTRICTACCESS	0x0
#endif
#ifndef MNT_EXV4ONLY
#define	MNT_EXV4ONLY		0x0
#endif

#ifdef _KERNEL
/*
 * Define this to invalidate the attribute cache for the nfs node.
 */
#define	NFSINVALATTRCACHE(n)	((n)->n_attrstamp = 0)

/* Used for FreeBSD only */
void nfsd_mntinit(void);

/*
 * Define these for vnode lock/unlock ops.
 *
 * These are good abstractions to macro out, so that they can be added to
 * later, for debugging or stats, etc.
 */
#define	NFSVOPLOCK(v, f)	vn_lock((v), (f))
#define	NFSVOPUNLOCK(v, f)	VOP_UNLOCK((v), (f))
#define	NFSVOPISLOCKED(v)	VOP_ISLOCKED((v))

/*
 * Define ncl_hash().
 */
#define	ncl_hash(f, l)	(fnv_32_buf((f), (l), FNV1_32_INIT))

int newnfs_iosize(struct nfsmount *);

#ifdef NFS_DEBUG

extern int nfs_debug;
#define	NFS_DEBUG_ASYNCIO	1 /* asynchronous i/o */
#define	NFS_DEBUG_WG		2 /* server write gathering */
#define	NFS_DEBUG_RC		4 /* server request caching */

#define	NFS_DPF(cat, args)					\
	do {							\
		if (nfs_debug & NFS_DEBUG_##cat) printf args;	\
	} while (0)

#else

#define	NFS_DPF(cat, args)

#endif

int newnfs_vncmpf(struct vnode *, void *);

#ifndef NFS_MINDIRATTRTIMO
#define	NFS_MINDIRATTRTIMO 3		/* VDIR attrib cache timeout in sec */
#endif
#ifndef NFS_MAXDIRATTRTIMO
#define	NFS_MAXDIRATTRTIMO 60
#endif

/*
 * Nfs outstanding request list element
 */
struct nfsreq {
	TAILQ_ENTRY(nfsreq) r_chain;
	u_int32_t	r_flags;	/* flags on request, see below */
	struct nfsmount *r_nmp;		/* Client mnt ptr */
	struct mtx	r_mtx;		/* Mutex lock for this structure */
};

#ifndef NFS_MAXBSIZE
#define	NFS_MAXBSIZE	MAXBSIZE
#endif

/*
 * This macro checks to see if issuing of delegations is allowed for this
 * vnode.
 */
#ifdef VV_DISABLEDELEG
#define	NFSVNO_DELEGOK(v)						\
	((v) == NULL || ((v)->v_vflag & VV_DISABLEDELEG) == 0)
#else
#define	NFSVNO_DELEGOK(v)	(1)
#endif

/*
 * Define this as the flags argument for msleep() when catching signals
 * while holding a resource that other threads would block for, such as
 * a vnode lock.
 */
#define	NFS_PCATCH	(PCATCH | PBDRY)

#endif	/* _KERNEL */

#endif	/* _NFS_NFSPORT_H */