1df8bae1dSRodney W. Grimes /* 2df8bae1dSRodney W. Grimes * Copyright (c) 1989, 1993 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * 5df8bae1dSRodney W. Grimes * This code is derived from software contributed 6df8bae1dSRodney W. Grimes * to Berkeley by John Heidemann of the UCLA Ficus project. 7df8bae1dSRodney W. Grimes * 8df8bae1dSRodney W. Grimes * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 19df8bae1dSRodney W. Grimes * must display the following acknowledgement: 20df8bae1dSRodney W. Grimes * This product includes software developed by the University of 21df8bae1dSRodney W. Grimes * California, Berkeley and its contributors. 22df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 23df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 24df8bae1dSRodney W. Grimes * without specific prior written permission. 25df8bae1dSRodney W. Grimes * 26df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36df8bae1dSRodney W. Grimes * SUCH DAMAGE. 37df8bae1dSRodney W. Grimes * 38df8bae1dSRodney W. Grimes * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94 392b14f991SJulian Elischer * $Id: vfs_init.c,v 1.10 1995/05/30 08:06:32 rgrimes Exp $ 40df8bae1dSRodney W. Grimes */ 41df8bae1dSRodney W. Grimes 42df8bae1dSRodney W. Grimes 43df8bae1dSRodney W. Grimes #include <sys/param.h> 44f23b4c91SGarrett Wollman #include <sys/systm.h> 45c901836cSGarrett Wollman #include <sys/kernel.h> 46df8bae1dSRodney W. Grimes #include <sys/mount.h> 47df8bae1dSRodney W. Grimes #include <sys/time.h> 48df8bae1dSRodney W. Grimes #include <sys/vnode.h> 49df8bae1dSRodney W. Grimes #include <sys/stat.h> 50df8bae1dSRodney W. Grimes #include <sys/namei.h> 51df8bae1dSRodney W. Grimes #include <sys/ucred.h> 52df8bae1dSRodney W. Grimes #include <sys/buf.h> 53df8bae1dSRodney W. Grimes #include <sys/errno.h> 54df8bae1dSRodney W. Grimes #include <sys/malloc.h> 55c901836cSGarrett Wollman #include <sys/proc.h> 56c901836cSGarrett Wollman #include <vm/vm.h> 57c901836cSGarrett Wollman #include <sys/sysctl.h> 58df8bae1dSRodney W. Grimes 59df8bae1dSRodney W. Grimes /* 602b14f991SJulian Elischer * System initialization 612b14f991SJulian Elischer */ 622b14f991SJulian Elischer 632b14f991SJulian Elischer static void vfsinit __P((caddr_t)); 642b14f991SJulian Elischer SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vfsinit, NULL) 652b14f991SJulian Elischer 662b14f991SJulian Elischer /* 67df8bae1dSRodney W. Grimes * Sigh, such primitive tools are these... 68df8bae1dSRodney W. Grimes */ 69df8bae1dSRodney W. Grimes #if 0 70df8bae1dSRodney W. Grimes #define DODEBUG(A) A 71df8bae1dSRodney W. Grimes #else 72df8bae1dSRodney W. Grimes #define DODEBUG(A) 73df8bae1dSRodney W. Grimes #endif 74df8bae1dSRodney W. Grimes 75c901836cSGarrett Wollman struct vfsconf void_vfsconf; 76c901836cSGarrett Wollman 77c901836cSGarrett Wollman extern struct linker_set vfs_opv_descs_; 78c901836cSGarrett Wollman #define vfs_opv_descs ((struct vnodeopv_desc **)vfs_opv_descs_.ls_items) 79c901836cSGarrett Wollman 80c901836cSGarrett Wollman extern struct linker_set vfs_set; 81c901836cSGarrett Wollman struct vfsops *vfssw[MOUNT_MAXTYPE + 1]; 82c901836cSGarrett Wollman struct vfsconf *vfsconf[MOUNT_MAXTYPE + 1]; 83c901836cSGarrett Wollman 84df8bae1dSRodney W. Grimes extern struct vnodeop_desc *vfs_op_descs[]; 85df8bae1dSRodney W. Grimes /* and the operations they perform */ 86df8bae1dSRodney W. Grimes /* 87df8bae1dSRodney W. Grimes * This code doesn't work if the defn is **vnodop_defns with cc. 88df8bae1dSRodney W. Grimes * The problem is because of the compiler sometimes putting in an 89df8bae1dSRodney W. Grimes * extra level of indirection for arrays. It's an interesting 90df8bae1dSRodney W. Grimes * "feature" of C. 91df8bae1dSRodney W. Grimes */ 92df8bae1dSRodney W. Grimes int vfs_opv_numops; 93df8bae1dSRodney W. Grimes 94c901836cSGarrett Wollman typedef int (*PFI)(); /* the standard Pointer to a Function returning an Int */ 95df8bae1dSRodney W. Grimes 96df8bae1dSRodney W. Grimes /* 97df8bae1dSRodney W. Grimes * A miscellaneous routine. 98df8bae1dSRodney W. Grimes * A generic "default" routine that just returns an error. 99df8bae1dSRodney W. Grimes */ 100df8bae1dSRodney W. Grimes int 101df8bae1dSRodney W. Grimes vn_default_error() 102df8bae1dSRodney W. Grimes { 103df8bae1dSRodney W. Grimes 104df8bae1dSRodney W. Grimes return (EOPNOTSUPP); 105df8bae1dSRodney W. Grimes } 106df8bae1dSRodney W. Grimes 107df8bae1dSRodney W. Grimes /* 108df8bae1dSRodney W. Grimes * vfs_init.c 109df8bae1dSRodney W. Grimes * 110df8bae1dSRodney W. Grimes * Allocate and fill in operations vectors. 111df8bae1dSRodney W. Grimes * 112df8bae1dSRodney W. Grimes * An undocumented feature of this approach to defining operations is that 113df8bae1dSRodney W. Grimes * there can be multiple entries in vfs_opv_descs for the same operations 114df8bae1dSRodney W. Grimes * vector. This allows third parties to extend the set of operations 115df8bae1dSRodney W. Grimes * supported by another layer in a binary compatibile way. For example, 116df8bae1dSRodney W. Grimes * assume that NFS needed to be modified to support Ficus. NFS has an entry 117df8bae1dSRodney W. Grimes * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by 118df8bae1dSRodney W. Grimes * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions) 119df8bae1dSRodney W. Grimes * listing those new operations Ficus adds to NFS, all without modifying the 120df8bae1dSRodney W. Grimes * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but 121df8bae1dSRodney W. Grimes * that is a(whole)nother story.) This is a feature. 122df8bae1dSRodney W. Grimes */ 123df8bae1dSRodney W. Grimes void 124c901836cSGarrett Wollman vfs_opv_init(struct vnodeopv_desc **them) 125df8bae1dSRodney W. Grimes { 126df8bae1dSRodney W. Grimes int i, j, k; 127df8bae1dSRodney W. Grimes int (***opv_desc_vector_p)(); 128df8bae1dSRodney W. Grimes int (**opv_desc_vector)(); 129df8bae1dSRodney W. Grimes struct vnodeopv_entry_desc *opve_descp; 130df8bae1dSRodney W. Grimes 131df8bae1dSRodney W. Grimes /* 132df8bae1dSRodney W. Grimes * Allocate the dynamic vectors and fill them in. 133df8bae1dSRodney W. Grimes */ 134c901836cSGarrett Wollman for (i=0; them[i]; i++) { 135c901836cSGarrett Wollman opv_desc_vector_p = them[i]->opv_desc_vector_p; 136df8bae1dSRodney W. Grimes /* 137df8bae1dSRodney W. Grimes * Allocate and init the vector, if it needs it. 138df8bae1dSRodney W. Grimes * Also handle backwards compatibility. 139df8bae1dSRodney W. Grimes */ 140df8bae1dSRodney W. Grimes if (*opv_desc_vector_p == NULL) { 141df8bae1dSRodney W. Grimes /* XXX - shouldn't be M_VNODE */ 142df8bae1dSRodney W. Grimes MALLOC(*opv_desc_vector_p, PFI*, 143df8bae1dSRodney W. Grimes vfs_opv_numops*sizeof(PFI), M_VNODE, M_WAITOK); 144df8bae1dSRodney W. Grimes bzero (*opv_desc_vector_p, vfs_opv_numops*sizeof(PFI)); 145df8bae1dSRodney W. Grimes DODEBUG(printf("vector at %x allocated\n", 146df8bae1dSRodney W. Grimes opv_desc_vector_p)); 147df8bae1dSRodney W. Grimes } 148df8bae1dSRodney W. Grimes opv_desc_vector = *opv_desc_vector_p; 149c901836cSGarrett Wollman for (j=0; them[i]->opv_desc_ops[j].opve_op; j++) { 150c901836cSGarrett Wollman opve_descp = &(them[i]->opv_desc_ops[j]); 151df8bae1dSRodney W. Grimes 152df8bae1dSRodney W. Grimes /* 153df8bae1dSRodney W. Grimes * Sanity check: is this operation listed 154df8bae1dSRodney W. Grimes * in the list of operations? We check this 155df8bae1dSRodney W. Grimes * by seeing if its offest is zero. Since 156df8bae1dSRodney W. Grimes * the default routine should always be listed 157df8bae1dSRodney W. Grimes * first, it should be the only one with a zero 158df8bae1dSRodney W. Grimes * offset. Any other operation with a zero 159df8bae1dSRodney W. Grimes * offset is probably not listed in 160df8bae1dSRodney W. Grimes * vfs_op_descs, and so is probably an error. 161df8bae1dSRodney W. Grimes * 162df8bae1dSRodney W. Grimes * A panic here means the layer programmer 163df8bae1dSRodney W. Grimes * has committed the all-too common bug 164df8bae1dSRodney W. Grimes * of adding a new operation to the layer's 165df8bae1dSRodney W. Grimes * list of vnode operations but 166df8bae1dSRodney W. Grimes * not adding the operation to the system-wide 167df8bae1dSRodney W. Grimes * list of supported operations. 168df8bae1dSRodney W. Grimes */ 169df8bae1dSRodney W. Grimes if (opve_descp->opve_op->vdesc_offset == 0 && 170df8bae1dSRodney W. Grimes opve_descp->opve_op->vdesc_offset != 171df8bae1dSRodney W. Grimes VOFFSET(vop_default)) { 172df8bae1dSRodney W. Grimes printf("operation %s not listed in %s.\n", 173df8bae1dSRodney W. Grimes opve_descp->opve_op->vdesc_name, 174df8bae1dSRodney W. Grimes "vfs_op_descs"); 175df8bae1dSRodney W. Grimes panic ("vfs_opv_init: bad operation"); 176df8bae1dSRodney W. Grimes } 177df8bae1dSRodney W. Grimes /* 178df8bae1dSRodney W. Grimes * Fill in this entry. 179df8bae1dSRodney W. Grimes */ 180df8bae1dSRodney W. Grimes opv_desc_vector[opve_descp->opve_op->vdesc_offset] = 181df8bae1dSRodney W. Grimes opve_descp->opve_impl; 182df8bae1dSRodney W. Grimes } 183df8bae1dSRodney W. Grimes } 184df8bae1dSRodney W. Grimes /* 185df8bae1dSRodney W. Grimes * Finally, go back and replace unfilled routines 186df8bae1dSRodney W. Grimes * with their default. (Sigh, an O(n^3) algorithm. I 187df8bae1dSRodney W. Grimes * could make it better, but that'd be work, and n is small.) 188df8bae1dSRodney W. Grimes */ 189c901836cSGarrett Wollman for (i = 0; them[i]; i++) { 190c901836cSGarrett Wollman opv_desc_vector = *(them[i]->opv_desc_vector_p); 191df8bae1dSRodney W. Grimes /* 192df8bae1dSRodney W. Grimes * Force every operations vector to have a default routine. 193df8bae1dSRodney W. Grimes */ 194df8bae1dSRodney W. Grimes if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { 195df8bae1dSRodney W. Grimes panic("vfs_opv_init: operation vector without default routine."); 196df8bae1dSRodney W. Grimes } 197df8bae1dSRodney W. Grimes for (k = 0; k<vfs_opv_numops; k++) 198df8bae1dSRodney W. Grimes if (opv_desc_vector[k] == NULL) 199df8bae1dSRodney W. Grimes opv_desc_vector[k] = 200df8bae1dSRodney W. Grimes opv_desc_vector[VOFFSET(vop_default)]; 201df8bae1dSRodney W. Grimes } 202df8bae1dSRodney W. Grimes } 203df8bae1dSRodney W. Grimes 204df8bae1dSRodney W. Grimes /* 205df8bae1dSRodney W. Grimes * Initialize known vnode operations vectors. 206df8bae1dSRodney W. Grimes */ 207df8bae1dSRodney W. Grimes void 208df8bae1dSRodney W. Grimes vfs_op_init() 209df8bae1dSRodney W. Grimes { 210df8bae1dSRodney W. Grimes int i; 211df8bae1dSRodney W. Grimes 212df8bae1dSRodney W. Grimes DODEBUG(printf("Vnode_interface_init.\n")); 213df8bae1dSRodney W. Grimes /* 214df8bae1dSRodney W. Grimes * Set all vnode vectors to a well known value. 215df8bae1dSRodney W. Grimes */ 216df8bae1dSRodney W. Grimes for (i = 0; vfs_opv_descs[i]; i++) 217df8bae1dSRodney W. Grimes *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL; 218df8bae1dSRodney W. Grimes /* 219df8bae1dSRodney W. Grimes * Figure out how many ops there are by counting the table, 220df8bae1dSRodney W. Grimes * and assign each its offset. 221df8bae1dSRodney W. Grimes */ 222df8bae1dSRodney W. Grimes for (vfs_opv_numops = 0, i = 0; vfs_op_descs[i]; i++) { 223df8bae1dSRodney W. Grimes vfs_op_descs[i]->vdesc_offset = vfs_opv_numops; 224df8bae1dSRodney W. Grimes vfs_opv_numops++; 225df8bae1dSRodney W. Grimes } 226df8bae1dSRodney W. Grimes DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops)); 227df8bae1dSRodney W. Grimes } 228df8bae1dSRodney W. Grimes 229df8bae1dSRodney W. Grimes /* 230df8bae1dSRodney W. Grimes * Routines having to do with the management of the vnode table. 231df8bae1dSRodney W. Grimes */ 232df8bae1dSRodney W. Grimes extern struct vnodeops dead_vnodeops; 233df8bae1dSRodney W. Grimes extern struct vnodeops spec_vnodeops; 234df8bae1dSRodney W. Grimes extern void vclean(); 235df8bae1dSRodney W. Grimes struct vattr va_null; 236df8bae1dSRodney W. Grimes 237df8bae1dSRodney W. Grimes /* 238df8bae1dSRodney W. Grimes * Initialize the vnode structures and initialize each file system type. 239df8bae1dSRodney W. Grimes */ 2402b14f991SJulian Elischer /* ARGSUSED*/ 2412b14f991SJulian Elischer static void 2422b14f991SJulian Elischer vfsinit( udata) 2432b14f991SJulian Elischer caddr_t udata; /* not used*/ 244df8bae1dSRodney W. Grimes { 245df8bae1dSRodney W. Grimes struct vfsops **vfsp; 246c901836cSGarrett Wollman struct vfsconf **vfc; 247c901836cSGarrett Wollman int i; 248c901836cSGarrett Wollman 249c901836cSGarrett Wollman /* 250c901836cSGarrett Wollman * Initialize the VFS switch table 251c901836cSGarrett Wollman */ 252c901836cSGarrett Wollman for(i = 0; i < MOUNT_MAXTYPE + 1; i++) { 253c901836cSGarrett Wollman vfsconf[i] = &void_vfsconf; 254c901836cSGarrett Wollman } 255c901836cSGarrett Wollman 256c901836cSGarrett Wollman vfc = (struct vfsconf **)vfs_set.ls_items; 257c901836cSGarrett Wollman while(*vfc) { 258c901836cSGarrett Wollman vfssw[(**vfc).vfc_index] = (**vfc).vfc_vfsops; 259c901836cSGarrett Wollman vfsconf[(**vfc).vfc_index] = *vfc; 260c901836cSGarrett Wollman vfc++; 261c901836cSGarrett Wollman } 262df8bae1dSRodney W. Grimes 263df8bae1dSRodney W. Grimes /* 264df8bae1dSRodney W. Grimes * Initialize the vnode table 265df8bae1dSRodney W. Grimes */ 266df8bae1dSRodney W. Grimes vntblinit(); 267df8bae1dSRodney W. Grimes /* 268df8bae1dSRodney W. Grimes * Initialize the vnode name cache 269df8bae1dSRodney W. Grimes */ 270df8bae1dSRodney W. Grimes nchinit(); 271df8bae1dSRodney W. Grimes /* 272df8bae1dSRodney W. Grimes * Build vnode operation vectors. 273df8bae1dSRodney W. Grimes */ 274df8bae1dSRodney W. Grimes vfs_op_init(); 275c901836cSGarrett Wollman vfs_opv_init(vfs_opv_descs); /* finish the job */ 276df8bae1dSRodney W. Grimes /* 277df8bae1dSRodney W. Grimes * Initialize each file system type. 278df8bae1dSRodney W. Grimes */ 279df8bae1dSRodney W. Grimes vattr_null(&va_null); 280df8bae1dSRodney W. Grimes for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) { 281df8bae1dSRodney W. Grimes if (*vfsp == NULL) 282df8bae1dSRodney W. Grimes continue; 283df8bae1dSRodney W. Grimes (*(*vfsp)->vfs_init)(); 284df8bae1dSRodney W. Grimes } 285df8bae1dSRodney W. Grimes } 286c901836cSGarrett Wollman 287c901836cSGarrett Wollman /* 288c901836cSGarrett Wollman * kernel related system variables. 289c901836cSGarrett Wollman */ 290c901836cSGarrett Wollman int 291c901836cSGarrett Wollman fs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 292c901836cSGarrett Wollman int *name; 293c901836cSGarrett Wollman u_int namelen; 294c901836cSGarrett Wollman void *oldp; 295c901836cSGarrett Wollman size_t *oldlenp; 296c901836cSGarrett Wollman void *newp; 297c901836cSGarrett Wollman size_t newlen; 298c901836cSGarrett Wollman struct proc *p; 299c901836cSGarrett Wollman { 300c901836cSGarrett Wollman int i; 301c901836cSGarrett Wollman int error; 302c901836cSGarrett Wollman int buflen = *oldlenp; 303dff55bb5SGarrett Wollman caddr_t where = oldp, start = oldp; 304c901836cSGarrett Wollman 305c901836cSGarrett Wollman switch (name[0]) { 306c901836cSGarrett Wollman case FS_VFSCONF: 307c901836cSGarrett Wollman if (namelen != 1) return ENOTDIR; 308c901836cSGarrett Wollman 309c901836cSGarrett Wollman if (oldp == NULL) { 310c901836cSGarrett Wollman *oldlenp = (MOUNT_MAXTYPE+1) * sizeof(struct vfsconf); 311c901836cSGarrett Wollman return 0; 312c901836cSGarrett Wollman } 313c901836cSGarrett Wollman if (newp) { 314c901836cSGarrett Wollman return EINVAL; 315c901836cSGarrett Wollman } 316c901836cSGarrett Wollman 317c901836cSGarrett Wollman for(i = 0; i < MOUNT_MAXTYPE + 1; i++) { 318c901836cSGarrett Wollman if(buflen < sizeof *vfsconf[i]) { 319c901836cSGarrett Wollman *oldlenp = where - start; 320c901836cSGarrett Wollman return ENOMEM; 321c901836cSGarrett Wollman } 322c901836cSGarrett Wollman 323dcd01eb3SPoul-Henning Kamp error = copyout(vfsconf[i], where, sizeof *vfsconf[i]); 324dcd01eb3SPoul-Henning Kamp if(error) 325c901836cSGarrett Wollman return error; 326c901836cSGarrett Wollman where += sizeof *vfsconf[i]; 327c901836cSGarrett Wollman buflen -= sizeof *vfsconf[i]; 328c901836cSGarrett Wollman } 329c901836cSGarrett Wollman *oldlenp = where - start; 330c901836cSGarrett Wollman return 0; 331c901836cSGarrett Wollman 332c901836cSGarrett Wollman default: 33303a62940SGarrett Wollman if(namelen < 1) return EINVAL; 33403a62940SGarrett Wollman 33503a62940SGarrett Wollman i = name[0]; 33603a62940SGarrett Wollman 33703a62940SGarrett Wollman if(i <= MOUNT_MAXTYPE 33803a62940SGarrett Wollman && vfssw[i] 33903a62940SGarrett Wollman && vfssw[i]->vfs_sysctl) { 34003a62940SGarrett Wollman return vfssw[i]->vfs_sysctl(name + 1, namelen - 1, 34103a62940SGarrett Wollman oldp, oldlenp, 34203a62940SGarrett Wollman newp, newlen, p); 34303a62940SGarrett Wollman } 34403a62940SGarrett Wollman 345c901836cSGarrett Wollman return (EOPNOTSUPP); 346c901836cSGarrett Wollman } 347c901836cSGarrett Wollman /* NOTREACHED */ 348c901836cSGarrett Wollman } 349c901836cSGarrett Wollman 350e21fa31aSGarrett Wollman /* 351e21fa31aSGarrett Wollman * This goop is here to support a loadable NFS module... grumble... 352e21fa31aSGarrett Wollman */ 353e21fa31aSGarrett Wollman void (*lease_check) __P((struct vnode *, struct proc *, struct ucred *, int)) 354e21fa31aSGarrett Wollman = 0; 355e21fa31aSGarrett Wollman void (*lease_updatetime) __P((int)) 356e21fa31aSGarrett Wollman = 0; 357e21fa31aSGarrett Wollman 358