| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-3-Clause |
| 3 | * |
| 4 | * Copyright (c) 1989, 1993, 1995 |
| 5 | *	The Regents of the University of California. All rights reserved. |
| 6 | * |
| 7 | * This code is derived from software contributed to Berkeley by |
| 8 | * Rick Macklem at The University of Guelph. |
| 9 | * |
| 10 | * Redistribution and use in source and binary forms, with or without |
| 11 | * modification, are permitted provided that the following conditions |
| 12 | * are met: |
| 13 | * 1. Redistributions of source code must retain the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer. |
| 15 | * 2. Redistributions in binary form must reproduce the above copyright |
| 16 | * notice, this list of conditions and the following disclaimer in the |
| 17 | * documentation and/or other materials provided with the distribution. |
| 18 | * 3. Neither the name of the University nor the names of its contributors |
| 19 | * may be used to endorse or promote products derived from this software |
| 20 | * without specific prior written permission. |
| 21 | * |
| 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | * SUCH DAMAGE. |
| 33 | */ |
| 34 | |
| 35 | #ifndef _NFSCLIENT_NFS_H_ |
| 36 | #define _NFSCLIENT_NFS_H_ |
| 37 | |
| 38 | #ifdef _KERNEL |
| 39 | #include "opt_nfs.h" |
| 40 | #endif |
| 41 | |
| 42 | #include <nfsclient/nfsargs.h> |
| 43 | |
| 44 | /* |
| 45 | * Tunable constants for nfs |
| 46 | */ |
| 47 | |
| 48 | #define NFS_TICKINTVL	10		/* Desired time for a tick (msec) */ |
| 49 | #define NFS_HZ		(hz / nfs_ticks) /* Ticks/sec */ |
| 50 | #define	NFS_TIMEO	(1 * NFS_HZ)	/* Default timeout = 1 second */ |
| 51 | #define	NFS_MINTIMEO	(1 * NFS_HZ)	/* Min timeout to use */ |
| 52 | #define	NFS_MAXTIMEO	(60 * NFS_HZ)	/* Max timeout to backoff to */ |
| 53 | #define	NFS_MINIDEMTIMEO (5 * NFS_HZ)	/* Min timeout for non-idempotent ops*/ |
| 54 | #define	NFS_MAXREXMIT	100		/* Stop counting after this many */ |
| 55 | #define	NFS_RETRANS	10		/* Num of retrans for UDP soft mounts */ |
| 56 | #define	NFS_RETRANS_TCP	2		/* Num of retrans for TCP soft mounts */ |
| 57 | #define	NFS_MAXGRPS	16		/* Max. size of groups list */ |
| 58 | #ifndef NFS_MINATTRTIMO |
| 59 | #define	NFS_MINATTRTIMO 3		/* VREG attrib cache timeout in sec */ |
| 60 | #endif |
| 61 | #ifndef NFS_MAXATTRTIMO |
| 62 | #define	NFS_MAXATTRTIMO 60 |
| 63 | #endif |
| 64 | #ifndef NFS_MINDIRATTRTIMO |
| 65 | #define	NFS_MINDIRATTRTIMO 3		/* VDIR attrib cache timeout in sec */ |
| 66 | #endif |
| 67 | #ifndef NFS_MAXDIRATTRTIMO |
| 68 | #define	NFS_MAXDIRATTRTIMO 60 |
| 69 | #endif |
| 70 | #ifndef	NFS_ACCESSCACHESIZE |
| 71 | #define	NFS_ACCESSCACHESIZE 8		/* Per-node access cache entries */ |
| 72 | #endif |
| 73 | #define	NFS_WSIZE	8192		/* Def. write data size <= 8192 */ |
| 74 | #define	NFS_RSIZE	8192		/* Def. read data size <= 8192 */ |
| 75 | #define NFS_READDIRSIZE	8192		/* Def. readdir size */ |
| 76 | #define	NFS_DEFRAHEAD	1		/* Def. read ahead # blocks */ |
| 77 | #define	NFS_MAXRAHEAD	4		/* Max. read ahead # blocks */ |
| 78 | #define	NFS_MAXASYNCDAEMON 	64	/* Max. number async_daemons runnable */ |
| 79 | #define	NFS_DIRBLKSIZ	4096		/* Must be a multiple of DIRBLKSIZ */ |
| 80 | #ifdef _KERNEL |
| 81 | #define	DIRBLKSIZ	512		/* XXX we used to use ufs's DIRBLKSIZ */ |
| 82 | #endif |
| 83 | #define NFS_MAXDEADTHRESH	9	/* How long till we say 'server not responding' */ |
| 84 | |
| 85 | /* |
| 86 | * Oddballs |
| 87 | */ |
| 88 | #define NFS_CMPFH(n, f, s) \ |
| 89 | 	((n)->n_fhsize == (s) && !bcmp((caddr_t)(n)->n_fhp, (caddr_t)(f), (s))) |
| 90 | #define NFS_ISV3(v)	(VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV3) |
| 91 | #define NFS_ISV4(v)	(VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV4) |
| 92 | |
| 93 | #define NFSSTA_HASWRITEVERF	0x00040000 /* Has write verifier for V3 */ |
| 94 | #define NFSSTA_GOTFSINFO	0x00100000 /* Got the V3 fsinfo */ |
| 95 | #define	NFSSTA_SNDLOCK		0x01000000 /* Send socket lock */ |
| 96 | #define	NFSSTA_WANTSND		0x02000000 /* Want above */ |
| 97 | #define	NFSSTA_TIMEO		0x10000000 /* Experiencing a timeout */ |
| 98 | #define	NFSSTA_LOCKTIMEO	0x20000000 /* Experiencing a lockd timeout */ |
| 99 | |
| 100 | /* |
| 101 | * XXX to allow amd to include nfs.h without nfsproto.h |
| 102 | */ |
| 103 | #ifdef NFS_NPROCS |
| 104 | #include <nfsclient/nfsstats.h> |
| 105 | #endif |
| 106 | |
| 107 | /* |
| 108 | * vfs.oldnfs sysctl(3) identifiers |
| 109 | */ |
| 110 | #define NFS_NFSSTATS	1		/* struct: struct nfsstats */ |
| 111 | |
| 112 | #ifdef _KERNEL |
| 113 | |
| 114 | #ifdef MALLOC_DECLARE |
| 115 | MALLOC_DECLARE(M_NFSDIROFF); |
| 116 | MALLOC_DECLARE(M_NFSDIRECTIO); |
| 117 | #endif |
| 118 | |
| 119 | extern struct uma_zone *nfsmount_zone; |
| 120 | |
| 121 | extern struct nfsstats nfsstats; |
| 122 | extern struct mtx nfs_iod_mtx; |
| 123 | extern struct task nfs_nfsiodnew_task; |
| 124 | |
| 125 | extern int nfs_numasync; |
| 126 | extern unsigned int nfs_iodmax; |
| 127 | extern int nfs_pbuf_freecnt; |
| 128 | extern int nfs_ticks; |
| 129 | |
| 130 | /* Data constants in XDR form */ |
| 131 | extern u_int32_t nfs_true, nfs_false, nfs_xdrneg1; |
| 132 | extern u_int32_t rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers; |
| 133 | extern u_int32_t rpc_auth_unix, rpc_msgaccepted, rpc_call, rpc_autherr; |
| 134 | |
| 135 | extern int nfsv3_procid[NFS_NPROCS]; |
| 136 | |
| 137 | /* |
| 138 | * Socket errors ignored for connectionless sockets?? |
| 139 | * For now, ignore them all |
| 140 | */ |
| 141 | #define	NFSIGNORE_SOERROR(s, e) \ |
| 142 | 		((e) != EINTR && (e) != EIO && \ |
| 143 | 		(e) != ERESTART && (e) != EWOULDBLOCK && \ |
| 144 | 		((s) & PR_CONNREQUIRED) == 0) |
| 145 | |
| 146 | struct nfsmount; |
| 147 | |
| 148 | struct buf; |
| 149 | struct socket; |
| 150 | struct uio; |
| 151 | struct vattr; |
| 152 | |
| 153 | /* |
| 154 | * Pointers to ops that differ from v3 to v4 |
| 155 | */ |
| 156 | struct nfs_rpcops { |
| 157 | 	int	(*nr_readrpc)(struct vnode *vp, struct uio *uiop, |
| 158 | 		 struct ucred *cred); |
| 159 | 	int	(*nr_writerpc)(struct vnode *vp, struct uio *uiop, |
| 160 | 		 struct ucred *cred, int *iomode, int *must_commit); |
| 161 | 	int	(*nr_writebp)(struct buf *bp, int force, struct thread *td); |
| 162 | 	int	(*nr_readlinkrpc)(struct vnode *vp, struct uio *uiop, |
| 163 | 		 struct ucred *cred); |
| 164 | 	void	(*nr_invaldir)(struct vnode *vp); |
| 165 | 	int	(*nr_commit)(struct vnode *vp, u_quad_t offset, int cnt, |
| 166 | 		 struct ucred *cred, struct thread *td); |
| 167 | }; |
| 168 | |
| 169 | /* |
| 170 | * Defines for WebNFS |
| 171 | */ |
| 172 | |
| 173 | #define WEBNFS_ESC_CHAR		'%' |
| 174 | #define WEBNFS_SPECCHAR_START	0x80 |
| 175 | |
| 176 | #define WEBNFS_NATIVE_CHAR	0x80 |
| 177 | /* |
| 178 | * .. |
| 179 | * Possibly more here in the future. |
| 180 | */ |
| 181 | |
| 182 | /* |
| 183 | * Macro for converting escape characters in WebNFS pathnames. |
| 184 | * Should really be in libkern. |
| 185 | */ |
| 186 | |
| 187 | #define HEXTOC(c) \ |
| 188 | 	((c) >= 'a' ? ((c) - ('a' - 10)) : \ |
| 189 | 	 ((c) >= 'A' ? ((c) - ('A' - 10)) : ((c) - '0'))) |
| 190 | #define HEXSTRTOI(p) \ |
| 191 | 	((HEXTOC(p[0]) << 4) + HEXTOC(p[1])) |
| 192 | |
| 193 | /* nfs_sigintr() helper, when 'rep' has all we need */ |
| 194 | #define NFS_SIGREP(rep)		nfs_sigintr((rep)->r_nmp, (rep), (rep)->r_td) |
| 195 | |
| 196 | #ifdef NFS_DEBUG |
| 197 | |
| 198 | extern int nfs_debug; |
| 199 | #define NFS_DEBUG_ASYNCIO	1 /* asynchronous i/o */ |
| 200 | #define NFS_DEBUG_WG		2 /* server write gathering */ |
| 201 | #define NFS_DEBUG_RC		4 /* server request caching */ |
| 202 | |
| 203 | #define NFS_DPF(cat, args)					\ |
| 204 | 	do {							\ |
| 205 | 		if (nfs_debug & NFS_DEBUG_##cat) printf args;	\ |
| 206 | 	} while (0) |
| 207 | |
| 208 | #else |
| 209 | |
| 210 | #define NFS_DPF(cat, args) |
| 211 | |
| 212 | #endif |
| 213 | |
| 214 | /* |
| 215 | * On fast networks, the estimator will try to reduce the |
| 216 | * timeout lower than the latency of the server's disks, |
| 217 | * which results in too many timeouts, so cap the lower |
| 218 | * bound. |
| 219 | */ |
| 220 | #define NFS_MINRTO	(NFS_HZ >> 2) |
| 221 | |
| 222 | /* |
| 223 | * Keep the RTO from increasing to unreasonably large values |
| 224 | * when a server is not responding. |
| 225 | */ |
| 226 | #define NFS_MAXRTO	(20 * NFS_HZ) |
| 227 | |
| 228 | enum nfs_rto_timer_t { |
| 229 | 	NFS_DEFAULT_TIMER, |
| 230 | 	NFS_GETATTR_TIMER, |
| 231 | 	NFS_LOOKUP_TIMER, |
| 232 | 	NFS_READ_TIMER, |
| 233 | 	NFS_WRITE_TIMER, |
| 234 | }; |
| 235 | #define NFS_MAX_TIMER	(NFS_WRITE_TIMER) |
| 236 | |
| 237 | #define NFS_INITRTT	(NFS_HZ << 3) |
| 238 | |
| 239 | vfs_init_t nfs_init; |
| 240 | vfs_uninit_t nfs_uninit; |
| 241 | int	nfs_mountroot(struct mount *mp); |
| 242 | |
| 243 | void	nfs_purgecache(struct vnode *); |
| 244 | int	nfs_vinvalbuf(struct vnode *, int, struct thread *, int); |
| 245 | int	nfs_readrpc(struct vnode *, struct uio *, struct ucred *); |
| 246 | int	nfs_writerpc(struct vnode *, struct uio *, struct ucred *, int *, |
| 247 | 	 int *); |
| 248 | int	nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, |
| 249 | 	 struct ucred *cred, struct thread *td); |
| 250 | int	nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *); |
| 251 | void	nfs_nfsiodnew(void); |
| 252 | void	nfs_nfsiodnew_tq(__unused void *, int); |
| 253 | int	nfs_asyncio(struct nfsmount *, struct buf *, struct ucred *, struct thread *); |
| 254 | int	nfs_doio(struct vnode *, struct buf *, struct ucred *, struct thread *); |
| 255 | void	nfs_doio_directwrite (struct buf *); |
| 256 | int	nfs_readlinkrpc(struct vnode *, struct uio *, struct ucred *); |
| 257 | int	nfs_sigintr(struct nfsmount *, struct thread *); |
| 258 | int	nfs_readdirplusrpc(struct vnode *, struct uio *, struct ucred *); |
| 259 | int	nfs_request(struct vnode *, struct mbuf *, int, struct thread *, |
| 260 | 	 struct ucred *, struct mbuf **, struct mbuf **, caddr_t *); |
| 261 | int	nfs_loadattrcache(struct vnode **, struct mbuf **, caddr_t *, |
| 262 | 	 struct vattr *, int); |
| 263 | int	nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *); |
| 264 | void	nfs_nhinit(void); |
| 265 | void	nfs_nhuninit(void); |
| 266 | int	nfs_nmcancelreqs(struct nfsmount *); |
| 267 | void	nfs_timer(void*); |
| 268 | |
| 269 | int	nfs_connect(struct nfsmount *); |
| 270 | void	nfs_disconnect(struct nfsmount *); |
| 271 | void	nfs_safedisconnect(struct nfsmount *); |
| 272 | int	nfs_getattrcache(struct vnode *, struct vattr *); |
| 273 | int	nfs_iosize(struct nfsmount *nmp); |
| 274 | int	nfsm_strtmbuf(struct mbuf **, char **, const char *, long); |
| 275 | int	nfs_bioread(struct vnode *, struct uio *, int, struct ucred *); |
| 276 | int	nfsm_uiotombuf(struct uio *, struct mbuf **, int, caddr_t *); |
| 277 | void	nfs_clearcommit(struct mount *); |
| 278 | int	nfs_writebp(struct buf *, int, struct thread *); |
| 279 | int	nfs_fsinfo(struct nfsmount *, struct vnode *, struct ucred *, |
| 280 | 	 struct thread *); |
| 281 | int	nfs_meta_setsize (struct vnode *, struct ucred *, |
| 282 | 	 struct thread *, u_quad_t); |
| 283 | |
| 284 | void	nfs_set_sigmask(struct thread *td, sigset_t *oldset); |
| 285 | void	nfs_restore_sigmask(struct thread *td, sigset_t *set); |
| 286 | int	nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, |
| 287 | 	 int priority, char *wmesg, int timo); |
| 288 | |
| 289 | #endif	/* _KERNEL */ |
| 290 | |
| 291 | #endif |