Home | History | Annotate | Line # | Download | only in coda
coda_vfsops.c revision 1.1.1.1
      1  1.1  rvb /*
      2  1.1  rvb 
      3  1.1  rvb             Coda: an Experimental Distributed File System
      4  1.1  rvb                              Release 3.1
      5  1.1  rvb 
      6  1.1  rvb           Copyright (c) 1987-1998 Carnegie Mellon University
      7  1.1  rvb                          All Rights Reserved
      8  1.1  rvb 
      9  1.1  rvb Permission  to  use, copy, modify and distribute this software and its
     10  1.1  rvb documentation is hereby granted,  provided  that  both  the  copyright
     11  1.1  rvb notice  and  this  permission  notice  appear  in  all  copies  of the
     12  1.1  rvb software, derivative works or  modified  versions,  and  any  portions
     13  1.1  rvb thereof, and that both notices appear in supporting documentation, and
     14  1.1  rvb that credit is given to Carnegie Mellon University  in  all  documents
     15  1.1  rvb and publicity pertaining to direct or indirect use of this code or its
     16  1.1  rvb derivatives.
     17  1.1  rvb 
     18  1.1  rvb CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS  KNOWN  TO  HAVE  BUGS,
     19  1.1  rvb SOME  OF  WHICH MAY HAVE SERIOUS CONSEQUENCES.  CARNEGIE MELLON ALLOWS
     20  1.1  rvb FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.   CARNEGIE  MELLON
     21  1.1  rvb DISCLAIMS  ANY  LIABILITY  OF  ANY  KIND  FOR  ANY  DAMAGES WHATSOEVER
     22  1.1  rvb RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE  OR  OF
     23  1.1  rvb ANY DERIVATIVE WORK.
     24  1.1  rvb 
     25  1.1  rvb Carnegie  Mellon  encourages  users  of  this  software  to return any
     26  1.1  rvb improvements or extensions that  they  make,  and  to  grant  Carnegie
     27  1.1  rvb Mellon the rights to redistribute these changes without encumbrance.
     28  1.1  rvb */
     29  1.1  rvb 
     30  1.1  rvb /* $Header: /tank/opengrok/rsync2/NetBSD/src/sys/coda/coda_vfsops.c,v 1.1.1.1 1998/08/29 21:26:45 rvb Exp $ */
     31  1.1  rvb 
     32  1.1  rvb /*
     33  1.1  rvb  * Mach Operating System
     34  1.1  rvb  * Copyright (c) 1989 Carnegie-Mellon University
     35  1.1  rvb  * All rights reserved.  The CMU software License Agreement specifies
     36  1.1  rvb  * the terms and conditions for use and redistribution.
     37  1.1  rvb  */
     38  1.1  rvb 
     39  1.1  rvb /*
     40  1.1  rvb  * This code was written for the Coda file system at Carnegie Mellon
     41  1.1  rvb  * University.  Contributers include David Steere, James Kistler, and
     42  1.1  rvb  * M. Satyanarayanan.
     43  1.1  rvb  */
     44  1.1  rvb 
     45  1.1  rvb /*
     46  1.1  rvb  * HISTORY
     47  1.1  rvb  * $Log: coda_vfsops.c,v $
     48  1.1  rvb  * Revision 1.1.1.1  1998/08/29 21:26:45  rvb
     49  1.1  rvb  * Very Preliminary Coda
     50  1.1  rvb  *
     51  1.1  rvb  * Revision 1.11  1998/08/28 18:12:22  rvb
     52  1.1  rvb  * Now it also works on FreeBSD -current.  This code will be
     53  1.1  rvb  * committed to the FreeBSD -current and NetBSD -current
     54  1.1  rvb  * trees.  It will then be tailored to the particular platform
     55  1.1  rvb  * by flushing conditional code.
     56  1.1  rvb  *
     57  1.1  rvb  * Revision 1.10  1998/08/18 17:05:19  rvb
     58  1.1  rvb  * Don't use __RCSID now
     59  1.1  rvb  *
     60  1.1  rvb  * Revision 1.9  1998/08/18 16:31:44  rvb
     61  1.1  rvb  * Sync the code for NetBSD -current; test on 1.3 later
     62  1.1  rvb  *
     63  1.1  rvb  * Revision 1.8  98/02/24  22:22:48  rvb
     64  1.1  rvb  * Fixes up mainly to flush iopen and friends
     65  1.1  rvb  *
     66  1.1  rvb  * Revision 1.7  98/01/23  11:53:45  rvb
     67  1.1  rvb  * Bring RVB_CFS1_1 to HEAD
     68  1.1  rvb  *
     69  1.1  rvb  * Revision 1.6.2.6  98/01/23  11:21:07  rvb
     70  1.1  rvb  * Sync with 2.2.5
     71  1.1  rvb  *
     72  1.1  rvb  * Revision 1.6.2.5  98/01/22  13:05:33  rvb
     73  1.1  rvb  * Move makecfsnode ctlfid later so vfsp is known
     74  1.1  rvb  *
     75  1.1  rvb  * Revision 1.6.2.4  97/12/19  14:26:05  rvb
     76  1.1  rvb  * session id
     77  1.1  rvb  *
     78  1.1  rvb  * Revision 1.6.2.3  97/12/16  12:40:11  rvb
     79  1.1  rvb  * Sync with 1.3
     80  1.1  rvb  *
     81  1.1  rvb  * Revision 1.6.2.2  97/12/10  11:40:25  rvb
     82  1.1  rvb  * No more ody
     83  1.1  rvb  *
     84  1.1  rvb  * Revision 1.6.2.1  97/12/06  17:41:24  rvb
     85  1.1  rvb  * Sync with peters coda.h
     86  1.1  rvb  *
     87  1.1  rvb  * Revision 1.6  97/12/05  10:39:21  rvb
     88  1.1  rvb  * Read CHANGES
     89  1.1  rvb  *
     90  1.1  rvb  * Revision 1.5.14.8  97/11/24  15:44:46  rvb
     91  1.1  rvb  * Final cfs_venus.c w/o macros, but one locking bug
     92  1.1  rvb  *
     93  1.1  rvb  * Revision 1.5.14.7  97/11/21  13:22:03  rvb
     94  1.1  rvb  * Catch a few cfscalls in cfs_vfsops.c
     95  1.1  rvb  *
     96  1.1  rvb  * Revision 1.5.14.6  97/11/20  11:46:48  rvb
     97  1.1  rvb  * Capture current cfs_venus
     98  1.1  rvb  *
     99  1.1  rvb  * Revision 1.5.14.5  97/11/18  10:27:17  rvb
    100  1.1  rvb  * cfs_nbsd.c is DEAD!!!; integrated into cfs_vf/vnops.c
    101  1.1  rvb  * cfs_nb_foo and cfs_foo are joined
    102  1.1  rvb  *
    103  1.1  rvb  * Revision 1.5.14.4  97/11/13  22:03:01  rvb
    104  1.1  rvb  * pass2 cfs_NetBSD.h mt
    105  1.1  rvb  *
    106  1.1  rvb  * Revision 1.5.14.3  97/11/12  12:09:40  rvb
    107  1.1  rvb  * reorg pass1
    108  1.1  rvb  *
    109  1.1  rvb  * Revision 1.5.14.2  97/10/29  16:06:28  rvb
    110  1.1  rvb  * Kill DYING
    111  1.1  rvb  *
    112  1.1  rvb  * Revision 1.5.14.1  1997/10/28 23:10:17  rvb
    113  1.1  rvb  * >64Meg; venus can be killed!
    114  1.1  rvb  *
    115  1.1  rvb  * Revision 1.5  1997/01/13 17:11:07  bnoble
    116  1.1  rvb  * Coda statfs needs to return something other than -1 for blocks avail. and
    117  1.1  rvb  * files available for wabi (and other windowsish) programs to install
    118  1.1  rvb  * there correctly.
    119  1.1  rvb  *
    120  1.1  rvb  * Revision 1.4  1996/12/12 22:11:00  bnoble
    121  1.1  rvb  * Fixed the "downcall invokes venus operation" deadlock in all known cases.
    122  1.1  rvb  * There may be more
    123  1.1  rvb  *
    124  1.1  rvb  * Revision 1.3  1996/11/08 18:06:12  bnoble
    125  1.1  rvb  * Minor changes in vnode operation signature, VOP_UPDATE signature, and
    126  1.1  rvb  * some newly defined bits in the include files.
    127  1.1  rvb  *
    128  1.1  rvb  * Revision 1.2  1996/01/02 16:57:04  bnoble
    129  1.1  rvb  * Added support for Coda MiniCache and raw inode calls (final commit)
    130  1.1  rvb  *
    131  1.1  rvb  * Revision 1.1.2.1  1995/12/20 01:57:32  bnoble
    132  1.1  rvb  * Added CFS-specific files
    133  1.1  rvb  *
    134  1.1  rvb  * Revision 3.1.1.1  1995/03/04  19:08:02  bnoble
    135  1.1  rvb  * Branch for NetBSD port revisions
    136  1.1  rvb  *
    137  1.1  rvb  * Revision 3.1  1995/03/04  19:08:01  bnoble
    138  1.1  rvb  * Bump to major revision 3 to prepare for NetBSD port
    139  1.1  rvb  *
    140  1.1  rvb  * Revision 2.4  1995/02/17  16:25:22  dcs
    141  1.1  rvb  * These versions represent several changes:
    142  1.1  rvb  * 1. Allow venus to restart even if outstanding references exist.
    143  1.1  rvb  * 2. Have only one ctlvp per client, as opposed to one per mounted cfs device.d
    144  1.1  rvb  * 3. Allow ody_expand to return many members, not just one.
    145  1.1  rvb  *
    146  1.1  rvb  * Revision 2.3  94/10/14  09:58:21  dcs
    147  1.1  rvb  * Made changes 'cause sun4s have braindead compilers
    148  1.1  rvb  *
    149  1.1  rvb  * Revision 2.2  94/10/12  16:46:33  dcs
    150  1.1  rvb  * Cleaned kernel/venus interface by removing XDR junk, plus
    151  1.1  rvb  * so cleanup to allow this code to be more easily ported.
    152  1.1  rvb  *
    153  1.1  rvb  * Revision 1.3  93/05/28  16:24:29  bnoble
    154  1.1  rvb  * *** empty log message ***
    155  1.1  rvb  *
    156  1.1  rvb  * Revision 1.2  92/10/27  17:58:24  lily
    157  1.1  rvb  * merge kernel/latest and alpha/src/cfs
    158  1.1  rvb  *
    159  1.1  rvb  * Revision 2.3  92/09/30  14:16:32  mja
    160  1.1  rvb  * 	Added call to cfs_flush to cfs_unmount.
    161  1.1  rvb  * 	[90/12/15            dcs]
    162  1.1  rvb  *
    163  1.1  rvb  * 	Added contributors blurb.
    164  1.1  rvb  * 	[90/12/13            jjk]
    165  1.1  rvb  *
    166  1.1  rvb  * Revision 2.2  90/07/05  11:26:40  mrt
    167  1.1  rvb  * 	Created for the Coda File System.
    168  1.1  rvb  * 	[90/05/23            dcs]
    169  1.1  rvb  *
    170  1.1  rvb  * Revision 1.3  90/05/31  17:01:42  dcs
    171  1.1  rvb  * Prepare for merge with facilities kernel.
    172  1.1  rvb  *
    173  1.1  rvb  *
    174  1.1  rvb  */
    175  1.1  rvb #include <vcfs.h>
    176  1.1  rvb 
    177  1.1  rvb #include <sys/param.h>
    178  1.1  rvb #include <sys/systm.h>
    179  1.1  rvb #include <sys/malloc.h>
    180  1.1  rvb #include <sys/conf.h>
    181  1.1  rvb #include <sys/namei.h>
    182  1.1  rvb #include <sys/mount.h>
    183  1.1  rvb #include <sys/proc.h>
    184  1.1  rvb #include <sys/select.h>
    185  1.1  rvb 
    186  1.1  rvb #include <cfs/coda.h>
    187  1.1  rvb #include <cfs/cnode.h>
    188  1.1  rvb #include <cfs/cfs_vfsops.h>
    189  1.1  rvb #include <cfs/cfs_venus.h>
    190  1.1  rvb #include <cfs/cfs_subr.h>
    191  1.1  rvb #include <cfs/coda_opstats.h>
    192  1.1  rvb /* for VN_RDEV */
    193  1.1  rvb #include <miscfs/specfs/specdev.h>
    194  1.1  rvb 
    195  1.1  rvb #ifdef	__FreeBSD__
    196  1.1  rvb #ifdef	__FreeBSD_version
    197  1.1  rvb MALLOC_DEFINE(M_CFS, "CFS storage", "Various Coda Structures");
    198  1.1  rvb #endif
    199  1.1  rvb #endif
    200  1.1  rvb 
    201  1.1  rvb int cfsdebug = 0;
    202  1.1  rvb 
    203  1.1  rvb int cfs_vfsop_print_entry = 0;
    204  1.1  rvb #ifdef __GNUC__
    205  1.1  rvb #define ENTRY    \
    206  1.1  rvb     if(cfs_vfsop_print_entry) myprintf(("Entered %s\n",__FUNCTION__))
    207  1.1  rvb #else
    208  1.1  rvb #define ENTRY
    209  1.1  rvb #endif
    210  1.1  rvb 
    211  1.1  rvb 
    212  1.1  rvb struct vnode *cfs_ctlvp;
    213  1.1  rvb struct cfs_mntinfo cfs_mnttbl[NVCFS]; /* indexed by minor device number */
    214  1.1  rvb 
    215  1.1  rvb /* structure to keep statistics of internally generated/satisfied calls */
    216  1.1  rvb 
    217  1.1  rvb struct cfs_op_stats cfs_vfsopstats[CFS_VFSOPS_SIZE];
    218  1.1  rvb 
    219  1.1  rvb #define MARK_ENTRY(op) (cfs_vfsopstats[op].entries++)
    220  1.1  rvb #define MARK_INT_SAT(op) (cfs_vfsopstats[op].sat_intrn++)
    221  1.1  rvb #define MARK_INT_FAIL(op) (cfs_vfsopstats[op].unsat_intrn++)
    222  1.1  rvb #define MRAK_INT_GEN(op) (cfs_vfsopstats[op].gen_intrn++)
    223  1.1  rvb 
    224  1.1  rvb extern int cfsnc_initialized;     /* Set if cache has been initialized */
    225  1.1  rvb extern int vc_nb_open __P((dev_t, int, int, struct proc *));
    226  1.1  rvb #ifdef	__NetBSD__
    227  1.1  rvb extern struct cdevsw cdevsw[];    /* For sanity check in cfs_mount */
    228  1.1  rvb #endif
    229  1.1  rvb /* NetBSD interface to statfs */
    230  1.1  rvb 
    231  1.1  rvb #if	defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 5)
    232  1.1  rvb extern struct vnodeopv_desc cfs_vnodeop_opv_desc;
    233  1.1  rvb 
    234  1.1  rvb struct vnodeopv_desc *cfs_vnodeopv_descs[] = {
    235  1.1  rvb 	&cfs_vnodeop_opv_desc,
    236  1.1  rvb 	NULL,
    237  1.1  rvb };
    238  1.1  rvb 
    239  1.1  rvb struct vfsops cfs_vfsops = {
    240  1.1  rvb     MOUNT_CFS,
    241  1.1  rvb     cfs_mount,
    242  1.1  rvb     cfs_start,
    243  1.1  rvb     cfs_unmount,
    244  1.1  rvb     cfs_root,
    245  1.1  rvb     cfs_quotactl,
    246  1.1  rvb     cfs_nb_statfs,
    247  1.1  rvb     cfs_sync,
    248  1.1  rvb     cfs_vget,
    249  1.1  rvb     (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **,
    250  1.1  rvb 	      int *, struct ucred **))
    251  1.1  rvb 	eopnotsupp,
    252  1.1  rvb     (int (*) (struct vnode *, struct fid *)) eopnotsupp,
    253  1.1  rvb     cfs_init,
    254  1.1  rvb #if (NetBSD1_3 >= 7)
    255  1.1  rvb     cfs_sysctl,
    256  1.1  rvb #endif
    257  1.1  rvb     (int (*)(void)) eopnotsupp,
    258  1.1  rvb     cfs_vnodeopv_descs,
    259  1.1  rvb     0
    260  1.1  rvb };
    261  1.1  rvb #elif	defined(__NetBSD__)
    262  1.1  rvb struct vfsops cfs_vfsops = {
    263  1.1  rvb     MOUNT_CFS,
    264  1.1  rvb     cfs_mount,
    265  1.1  rvb     cfs_start,
    266  1.1  rvb     cfs_unmount,
    267  1.1  rvb     cfs_root,
    268  1.1  rvb     cfs_quotactl,
    269  1.1  rvb     cfs_nb_statfs,
    270  1.1  rvb     cfs_sync,
    271  1.1  rvb     cfs_vget,
    272  1.1  rvb     (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **,
    273  1.1  rvb 	      int *, struct ucred **))
    274  1.1  rvb 	eopnotsupp,
    275  1.1  rvb     (int (*) (struct vnode *, struct fid *)) eopnotsupp,
    276  1.1  rvb     cfs_init,
    277  1.1  rvb #ifdef	NetBSD1_3
    278  1.1  rvb     (int (*)(void)) eopnotsupp,
    279  1.1  rvb #endif
    280  1.1  rvb     0
    281  1.1  rvb };
    282  1.1  rvb 
    283  1.1  rvb #elif	defined(__FreeBSD__)
    284  1.1  rvb #ifdef	__FreeBSD_version
    285  1.1  rvb struct vfsops cfs_vfsops = {
    286  1.1  rvb     cfs_mount,
    287  1.1  rvb     cfs_start,
    288  1.1  rvb     cfs_unmount,
    289  1.1  rvb     cfs_root,
    290  1.1  rvb     cfs_quotactl,
    291  1.1  rvb     cfs_nb_statfs,
    292  1.1  rvb     cfs_sync,
    293  1.1  rvb     cfs_vget,
    294  1.1  rvb     (int (*) (struct mount *, struct fid *, struct sockaddr *, struct vnode **,
    295  1.1  rvb 	      int *, struct ucred **))
    296  1.1  rvb 	eopnotsupp,
    297  1.1  rvb     (int (*) (struct vnode *, struct fid *)) eopnotsupp,
    298  1.1  rvb     cfs_init,
    299  1.1  rvb };
    300  1.1  rvb 
    301  1.1  rvb #else
    302  1.1  rvb struct vfsops cfs_vfsops = {
    303  1.1  rvb     cfs_mount,
    304  1.1  rvb     cfs_start,
    305  1.1  rvb     cfs_unmount,
    306  1.1  rvb     cfs_root,
    307  1.1  rvb     cfs_quotactl,
    308  1.1  rvb     cfs_nb_statfs,
    309  1.1  rvb     cfs_sync,
    310  1.1  rvb     cfs_vget,
    311  1.1  rvb     (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **,
    312  1.1  rvb 	      int *, struct ucred **))
    313  1.1  rvb 	eopnotsupp,
    314  1.1  rvb     (int (*) (struct vnode *, struct fid *)) eopnotsupp,
    315  1.1  rvb     cfs_init,
    316  1.1  rvb };
    317  1.1  rvb 
    318  1.1  rvb #endif
    319  1.1  rvb 
    320  1.1  rvb 
    321  1.1  rvb #include <sys/kernel.h>
    322  1.1  rvb VFS_SET(cfs_vfsops, cfs, MOUNT_CFS, VFCF_NETWORK);
    323  1.1  rvb #endif
    324  1.1  rvb 
    325  1.1  rvb int
    326  1.1  rvb cfs_vfsopstats_init(void)
    327  1.1  rvb {
    328  1.1  rvb 	register int i;
    329  1.1  rvb 
    330  1.1  rvb 	for (i=0;i<CFS_VFSOPS_SIZE;i++) {
    331  1.1  rvb 		cfs_vfsopstats[i].opcode = i;
    332  1.1  rvb 		cfs_vfsopstats[i].entries = 0;
    333  1.1  rvb 		cfs_vfsopstats[i].sat_intrn = 0;
    334  1.1  rvb 		cfs_vfsopstats[i].unsat_intrn = 0;
    335  1.1  rvb 		cfs_vfsopstats[i].gen_intrn = 0;
    336  1.1  rvb 	}
    337  1.1  rvb 
    338  1.1  rvb 	return 0;
    339  1.1  rvb }
    340  1.1  rvb 
    341  1.1  rvb 
    342  1.1  rvb /*
    343  1.1  rvb  * cfs mount vfsop
    344  1.1  rvb  * Set up mount info record and attach it to vfs struct.
    345  1.1  rvb  */
    346  1.1  rvb /*ARGSUSED*/
    347  1.1  rvb int
    348  1.1  rvb cfs_mount(vfsp, path, data, ndp, p)
    349  1.1  rvb     struct mount *vfsp;		/* Allocated and initialized by mount(2) */
    350  1.1  rvb #ifdef	NetBSD1_3
    351  1.1  rvb     const char *path;		/* path covered: ignored by the fs-layer */
    352  1.1  rvb     void *data;			/* Need to define a data type for this in netbsd? */
    353  1.1  rvb #else
    354  1.1  rvb     char *path;			/* path covered: ignored by the fs-layer */
    355  1.1  rvb     caddr_t data;		/* Need to define a data type for this in netbsd? */
    356  1.1  rvb #endif
    357  1.1  rvb     struct nameidata *ndp;	/* Clobber this to lookup the device name */
    358  1.1  rvb     struct proc *p;		/* The ever-famous proc pointer */
    359  1.1  rvb {
    360  1.1  rvb     struct vnode *dvp;
    361  1.1  rvb     struct cnode *cp;
    362  1.1  rvb     dev_t dev;
    363  1.1  rvb     struct cfs_mntinfo *mi;
    364  1.1  rvb     struct vnode *rootvp;
    365  1.1  rvb     ViceFid rootfid;
    366  1.1  rvb     ViceFid ctlfid;
    367  1.1  rvb     int error;
    368  1.1  rvb 
    369  1.1  rvb     ENTRY;
    370  1.1  rvb 
    371  1.1  rvb     cfs_vfsopstats_init();
    372  1.1  rvb     cfs_vnodeopstats_init();
    373  1.1  rvb 
    374  1.1  rvb     MARK_ENTRY(CFS_MOUNT_STATS);
    375  1.1  rvb     if (CFS_MOUNTED(vfsp)) {
    376  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    377  1.1  rvb 	return(EBUSY);
    378  1.1  rvb     }
    379  1.1  rvb 
    380  1.1  rvb     /* Validate mount device.  Similar to getmdev(). */
    381  1.1  rvb 
    382  1.1  rvb     NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, data, p);
    383  1.1  rvb     error = namei(ndp);
    384  1.1  rvb     dvp = ndp->ni_vp;
    385  1.1  rvb 
    386  1.1  rvb     if (error) {
    387  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    388  1.1  rvb 	return (error);
    389  1.1  rvb     }
    390  1.1  rvb     if (dvp->v_type != VCHR) {
    391  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    392  1.1  rvb 	vrele(dvp);
    393  1.1  rvb 	return(ENXIO);
    394  1.1  rvb     }
    395  1.1  rvb     dev = dvp->v_specinfo->si_rdev;
    396  1.1  rvb     vrele(dvp);
    397  1.1  rvb     if (major(dev) >= nchrdev || major(dev) < 0) {
    398  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    399  1.1  rvb 	return(ENXIO);
    400  1.1  rvb     }
    401  1.1  rvb 
    402  1.1  rvb     /*
    403  1.1  rvb      * See if the device table matches our expectations.
    404  1.1  rvb      */
    405  1.1  rvb #ifdef	__NetBSD__
    406  1.1  rvb     if (cdevsw[major(dev)].d_open != vc_nb_open)
    407  1.1  rvb #elif	defined(__FreeBSD__)
    408  1.1  rvb     if (cdevsw[major(dev)]->d_open != vc_nb_open)
    409  1.1  rvb #endif
    410  1.1  rvb     {
    411  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    412  1.1  rvb 	return(ENXIO);
    413  1.1  rvb     }
    414  1.1  rvb 
    415  1.1  rvb     if (minor(dev) >= NVCFS || minor(dev) < 0) {
    416  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    417  1.1  rvb 	return(ENXIO);
    418  1.1  rvb     }
    419  1.1  rvb 
    420  1.1  rvb     /*
    421  1.1  rvb      * Initialize the mount record and link it to the vfs struct
    422  1.1  rvb      */
    423  1.1  rvb     mi = &cfs_mnttbl[minor(dev)];
    424  1.1  rvb 
    425  1.1  rvb     if (!VC_OPEN(&mi->mi_vcomm)) {
    426  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    427  1.1  rvb 	return(ENODEV);
    428  1.1  rvb     }
    429  1.1  rvb 
    430  1.1  rvb     /* No initialization (here) of mi_vcomm! */
    431  1.1  rvb     vfsp->mnt_data = (qaddr_t)mi;
    432  1.1  rvb #ifdef	__NetBSD__
    433  1.1  rvb     vfsp->mnt_stat.f_fsid.val[0] = 0;
    434  1.1  rvb     vfsp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_CFS);
    435  1.1  rvb #elif	defined(__FreeBSD__) && defined(__FreeBSD_version)
    436  1.1  rvb 
    437  1.1  rvb     vfs_getnewfsid (vfsp);
    438  1.1  rvb 
    439  1.1  rvb #elif	defined(__FreeBSD__)
    440  1.1  rvb     /* Seems a bit overkill, since usualy /coda is the only mount point
    441  1.1  rvb      * for cfs.
    442  1.1  rvb      */
    443  1.1  rvb     getnewfsid (vfsp, MOUNT_CFS);
    444  1.1  rvb #endif
    445  1.1  rvb     mi->mi_vfsp = vfsp;
    446  1.1  rvb 
    447  1.1  rvb     /*
    448  1.1  rvb      * Make a root vnode to placate the Vnode interface, but don't
    449  1.1  rvb      * actually make the CFS_ROOT call to venus until the first call
    450  1.1  rvb      * to cfs_root in case a server is down while venus is starting.
    451  1.1  rvb      */
    452  1.1  rvb     rootfid.Volume = 0;
    453  1.1  rvb     rootfid.Vnode = 0;
    454  1.1  rvb     rootfid.Unique = 0;
    455  1.1  rvb     cp = makecfsnode(&rootfid, vfsp, VDIR);
    456  1.1  rvb     rootvp = CTOV(cp);
    457  1.1  rvb     rootvp->v_flag |= VROOT;
    458  1.1  rvb 
    459  1.1  rvb     ctlfid.Volume = CTL_VOL;
    460  1.1  rvb     ctlfid.Vnode = CTL_VNO;
    461  1.1  rvb     ctlfid.Unique = CTL_UNI;
    462  1.1  rvb /*  cp = makecfsnode(&ctlfid, vfsp, VCHR);
    463  1.1  rvb     The above code seems to cause a loop in the cnode links.
    464  1.1  rvb     I don't totally understand when it happens, it is caught
    465  1.1  rvb     when closing down the system.
    466  1.1  rvb  */
    467  1.1  rvb     cp = makecfsnode(&ctlfid, 0, VCHR);
    468  1.1  rvb 
    469  1.1  rvb     cfs_ctlvp = CTOV(cp);
    470  1.1  rvb 
    471  1.1  rvb     /* Add vfs and rootvp to chain of vfs hanging off mntinfo */
    472  1.1  rvb     mi->mi_vfsp = vfsp;
    473  1.1  rvb     mi->mi_rootvp = rootvp;
    474  1.1  rvb 
    475  1.1  rvb     /* set filesystem block size */
    476  1.1  rvb     vfsp->mnt_stat.f_bsize = 8192;	    /* XXX -JJK */
    477  1.1  rvb #ifdef	 __FreeBSD__
    478  1.1  rvb     /* Set f_iosize.  XXX -- inamura (at) isl.ntt.co.jp.
    479  1.1  rvb        For vnode_pager_haspage() references. The value should be obtained
    480  1.1  rvb        from underlying UFS. */
    481  1.1  rvb     /* Checked UFS. iosize is set as 8192 */
    482  1.1  rvb     vfsp->mnt_stat.f_iosize = 8192;
    483  1.1  rvb #endif
    484  1.1  rvb 
    485  1.1  rvb     /* error is currently guaranteed to be zero, but in case some
    486  1.1  rvb        code changes... */
    487  1.1  rvb     CFSDEBUG(1,
    488  1.1  rvb 	     myprintf(("cfs_mount returned %d\n",error)););
    489  1.1  rvb     if (error)
    490  1.1  rvb 	MARK_INT_FAIL(CFS_MOUNT_STATS);
    491  1.1  rvb     else
    492  1.1  rvb 	MARK_INT_SAT(CFS_MOUNT_STATS);
    493  1.1  rvb 
    494  1.1  rvb     return(error);
    495  1.1  rvb }
    496  1.1  rvb 
    497  1.1  rvb int
    498  1.1  rvb cfs_start(vfsp, flags, p)
    499  1.1  rvb     struct mount *vfsp;
    500  1.1  rvb     int flags;
    501  1.1  rvb     struct proc *p;
    502  1.1  rvb {
    503  1.1  rvb     ENTRY;
    504  1.1  rvb     return (0);
    505  1.1  rvb }
    506  1.1  rvb 
    507  1.1  rvb int
    508  1.1  rvb cfs_unmount(vfsp, mntflags, p)
    509  1.1  rvb     struct mount *vfsp;
    510  1.1  rvb     int mntflags;
    511  1.1  rvb     struct proc *p;
    512  1.1  rvb {
    513  1.1  rvb     struct cfs_mntinfo *mi = vftomi(vfsp);
    514  1.1  rvb     int active, error = 0;
    515  1.1  rvb 
    516  1.1  rvb     ENTRY;
    517  1.1  rvb     MARK_ENTRY(CFS_UMOUNT_STATS);
    518  1.1  rvb     if (!CFS_MOUNTED(vfsp)) {
    519  1.1  rvb 	MARK_INT_FAIL(CFS_UMOUNT_STATS);
    520  1.1  rvb 	return(EINVAL);
    521  1.1  rvb     }
    522  1.1  rvb 
    523  1.1  rvb     if (mi->mi_vfsp == vfsp) {	/* We found the victim */
    524  1.1  rvb 	if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp)))
    525  1.1  rvb 	    return (EBUSY); 	/* Venus is still running */
    526  1.1  rvb 
    527  1.1  rvb #ifdef	DEBUG
    528  1.1  rvb 	printf("cfs_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp));
    529  1.1  rvb #endif
    530  1.1  rvb 	vrele(mi->mi_rootvp);
    531  1.1  rvb 
    532  1.1  rvb #ifdef	NetBSD1_3
    533  1.1  rvb 	active = cfs_kill(vfsp, NOT_DOWNCALL);
    534  1.1  rvb 
    535  1.1  rvb #if	defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 7)
    536  1.1  rvb 	if (1)
    537  1.1  rvb #else
    538  1.1  rvb 	if ((error = vfs_busy(mi->mi_vfsp)) == 0)
    539  1.1  rvb #endif
    540  1.1  rvb 	{
    541  1.1  rvb 		error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE);
    542  1.1  rvb 		printf("cfs_unmount: active = %d, vflush active %d\n", active, error);
    543  1.1  rvb 		error = 0;
    544  1.1  rvb 	} else {
    545  1.1  rvb 		printf("cfs_unmount: busy\n");
    546  1.1  rvb 	}
    547  1.1  rvb #else	/* FreeBSD I guess */
    548  1.1  rvb 	active = cfs_kill(vfsp, NOT_DOWNCALL);
    549  1.1  rvb 	error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE);
    550  1.1  rvb 	printf("cfs_unmount: active = %d, vflush active %d\n", active, error);
    551  1.1  rvb 	error = 0;
    552  1.1  rvb #endif
    553  1.1  rvb 	/* I'm going to take this out to allow lookups to go through. I'm
    554  1.1  rvb 	 * not sure it's important anyway. -- DCS 2/2/94
    555  1.1  rvb 	 */
    556  1.1  rvb 	/* vfsp->VFS_DATA = NULL; */
    557  1.1  rvb 
    558  1.1  rvb 	/* No more vfsp's to hold onto */
    559  1.1  rvb 	mi->mi_vfsp = NULL;
    560  1.1  rvb 	mi->mi_rootvp = NULL;
    561  1.1  rvb 
    562  1.1  rvb 	if (error)
    563  1.1  rvb 	    MARK_INT_FAIL(CFS_UMOUNT_STATS);
    564  1.1  rvb 	else
    565  1.1  rvb 	    MARK_INT_SAT(CFS_UMOUNT_STATS);
    566  1.1  rvb 
    567  1.1  rvb 	return(error);
    568  1.1  rvb     }
    569  1.1  rvb     return (EINVAL);
    570  1.1  rvb }
    571  1.1  rvb 
    572  1.1  rvb /*
    573  1.1  rvb  * find root of cfs
    574  1.1  rvb  */
    575  1.1  rvb int
    576  1.1  rvb cfs_root(vfsp, vpp)
    577  1.1  rvb 	struct mount *vfsp;
    578  1.1  rvb 	struct vnode **vpp;
    579  1.1  rvb {
    580  1.1  rvb     struct cfs_mntinfo *mi = vftomi(vfsp);
    581  1.1  rvb     struct vnode **result;
    582  1.1  rvb     int error;
    583  1.1  rvb     struct proc *p = curproc;    /* XXX - bnoble */
    584  1.1  rvb     ViceFid VFid;
    585  1.1  rvb 
    586  1.1  rvb     ENTRY;
    587  1.1  rvb     MARK_ENTRY(CFS_ROOT_STATS);
    588  1.1  rvb     result = NULL;
    589  1.1  rvb 
    590  1.1  rvb     if (vfsp == mi->mi_vfsp) {
    591  1.1  rvb 	if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) ||
    592  1.1  rvb 	    (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) ||
    593  1.1  rvb 	    (VTOC(mi->mi_rootvp)->c_fid.Unique != 0))
    594  1.1  rvb 	    { /* Found valid root. */
    595  1.1  rvb 		*vpp = mi->mi_rootvp;
    596  1.1  rvb 		/* On Mach, this is vref.  On NetBSD, VOP_LOCK */
    597  1.1  rvb 		vref(*vpp);
    598  1.1  rvb 		VOP_X_LOCK(*vpp, LK_EXCLUSIVE);
    599  1.1  rvb 		MARK_INT_SAT(CFS_ROOT_STATS);
    600  1.1  rvb 		return(0);
    601  1.1  rvb 	    }
    602  1.1  rvb     }
    603  1.1  rvb 
    604  1.1  rvb     error = venus_root(vftomi(vfsp), p->p_cred->pc_ucred, p, &VFid);
    605  1.1  rvb 
    606  1.1  rvb     if (!error) {
    607  1.1  rvb 	/*
    608  1.1  rvb 	 * Save the new rootfid in the cnode, and rehash the cnode into the
    609  1.1  rvb 	 * cnode hash with the new fid key.
    610  1.1  rvb 	 */
    611  1.1  rvb 	cfs_unsave(VTOC(mi->mi_rootvp));
    612  1.1  rvb 	VTOC(mi->mi_rootvp)->c_fid = VFid;
    613  1.1  rvb 	cfs_save(VTOC(mi->mi_rootvp));
    614  1.1  rvb 
    615  1.1  rvb 	*vpp = mi->mi_rootvp;
    616  1.1  rvb 	vref(*vpp);
    617  1.1  rvb 	VOP_X_LOCK(*vpp, LK_EXCLUSIVE);
    618  1.1  rvb 	MARK_INT_SAT(CFS_ROOT_STATS);
    619  1.1  rvb 	goto exit;
    620  1.1  rvb     } else if (error == ENODEV) {
    621  1.1  rvb 	/* Gross hack here! */
    622  1.1  rvb 	/*
    623  1.1  rvb 	 * If Venus fails to respond to the CFS_ROOT call, cfscall returns
    624  1.1  rvb 	 * ENODEV. Return the uninitialized root vnode to allow vfs
    625  1.1  rvb 	 * operations such as unmount to continue. Without this hack,
    626  1.1  rvb 	 * there is no way to do an unmount if Venus dies before a
    627  1.1  rvb 	 * successful CFS_ROOT call is done. All vnode operations
    628  1.1  rvb 	 * will fail.
    629  1.1  rvb 	 */
    630  1.1  rvb 	*vpp = mi->mi_rootvp;
    631  1.1  rvb 	vref(*vpp);
    632  1.1  rvb 	VOP_X_LOCK(*vpp, LK_EXCLUSIVE);
    633  1.1  rvb 	MARK_INT_FAIL(CFS_ROOT_STATS);
    634  1.1  rvb 	error = 0;
    635  1.1  rvb 	goto exit;
    636  1.1  rvb     } else {
    637  1.1  rvb 	CFSDEBUG( CFS_ROOT, myprintf(("error %d in CFS_ROOT\n", error)); );
    638  1.1  rvb 	MARK_INT_FAIL(CFS_ROOT_STATS);
    639  1.1  rvb 
    640  1.1  rvb 	goto exit;
    641  1.1  rvb     }
    642  1.1  rvb  exit:
    643  1.1  rvb     return(error);
    644  1.1  rvb }
    645  1.1  rvb 
    646  1.1  rvb int
    647  1.1  rvb cfs_quotactl(vfsp, cmd, uid, arg, p)
    648  1.1  rvb     struct mount *vfsp;
    649  1.1  rvb     int cmd;
    650  1.1  rvb     uid_t uid;
    651  1.1  rvb     caddr_t arg;
    652  1.1  rvb     struct proc *p;
    653  1.1  rvb {
    654  1.1  rvb     ENTRY;
    655  1.1  rvb     return (EOPNOTSUPP);
    656  1.1  rvb }
    657  1.1  rvb 
    658  1.1  rvb /*
    659  1.1  rvb  * Get file system statistics.
    660  1.1  rvb  */
    661  1.1  rvb int
    662  1.1  rvb cfs_nb_statfs(vfsp, sbp, p)
    663  1.1  rvb     register struct mount *vfsp;
    664  1.1  rvb     struct statfs *sbp;
    665  1.1  rvb     struct proc *p;
    666  1.1  rvb {
    667  1.1  rvb     ENTRY;
    668  1.1  rvb /*  MARK_ENTRY(CFS_STATFS_STATS); */
    669  1.1  rvb     if (!CFS_MOUNTED(vfsp)) {
    670  1.1  rvb /*	MARK_INT_FAIL(CFS_STATFS_STATS);*/
    671  1.1  rvb 	return(EINVAL);
    672  1.1  rvb     }
    673  1.1  rvb 
    674  1.1  rvb     bzero(sbp, sizeof(struct statfs));
    675  1.1  rvb     /* XXX - what to do about f_flags, others? --bnoble */
    676  1.1  rvb     /* Below This is what AFS does
    677  1.1  rvb     	#define NB_SFS_SIZ 0x895440
    678  1.1  rvb      */
    679  1.1  rvb     /* Note: Normal fs's have a bsize of 0x400 == 1024 */
    680  1.1  rvb #ifdef	__NetBSD__
    681  1.1  rvb     sbp->f_type = 0;
    682  1.1  rvb #elif	defined(__FreeBSD__)
    683  1.1  rvb     sbp->f_type = MOUNT_CFS;
    684  1.1  rvb #endif
    685  1.1  rvb     sbp->f_bsize = 8192; /* XXX */
    686  1.1  rvb     sbp->f_iosize = 8192; /* XXX */
    687  1.1  rvb #define NB_SFS_SIZ 0x8AB75D
    688  1.1  rvb     sbp->f_blocks = NB_SFS_SIZ;
    689  1.1  rvb     sbp->f_bfree = NB_SFS_SIZ;
    690  1.1  rvb     sbp->f_bavail = NB_SFS_SIZ;
    691  1.1  rvb     sbp->f_files = NB_SFS_SIZ;
    692  1.1  rvb     sbp->f_ffree = NB_SFS_SIZ;
    693  1.1  rvb     bcopy((caddr_t)&(vfsp->mnt_stat.f_fsid), (caddr_t)&(sbp->f_fsid), sizeof (fsid_t));
    694  1.1  rvb #ifdef	__NetBSD__
    695  1.1  rvb     strncpy(sbp->f_fstypename, MOUNT_CFS, MFSNAMELEN-1);
    696  1.1  rvb #endif
    697  1.1  rvb     strcpy(sbp->f_mntonname, "/coda");
    698  1.1  rvb     strcpy(sbp->f_mntfromname, "CFS");
    699  1.1  rvb /*  MARK_INT_SAT(CFS_STATFS_STATS); */
    700  1.1  rvb     return(0);
    701  1.1  rvb }
    702  1.1  rvb 
    703  1.1  rvb /*
    704  1.1  rvb  * Flush any pending I/O.
    705  1.1  rvb  */
    706  1.1  rvb int
    707  1.1  rvb cfs_sync(vfsp, waitfor, cred, p)
    708  1.1  rvb     struct mount *vfsp;
    709  1.1  rvb     int    waitfor;
    710  1.1  rvb     struct ucred *cred;
    711  1.1  rvb     struct proc *p;
    712  1.1  rvb {
    713  1.1  rvb     ENTRY;
    714  1.1  rvb     MARK_ENTRY(CFS_SYNC_STATS);
    715  1.1  rvb     MARK_INT_SAT(CFS_SYNC_STATS);
    716  1.1  rvb     return(0);
    717  1.1  rvb }
    718  1.1  rvb 
    719  1.1  rvb int
    720  1.1  rvb cfs_vget(vfsp, ino, vpp)
    721  1.1  rvb     struct mount *vfsp;
    722  1.1  rvb     ino_t ino;
    723  1.1  rvb     struct vnode **vpp;
    724  1.1  rvb {
    725  1.1  rvb     ENTRY;
    726  1.1  rvb     return (EOPNOTSUPP);
    727  1.1  rvb }
    728  1.1  rvb 
    729  1.1  rvb /*
    730  1.1  rvb  * fhtovp is now what vget used to be in 4.3-derived systems.  For
    731  1.1  rvb  * some silly reason, vget is now keyed by a 32 bit ino_t, rather than
    732  1.1  rvb  * a type-specific fid.
    733  1.1  rvb  */
    734  1.1  rvb int
    735  1.1  rvb cfs_fhtovp(vfsp, fhp, nam, vpp, exflagsp, creadanonp)
    736  1.1  rvb     register struct mount *vfsp;
    737  1.1  rvb     struct fid *fhp;
    738  1.1  rvb     struct mbuf *nam;
    739  1.1  rvb     struct vnode **vpp;
    740  1.1  rvb     int *exflagsp;
    741  1.1  rvb     struct ucred **creadanonp;
    742  1.1  rvb {
    743  1.1  rvb     struct cfid *cfid = (struct cfid *)fhp;
    744  1.1  rvb     struct cnode *cp = 0;
    745  1.1  rvb     int error;
    746  1.1  rvb     struct proc *p = curproc; /* XXX -mach */
    747  1.1  rvb     ViceFid VFid;
    748  1.1  rvb     int vtype;
    749  1.1  rvb 
    750  1.1  rvb     ENTRY;
    751  1.1  rvb 
    752  1.1  rvb     MARK_ENTRY(CFS_VGET_STATS);
    753  1.1  rvb     /* Check for vget of control object. */
    754  1.1  rvb     if (IS_CTL_FID(&cfid->cfid_fid)) {
    755  1.1  rvb 	*vpp = cfs_ctlvp;
    756  1.1  rvb 	vref(cfs_ctlvp);
    757  1.1  rvb 	MARK_INT_SAT(CFS_VGET_STATS);
    758  1.1  rvb 	return(0);
    759  1.1  rvb     }
    760  1.1  rvb 
    761  1.1  rvb     error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, p->p_cred->pc_ucred, p, &VFid, &vtype);
    762  1.1  rvb 
    763  1.1  rvb     if (error) {
    764  1.1  rvb 	CFSDEBUG(CFS_VGET, myprintf(("vget error %d\n",error));)
    765  1.1  rvb 	    *vpp = (struct vnode *)0;
    766  1.1  rvb     } else {
    767  1.1  rvb 	CFSDEBUG(CFS_VGET,
    768  1.1  rvb 		 myprintf(("vget: vol %lx vno %lx uni %lx type %d result %d\n",
    769  1.1  rvb 			VFid.Volume, VFid.Vnode, VFid.Unique, vtype, error)); )
    770  1.1  rvb 
    771  1.1  rvb 	cp = makecfsnode(&VFid, vfsp, vtype);
    772  1.1  rvb 	*vpp = CTOV(cp);
    773  1.1  rvb     }
    774  1.1  rvb     return(error);
    775  1.1  rvb }
    776  1.1  rvb 
    777  1.1  rvb int
    778  1.1  rvb cfs_vptofh(vnp, fidp)
    779  1.1  rvb     struct vnode *vnp;
    780  1.1  rvb     struct fid   *fidp;
    781  1.1  rvb {
    782  1.1  rvb     ENTRY;
    783  1.1  rvb     return (EOPNOTSUPP);
    784  1.1  rvb }
    785  1.1  rvb 
    786  1.1  rvb #ifdef	__NetBSD__
    787  1.1  rvb void
    788  1.1  rvb cfs_init(void)
    789  1.1  rvb {
    790  1.1  rvb     ENTRY;
    791  1.1  rvb }
    792  1.1  rvb #elif	defined(__FreeBSD__)
    793  1.1  rvb #ifdef	__FreeBSD_version
    794  1.1  rvb int
    795  1.1  rvb cfs_init(struct vfsconf *vfsp)
    796  1.1  rvb {
    797  1.1  rvb     ENTRY;
    798  1.1  rvb     return 0;
    799  1.1  rvb }
    800  1.1  rvb #else
    801  1.1  rvb int
    802  1.1  rvb cfs_init(void)
    803  1.1  rvb {
    804  1.1  rvb     ENTRY;
    805  1.1  rvb     return 0;
    806  1.1  rvb }
    807  1.1  rvb #endif
    808  1.1  rvb #endif
    809  1.1  rvb 
    810  1.1  rvb #if	defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 7)
    811  1.1  rvb int
    812  1.1  rvb cfs_sysctl(name, namelen, oldp, oldlp, newp, newl, p)
    813  1.1  rvb 	int *name;
    814  1.1  rvb 	u_int namelen;
    815  1.1  rvb 	void *oldp;
    816  1.1  rvb 	size_t *oldlp;
    817  1.1  rvb 	void *newp;
    818  1.1  rvb 	size_t newl;
    819  1.1  rvb 	struct proc *p;
    820  1.1  rvb {
    821  1.1  rvb 
    822  1.1  rvb 	/* all sysctl names at this level are terminal */
    823  1.1  rvb 	if (namelen != 1)
    824  1.1  rvb 		return (ENOTDIR);		/* overloaded */
    825  1.1  rvb 
    826  1.1  rvb 	switch (name[0]) {
    827  1.1  rvb /*
    828  1.1  rvb 	case FFS_CLUSTERREAD:
    829  1.1  rvb 		return (sysctl_int(oldp, oldlp, newp, newl, &doclusterread));
    830  1.1  rvb  */
    831  1.1  rvb 	default:
    832  1.1  rvb 		return (EOPNOTSUPP);
    833  1.1  rvb 	}
    834  1.1  rvb 	/* NOTREACHED */
    835  1.1  rvb }
    836  1.1  rvb #endif
    837  1.1  rvb 
    838  1.1  rvb /*
    839  1.1  rvb  * To allow for greater ease of use, some vnodes may be orphaned when
    840  1.1  rvb  * Venus dies.  Certain operations should still be allowed to go
    841  1.1  rvb  * through, but without propagating ophan-ness.  So this function will
    842  1.1  rvb  * get a new vnode for the file from the current run of Venus.  */
    843  1.1  rvb 
    844  1.1  rvb int
    845  1.1  rvb getNewVnode(vpp)
    846  1.1  rvb      struct vnode **vpp;
    847  1.1  rvb {
    848  1.1  rvb     struct cfid cfid;
    849  1.1  rvb     struct cfs_mntinfo *mi = vftomi((*vpp)->v_mount);
    850  1.1  rvb 
    851  1.1  rvb     ENTRY;
    852  1.1  rvb 
    853  1.1  rvb     cfid.cfid_len = (short)sizeof(ViceFid);
    854  1.1  rvb     cfid.cfid_fid = VTOC(*vpp)->c_fid;	/* Structure assignment. */
    855  1.1  rvb     /* XXX ? */
    856  1.1  rvb 
    857  1.1  rvb     /* We're guessing that if set, the 1st element on the list is a
    858  1.1  rvb      * valid vnode to use. If not, return ENODEV as venus is dead.
    859  1.1  rvb      */
    860  1.1  rvb     if (mi->mi_vfsp == NULL)
    861  1.1  rvb 	return ENODEV;
    862  1.1  rvb 
    863  1.1  rvb     return cfs_fhtovp(mi->mi_vfsp, (struct fid*)&cfid, NULL, vpp,
    864  1.1  rvb 		      NULL, NULL);
    865  1.1  rvb }
    866  1.1  rvb 
    867  1.1  rvb #include <ufs/ufs/quota.h>
    868  1.1  rvb #include <ufs/ufs/ufsmount.h>
    869  1.1  rvb /* get the mount structure corresponding to a given device.  Assume
    870  1.1  rvb  * device corresponds to a UFS. Return NULL if no device is found.
    871  1.1  rvb  */
    872  1.1  rvb struct mount *devtomp(dev)
    873  1.1  rvb     dev_t dev;
    874  1.1  rvb {
    875  1.1  rvb     struct mount *mp, *nmp;
    876  1.1  rvb 
    877  1.1  rvb     for (mp = mountlist.cqh_first; mp != (void*)&mountlist; mp = nmp) {
    878  1.1  rvb 	nmp = mp->mnt_list.cqe_next;
    879  1.1  rvb 	if (
    880  1.1  rvb #ifdef	__NetBSD__
    881  1.1  rvb 	    (!strcmp(mp->mnt_op->vfs_name, MOUNT_UFS)) &&
    882  1.1  rvb #endif
    883  1.1  rvb 	    ((VFSTOUFS(mp))->um_dev == (dev_t) dev)) {
    884  1.1  rvb 	    /* mount corresponds to UFS and the device matches one we want */
    885  1.1  rvb 	    return(mp);
    886  1.1  rvb 	}
    887  1.1  rvb     }
    888               /* mount structure wasn't found */
    889               return(NULL);
    890           }
    891