coda_vfsops.c revision 76166
138625Srvb/*
238759Srvb *
338759Srvb *             Coda: an Experimental Distributed File System
438759Srvb *                              Release 3.1
538759Srvb *
638759Srvb *           Copyright (c) 1987-1998 Carnegie Mellon University
738759Srvb *                          All Rights Reserved
838759Srvb *
938759Srvb * Permission  to  use, copy, modify and distribute this software and its
1038759Srvb * documentation is hereby granted,  provided  that  both  the  copyright
1138759Srvb * notice  and  this  permission  notice  appear  in  all  copies  of the
1238759Srvb * software, derivative works or  modified  versions,  and  any  portions
1338759Srvb * thereof, and that both notices appear in supporting documentation, and
1438759Srvb * that credit is given to Carnegie Mellon University  in  all  documents
1538759Srvb * and publicity pertaining to direct or indirect use of this code or its
1638759Srvb * derivatives.
1738759Srvb *
1838759Srvb * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS  KNOWN  TO  HAVE  BUGS,
1938759Srvb * SOME  OF  WHICH MAY HAVE SERIOUS CONSEQUENCES.  CARNEGIE MELLON ALLOWS
2038759Srvb * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.   CARNEGIE  MELLON
2138759Srvb * DISCLAIMS  ANY  LIABILITY  OF  ANY  KIND  FOR  ANY  DAMAGES WHATSOEVER
2238759Srvb * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE  OR  OF
2338759Srvb * ANY DERIVATIVE WORK.
2438759Srvb *
2538759Srvb * Carnegie  Mellon  encourages  users  of  this  software  to return any
2638759Srvb * improvements or extensions that  they  make,  and  to  grant  Carnegie
2738759Srvb * Mellon the rights to redistribute these changes without encumbrance.
2838759Srvb *
2939085Srvb *  	@(#) src/sys/cfs/coda_vfsops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
3050477Speter * $FreeBSD: head/sys/fs/coda/coda_vfsops.c 76166 2001-05-01 08:13:21Z markm $
3138759Srvb *
3238759Srvb */
3338625Srvb
3438625Srvb/*
3538625Srvb * Mach Operating System
3638625Srvb * Copyright (c) 1989 Carnegie-Mellon University
3738625Srvb * All rights reserved.  The CMU software License Agreement specifies
3838625Srvb * the terms and conditions for use and redistribution.
3938625Srvb */
4038625Srvb
4138625Srvb/*
4238625Srvb * This code was written for the Coda file system at Carnegie Mellon
4338625Srvb * University.  Contributers include David Steere, James Kistler, and
4438625Srvb * M. Satyanarayanan.
4538625Srvb */
4638625Srvb
4739085Srvb#include <vcoda.h>
4838625Srvb
4938625Srvb#include <sys/param.h>
5038625Srvb#include <sys/systm.h>
5176166Smarkm#include <sys/conf.h>
5238759Srvb#include <sys/kernel.h>
5376166Smarkm#include <sys/lock.h>
5438625Srvb#include <sys/malloc.h>
5576166Smarkm#include <sys/mount.h>
5638625Srvb#include <sys/namei.h>
5776166Smarkm#include <sys/proc.h>
5875877Smjacob#include <sys/socket.h>
5938625Srvb
6039126Srvb#include <coda/coda.h>
6139126Srvb#include <coda/cnode.h>
6239126Srvb#include <coda/coda_vfsops.h>
6339126Srvb#include <coda/coda_venus.h>
6439126Srvb#include <coda/coda_subr.h>
6539126Srvb#include <coda/coda_opstats.h>
6638759Srvb
6739085SrvbMALLOC_DEFINE(M_CODA, "CODA storage", "Various Coda Structures");
6838625Srvb
6939085Srvbint codadebug = 0;
7039085Srvbint coda_vfsop_print_entry = 0;
7139085Srvb#define ENTRY    if(coda_vfsop_print_entry) myprintf(("Entered %s\n",__FUNCTION__))
7238625Srvb
7339085Srvbstruct vnode *coda_ctlvp;
7439085Srvbstruct coda_mntinfo coda_mnttbl[NVCODA]; /* indexed by minor device number */
7538625Srvb
7638625Srvb/* structure to keep statistics of internally generated/satisfied calls */
7738625Srvb
7839085Srvbstruct coda_op_stats coda_vfsopstats[CODA_VFSOPS_SIZE];
7938625Srvb
8039085Srvb#define MARK_ENTRY(op) (coda_vfsopstats[op].entries++)
8139085Srvb#define MARK_INT_SAT(op) (coda_vfsopstats[op].sat_intrn++)
8239085Srvb#define MARK_INT_FAIL(op) (coda_vfsopstats[op].unsat_intrn++)
8339085Srvb#define MRAK_INT_GEN(op) (coda_vfsopstats[op].gen_intrn++)
8438625Srvb
8539085Srvbextern int coda_nc_initialized;     /* Set if cache has been initialized */
8638625Srvbextern int vc_nb_open __P((dev_t, int, int, struct proc *));
8738625Srvb
8838625Srvbint
8939085Srvbcoda_vfsopstats_init(void)
9038625Srvb{
9138625Srvb	register int i;
9238625Srvb
9339085Srvb	for (i=0;i<CODA_VFSOPS_SIZE;i++) {
9439085Srvb		coda_vfsopstats[i].opcode = i;
9539085Srvb		coda_vfsopstats[i].entries = 0;
9639085Srvb		coda_vfsopstats[i].sat_intrn = 0;
9739085Srvb		coda_vfsopstats[i].unsat_intrn = 0;
9839085Srvb		coda_vfsopstats[i].gen_intrn = 0;
9938625Srvb	}
10038625Srvb
10138625Srvb	return 0;
10238625Srvb}
10338625Srvb
10438625Srvb/*
10538625Srvb * cfs mount vfsop
10638625Srvb * Set up mount info record and attach it to vfs struct.
10738625Srvb */
10838625Srvb/*ARGSUSED*/
10938625Srvbint
11039085Srvbcoda_mount(vfsp, path, data, ndp, p)
11138625Srvb    struct mount *vfsp;		/* Allocated and initialized by mount(2) */
11238625Srvb    char *path;			/* path covered: ignored by the fs-layer */
11338625Srvb    caddr_t data;		/* Need to define a data type for this in netbsd? */
11438625Srvb    struct nameidata *ndp;	/* Clobber this to lookup the device name */
11538625Srvb    struct proc *p;		/* The ever-famous proc pointer */
11638625Srvb{
11738625Srvb    struct vnode *dvp;
11838625Srvb    struct cnode *cp;
11938625Srvb    dev_t dev;
12039085Srvb    struct coda_mntinfo *mi;
12138625Srvb    struct vnode *rootvp;
12238625Srvb    ViceFid rootfid;
12338625Srvb    ViceFid ctlfid;
12438625Srvb    int error;
12538625Srvb
12638625Srvb    ENTRY;
12738625Srvb
12839085Srvb    coda_vfsopstats_init();
12939085Srvb    coda_vnodeopstats_init();
13038625Srvb
13139085Srvb    MARK_ENTRY(CODA_MOUNT_STATS);
13239085Srvb    if (CODA_MOUNTED(vfsp)) {
13339085Srvb	MARK_INT_FAIL(CODA_MOUNT_STATS);
13438625Srvb	return(EBUSY);
13538625Srvb    }
13638625Srvb
13738625Srvb    /* Validate mount device.  Similar to getmdev(). */
13838625Srvb    NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, data, p);
13938625Srvb    error = namei(ndp);
14038625Srvb    dvp = ndp->ni_vp;
14138625Srvb
14238625Srvb    if (error) {
14339085Srvb	MARK_INT_FAIL(CODA_MOUNT_STATS);
14438625Srvb	return (error);
14538625Srvb    }
14638625Srvb    if (dvp->v_type != VCHR) {
14739085Srvb	MARK_INT_FAIL(CODA_MOUNT_STATS);
14838625Srvb	vrele(dvp);
14954655Seivind	NDFREE(ndp, NDF_ONLY_PNBUF);
15038625Srvb	return(ENXIO);
15138625Srvb    }
15248926Sphk    dev = dvp->v_rdev;
15338625Srvb    vrele(dvp);
15454655Seivind    NDFREE(ndp, NDF_ONLY_PNBUF);
15538625Srvb
15638625Srvb    /*
15738625Srvb     * See if the device table matches our expectations.
15838625Srvb     */
15946676Sphk    if (devsw(dev)->d_open != vc_nb_open)
16038625Srvb    {
16139085Srvb	MARK_INT_FAIL(CODA_MOUNT_STATS);
16238625Srvb	return(ENXIO);
16338625Srvb    }
16438625Srvb
16539085Srvb    if (minor(dev) >= NVCODA || minor(dev) < 0) {
16639085Srvb	MARK_INT_FAIL(CODA_MOUNT_STATS);
16738625Srvb	return(ENXIO);
16838625Srvb    }
16938625Srvb
17038625Srvb    /*
17138625Srvb     * Initialize the mount record and link it to the vfs struct
17238625Srvb     */
17339085Srvb    mi = &coda_mnttbl[minor(dev)];
17438625Srvb
17538625Srvb    if (!VC_OPEN(&mi->mi_vcomm)) {
17639085Srvb	MARK_INT_FAIL(CODA_MOUNT_STATS);
17738625Srvb	return(ENODEV);
17838625Srvb    }
17938625Srvb
18038625Srvb    /* No initialization (here) of mi_vcomm! */
18138625Srvb    vfsp->mnt_data = (qaddr_t)mi;
18238625Srvb    vfs_getnewfsid (vfsp);
18338625Srvb
18438625Srvb    mi->mi_vfsp = vfsp;
18538625Srvb
18638625Srvb    /*
18738625Srvb     * Make a root vnode to placate the Vnode interface, but don't
18839085Srvb     * actually make the CODA_ROOT call to venus until the first call
18939085Srvb     * to coda_root in case a server is down while venus is starting.
19038625Srvb     */
19138625Srvb    rootfid.Volume = 0;
19238625Srvb    rootfid.Vnode = 0;
19338625Srvb    rootfid.Unique = 0;
19439085Srvb    cp = make_coda_node(&rootfid, vfsp, VDIR);
19538625Srvb    rootvp = CTOV(cp);
19638625Srvb    rootvp->v_flag |= VROOT;
19738625Srvb
19838625Srvb    ctlfid.Volume = CTL_VOL;
19938625Srvb    ctlfid.Vnode = CTL_VNO;
20038625Srvb    ctlfid.Unique = CTL_UNI;
20139085Srvb/*  cp = make_coda_node(&ctlfid, vfsp, VCHR);
20238625Srvb    The above code seems to cause a loop in the cnode links.
20338625Srvb    I don't totally understand when it happens, it is caught
20438625Srvb    when closing down the system.
20538625Srvb */
20639085Srvb    cp = make_coda_node(&ctlfid, 0, VCHR);
20738625Srvb
20839085Srvb    coda_ctlvp = CTOV(cp);
20938625Srvb
21038625Srvb    /* Add vfs and rootvp to chain of vfs hanging off mntinfo */
21138625Srvb    mi->mi_vfsp = vfsp;
21238625Srvb    mi->mi_rootvp = rootvp;
21338625Srvb
21438625Srvb    /* set filesystem block size */
21538625Srvb    vfsp->mnt_stat.f_bsize = 8192;	    /* XXX -JJK */
21638759Srvb
21738625Srvb    /* Set f_iosize.  XXX -- inamura@isl.ntt.co.jp.
21838625Srvb       For vnode_pager_haspage() references. The value should be obtained
21938625Srvb       from underlying UFS. */
22038625Srvb    /* Checked UFS. iosize is set as 8192 */
22138625Srvb    vfsp->mnt_stat.f_iosize = 8192;
22238625Srvb
22338625Srvb    /* error is currently guaranteed to be zero, but in case some
22438625Srvb       code changes... */
22539085Srvb    CODADEBUG(1,
22639085Srvb	     myprintf(("coda_mount returned %d\n",error)););
22738625Srvb    if (error)
22839085Srvb	MARK_INT_FAIL(CODA_MOUNT_STATS);
22938625Srvb    else
23039085Srvb	MARK_INT_SAT(CODA_MOUNT_STATS);
23138625Srvb
23238625Srvb    return(error);
23338625Srvb}
23438625Srvb
23538625Srvbint
23639085Srvbcoda_unmount(vfsp, mntflags, p)
23738625Srvb    struct mount *vfsp;
23838625Srvb    int mntflags;
23938625Srvb    struct proc *p;
24038625Srvb{
24139085Srvb    struct coda_mntinfo *mi = vftomi(vfsp);
24238625Srvb    int active, error = 0;
24338625Srvb
24438625Srvb    ENTRY;
24539085Srvb    MARK_ENTRY(CODA_UMOUNT_STATS);
24639085Srvb    if (!CODA_MOUNTED(vfsp)) {
24739085Srvb	MARK_INT_FAIL(CODA_UMOUNT_STATS);
24838625Srvb	return(EINVAL);
24938625Srvb    }
25038625Srvb
25138625Srvb    if (mi->mi_vfsp == vfsp) {	/* We found the victim */
25238625Srvb	if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp)))
25338625Srvb	    return (EBUSY); 	/* Venus is still running */
25438625Srvb
25538625Srvb#ifdef	DEBUG
25639085Srvb	printf("coda_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp));
25738625Srvb#endif
25838625Srvb	vrele(mi->mi_rootvp);
25938625Srvb
26039085Srvb	active = coda_kill(vfsp, NOT_DOWNCALL);
26141202Srvb	mi->mi_rootvp->v_flag &= ~VROOT;
26238625Srvb	error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE);
26339085Srvb	printf("coda_unmount: active = %d, vflush active %d\n", active, error);
26438625Srvb	error = 0;
26538625Srvb	/* I'm going to take this out to allow lookups to go through. I'm
26638625Srvb	 * not sure it's important anyway. -- DCS 2/2/94
26738625Srvb	 */
26838625Srvb	/* vfsp->VFS_DATA = NULL; */
26938625Srvb
27038625Srvb	/* No more vfsp's to hold onto */
27138625Srvb	mi->mi_vfsp = NULL;
27238625Srvb	mi->mi_rootvp = NULL;
27338625Srvb
27438625Srvb	if (error)
27539085Srvb	    MARK_INT_FAIL(CODA_UMOUNT_STATS);
27638625Srvb	else
27739085Srvb	    MARK_INT_SAT(CODA_UMOUNT_STATS);
27838625Srvb
27938625Srvb	return(error);
28038625Srvb    }
28138625Srvb    return (EINVAL);
28238625Srvb}
28338625Srvb
28438625Srvb/*
28538625Srvb * find root of cfs
28638625Srvb */
28738625Srvbint
28839085Srvbcoda_root(vfsp, vpp)
28938625Srvb	struct mount *vfsp;
29038625Srvb	struct vnode **vpp;
29138625Srvb{
29239085Srvb    struct coda_mntinfo *mi = vftomi(vfsp);
29338625Srvb    struct vnode **result;
29438625Srvb    int error;
29538625Srvb    struct proc *p = curproc;    /* XXX - bnoble */
29638625Srvb    ViceFid VFid;
29738625Srvb
29838625Srvb    ENTRY;
29939085Srvb    MARK_ENTRY(CODA_ROOT_STATS);
30038625Srvb    result = NULL;
30138625Srvb
30238625Srvb    if (vfsp == mi->mi_vfsp) {
30338625Srvb	if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) ||
30438625Srvb	    (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) ||
30538625Srvb	    (VTOC(mi->mi_rootvp)->c_fid.Unique != 0))
30638625Srvb	    { /* Found valid root. */
30738625Srvb		*vpp = mi->mi_rootvp;
30838625Srvb		/* On Mach, this is vref.  On NetBSD, VOP_LOCK */
30938759Srvb#if	1
31038625Srvb		vref(*vpp);
31138759Srvb		vn_lock(*vpp, LK_EXCLUSIVE, p);
31238759Srvb#else
31338759Srvb		vget(*vpp, LK_EXCLUSIVE, p);
31438759Srvb#endif
31539085Srvb		MARK_INT_SAT(CODA_ROOT_STATS);
31638625Srvb		return(0);
31738625Srvb	    }
31838625Srvb    }
31938625Srvb
32071699Sjhb    error = venus_root(vftomi(vfsp), p->p_ucred, p, &VFid);
32138625Srvb
32238625Srvb    if (!error) {
32338625Srvb	/*
32438625Srvb	 * Save the new rootfid in the cnode, and rehash the cnode into the
32538625Srvb	 * cnode hash with the new fid key.
32638625Srvb	 */
32739085Srvb	coda_unsave(VTOC(mi->mi_rootvp));
32838625Srvb	VTOC(mi->mi_rootvp)->c_fid = VFid;
32939085Srvb	coda_save(VTOC(mi->mi_rootvp));
33038625Srvb
33138625Srvb	*vpp = mi->mi_rootvp;
33238759Srvb#if	1
33338625Srvb	vref(*vpp);
33438759Srvb	vn_lock(*vpp, LK_EXCLUSIVE, p);
33538759Srvb#else
33638759Srvb	vget(*vpp, LK_EXCLUSIVE, p);
33738759Srvb#endif
33838759Srvb
33939085Srvb	MARK_INT_SAT(CODA_ROOT_STATS);
34038625Srvb	goto exit;
34141202Srvb    } else if (error == ENODEV || error == EINTR) {
34238625Srvb	/* Gross hack here! */
34338625Srvb	/*
34439085Srvb	 * If Venus fails to respond to the CODA_ROOT call, coda_call returns
34538625Srvb	 * ENODEV. Return the uninitialized root vnode to allow vfs
34638625Srvb	 * operations such as unmount to continue. Without this hack,
34738625Srvb	 * there is no way to do an unmount if Venus dies before a
34839085Srvb	 * successful CODA_ROOT call is done. All vnode operations
34938625Srvb	 * will fail.
35038625Srvb	 */
35138625Srvb	*vpp = mi->mi_rootvp;
35238759Srvb#if	1
35338625Srvb	vref(*vpp);
35438759Srvb	vn_lock(*vpp, LK_EXCLUSIVE, p);
35538759Srvb#else
35638759Srvb	vget(*vpp, LK_EXCLUSIVE, p);
35738759Srvb#endif
35838759Srvb
35939085Srvb	MARK_INT_FAIL(CODA_ROOT_STATS);
36038625Srvb	error = 0;
36138625Srvb	goto exit;
36238625Srvb    } else {
36339085Srvb	CODADEBUG( CODA_ROOT, myprintf(("error %d in CODA_ROOT\n", error)); );
36439085Srvb	MARK_INT_FAIL(CODA_ROOT_STATS);
36538625Srvb
36638625Srvb	goto exit;
36738625Srvb    }
36838759Srvb
36938625Srvb exit:
37038625Srvb    return(error);
37138625Srvb}
37238625Srvb
37338625Srvb/*
37438625Srvb * Get file system statistics.
37538625Srvb */
37638625Srvbint
37739085Srvbcoda_nb_statfs(vfsp, sbp, p)
37838625Srvb    register struct mount *vfsp;
37938625Srvb    struct statfs *sbp;
38038625Srvb    struct proc *p;
38138625Srvb{
38238625Srvb    ENTRY;
38339085Srvb/*  MARK_ENTRY(CODA_STATFS_STATS); */
38439085Srvb    if (!CODA_MOUNTED(vfsp)) {
38539085Srvb/*	MARK_INT_FAIL(CODA_STATFS_STATS);*/
38638625Srvb	return(EINVAL);
38738625Srvb    }
38838625Srvb
38938625Srvb    bzero(sbp, sizeof(struct statfs));
39038625Srvb    /* XXX - what to do about f_flags, others? --bnoble */
39138625Srvb    /* Below This is what AFS does
39238625Srvb    	#define NB_SFS_SIZ 0x895440
39338625Srvb     */
39438625Srvb    /* Note: Normal fs's have a bsize of 0x400 == 1024 */
39538909Sbde    sbp->f_type = vfsp->mnt_vfc->vfc_typenum;
39638625Srvb    sbp->f_bsize = 8192; /* XXX */
39738625Srvb    sbp->f_iosize = 8192; /* XXX */
39838625Srvb#define NB_SFS_SIZ 0x8AB75D
39938625Srvb    sbp->f_blocks = NB_SFS_SIZ;
40038625Srvb    sbp->f_bfree = NB_SFS_SIZ;
40138625Srvb    sbp->f_bavail = NB_SFS_SIZ;
40238625Srvb    sbp->f_files = NB_SFS_SIZ;
40338625Srvb    sbp->f_ffree = NB_SFS_SIZ;
40438625Srvb    bcopy((caddr_t)&(vfsp->mnt_stat.f_fsid), (caddr_t)&(sbp->f_fsid), sizeof (fsid_t));
40541514Sarchie    snprintf(sbp->f_mntonname, sizeof(sbp->f_mntonname), "/coda");
40641514Sarchie    snprintf(sbp->f_mntfromname, sizeof(sbp->f_mntfromname), "CODA");
40739085Srvb/*  MARK_INT_SAT(CODA_STATFS_STATS); */
40838625Srvb    return(0);
40938625Srvb}
41038625Srvb
41138625Srvb/*
41238625Srvb * Flush any pending I/O.
41338625Srvb */
41438625Srvbint
41539085Srvbcoda_sync(vfsp, waitfor, cred, p)
41638625Srvb    struct mount *vfsp;
41738625Srvb    int    waitfor;
41838625Srvb    struct ucred *cred;
41938625Srvb    struct proc *p;
42038625Srvb{
42138625Srvb    ENTRY;
42239085Srvb    MARK_ENTRY(CODA_SYNC_STATS);
42339085Srvb    MARK_INT_SAT(CODA_SYNC_STATS);
42438625Srvb    return(0);
42538625Srvb}
42638625Srvb
42738625Srvb/*
42838625Srvb * fhtovp is now what vget used to be in 4.3-derived systems.  For
42938625Srvb * some silly reason, vget is now keyed by a 32 bit ino_t, rather than
43038625Srvb * a type-specific fid.
43138625Srvb */
43238625Srvbint
43339085Srvbcoda_fhtovp(vfsp, fhp, nam, vpp, exflagsp, creadanonp)
43438625Srvb    register struct mount *vfsp;
43538625Srvb    struct fid *fhp;
43638625Srvb    struct mbuf *nam;
43738625Srvb    struct vnode **vpp;
43838625Srvb    int *exflagsp;
43938625Srvb    struct ucred **creadanonp;
44038625Srvb{
44138625Srvb    struct cfid *cfid = (struct cfid *)fhp;
44238625Srvb    struct cnode *cp = 0;
44338625Srvb    int error;
44438625Srvb    struct proc *p = curproc; /* XXX -mach */
44538625Srvb    ViceFid VFid;
44638625Srvb    int vtype;
44738625Srvb
44838625Srvb    ENTRY;
44938625Srvb
45039085Srvb    MARK_ENTRY(CODA_VGET_STATS);
45138625Srvb    /* Check for vget of control object. */
45238625Srvb    if (IS_CTL_FID(&cfid->cfid_fid)) {
45339085Srvb	*vpp = coda_ctlvp;
45439085Srvb	vref(coda_ctlvp);
45539085Srvb	MARK_INT_SAT(CODA_VGET_STATS);
45638625Srvb	return(0);
45738625Srvb    }
45838625Srvb
45971699Sjhb    error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, p->p_ucred, p, &VFid, &vtype);
46038625Srvb
46138625Srvb    if (error) {
46239085Srvb	CODADEBUG(CODA_VGET, myprintf(("vget error %d\n",error));)
46338625Srvb	    *vpp = (struct vnode *)0;
46438625Srvb    } else {
46539085Srvb	CODADEBUG(CODA_VGET,
46638625Srvb		 myprintf(("vget: vol %lx vno %lx uni %lx type %d result %d\n",
46738625Srvb			VFid.Volume, VFid.Vnode, VFid.Unique, vtype, error)); )
46838625Srvb
46939085Srvb	cp = make_coda_node(&VFid, vfsp, vtype);
47038625Srvb	*vpp = CTOV(cp);
47138625Srvb    }
47238625Srvb    return(error);
47338625Srvb}
47438625Srvb
47538625Srvb/*
47638625Srvb * To allow for greater ease of use, some vnodes may be orphaned when
47738625Srvb * Venus dies.  Certain operations should still be allowed to go
47838625Srvb * through, but without propagating ophan-ness.  So this function will
47938625Srvb * get a new vnode for the file from the current run of Venus.  */
48038625Srvb
48138625Srvbint
48238625SrvbgetNewVnode(vpp)
48338625Srvb     struct vnode **vpp;
48438625Srvb{
48538625Srvb    struct cfid cfid;
48639085Srvb    struct coda_mntinfo *mi = vftomi((*vpp)->v_mount);
48738625Srvb
48838625Srvb    ENTRY;
48938625Srvb
49038625Srvb    cfid.cfid_len = (short)sizeof(ViceFid);
49138625Srvb    cfid.cfid_fid = VTOC(*vpp)->c_fid;	/* Structure assignment. */
49238625Srvb    /* XXX ? */
49338625Srvb
49438625Srvb    /* We're guessing that if set, the 1st element on the list is a
49538625Srvb     * valid vnode to use. If not, return ENODEV as venus is dead.
49638625Srvb     */
49738625Srvb    if (mi->mi_vfsp == NULL)
49838625Srvb	return ENODEV;
49938625Srvb
50039085Srvb    return coda_fhtovp(mi->mi_vfsp, (struct fid*)&cfid, NULL, vpp,
50138625Srvb		      NULL, NULL);
50238625Srvb}
50338625Srvb
50459241Srwatson#include <ufs/ufs/extattr.h>
50538625Srvb#include <ufs/ufs/quota.h>
50638625Srvb#include <ufs/ufs/ufsmount.h>
50738625Srvb/* get the mount structure corresponding to a given device.  Assume
50838625Srvb * device corresponds to a UFS. Return NULL if no device is found.
50938625Srvb */
51038625Srvbstruct mount *devtomp(dev)
51138625Srvb    dev_t dev;
51238625Srvb{
51353452Sphk    struct mount *mp;
51453452Sphk
51553452Sphk    TAILQ_FOREACH(mp, &mountlist, mnt_list) {
51646795Sphk	if (((VFSTOUFS(mp))->um_dev == dev)) {
51738625Srvb	    /* mount corresponds to UFS and the device matches one we want */
51838625Srvb	    return(mp);
51938625Srvb	}
52038625Srvb    }
52138625Srvb    /* mount structure wasn't found */
52238625Srvb    return(NULL);
52338625Srvb}
52439650Srvb
52539650Srvbstruct vfsops coda_vfsops = {
52639650Srvb    coda_mount,
52751068Salfred    vfs_stdstart,
52839650Srvb    coda_unmount,
52939650Srvb    coda_root,
53051068Salfred    vfs_stdquotactl,
53139650Srvb    coda_nb_statfs,
53239650Srvb    coda_sync,
53351068Salfred    vfs_stdvget,
53451068Salfred    vfs_stdfhtovp,
53551138Salfred    vfs_stdcheckexp,
53651068Salfred    vfs_stdvptofh,
53754803Srwatson    vfs_stdinit,
53854803Srwatson    vfs_stduninit,
53954803Srwatson    vfs_stdextattrctl,
54039650Srvb};
54139650Srvb
54239650SrvbVFS_SET(coda_vfsops, coda, VFCF_NETWORK);
543