coda_vfsops.c revision 39085
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 $ 3039085Srvb * $Id: coda_vfsops.c,v 1.2 1998/09/02 19:09:53 rvb Exp $ 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 4738625Srvb/* 4838625Srvb * HISTORY 4939085Srvb * $Log: coda_vfsops.c,v $ 5038909Sbde * Revision 1.2 1998/09/02 19:09:53 rvb 5138909Sbde * Pass2 complete 5238909Sbde * 5338759Srvb * Revision 1.1.1.1 1998/08/29 21:14:52 rvb 5438759Srvb * Very Preliminary Coda 5538759Srvb * 5638625Srvb * Revision 1.11 1998/08/28 18:12:22 rvb 5738625Srvb * Now it also works on FreeBSD -current. This code will be 5838625Srvb * committed to the FreeBSD -current and NetBSD -current 5938625Srvb * trees. It will then be tailored to the particular platform 6038625Srvb * by flushing conditional code. 6138625Srvb * 6238625Srvb * Revision 1.10 1998/08/18 17:05:19 rvb 6338625Srvb * Don't use __RCSID now 6438625Srvb * 6538625Srvb * Revision 1.9 1998/08/18 16:31:44 rvb 6638625Srvb * Sync the code for NetBSD -current; test on 1.3 later 6738625Srvb * 6838625Srvb * Revision 1.8 98/02/24 22:22:48 rvb 6938625Srvb * Fixes up mainly to flush iopen and friends 7038625Srvb * 7138625Srvb * Revision 1.7 98/01/23 11:53:45 rvb 7239085Srvb * Bring RVB_CODA1_1 to HEAD 7338625Srvb * 7438625Srvb * Revision 1.6.2.6 98/01/23 11:21:07 rvb 7538625Srvb * Sync with 2.2.5 7638625Srvb * 7738625Srvb * Revision 1.6.2.5 98/01/22 13:05:33 rvb 7839085Srvb * Move make_coda_node ctlfid later so vfsp is known 7938625Srvb * 8038625Srvb * Revision 1.6.2.4 97/12/19 14:26:05 rvb 8138625Srvb * session id 8238625Srvb * 8338625Srvb * Revision 1.6.2.3 97/12/16 12:40:11 rvb 8438625Srvb * Sync with 1.3 8538625Srvb * 8638625Srvb * Revision 1.6.2.2 97/12/10 11:40:25 rvb 8738625Srvb * No more ody 8838625Srvb * 8938625Srvb * Revision 1.6.2.1 97/12/06 17:41:24 rvb 9038625Srvb * Sync with peters coda.h 9138625Srvb * 9238625Srvb * Revision 1.6 97/12/05 10:39:21 rvb 9338625Srvb * Read CHANGES 9438625Srvb * 9538625Srvb * Revision 1.5.14.8 97/11/24 15:44:46 rvb 9638625Srvb * Final cfs_venus.c w/o macros, but one locking bug 9738625Srvb * 9838625Srvb * Revision 1.5.14.7 97/11/21 13:22:03 rvb 9939085Srvb * Catch a few coda_calls in coda_vfsops.c 10038625Srvb * 10138625Srvb * Revision 1.5.14.6 97/11/20 11:46:48 rvb 10238625Srvb * Capture current cfs_venus 10338625Srvb * 10438625Srvb * Revision 1.5.14.5 97/11/18 10:27:17 rvb 10538625Srvb * cfs_nbsd.c is DEAD!!!; integrated into cfs_vf/vnops.c 10638625Srvb * cfs_nb_foo and cfs_foo are joined 10738625Srvb * 10838625Srvb * Revision 1.5.14.4 97/11/13 22:03:01 rvb 10938625Srvb * pass2 cfs_NetBSD.h mt 11038625Srvb * 11138625Srvb * Revision 1.5.14.3 97/11/12 12:09:40 rvb 11238625Srvb * reorg pass1 11338625Srvb * 11438625Srvb * Revision 1.5.14.2 97/10/29 16:06:28 rvb 11538625Srvb * Kill DYING 11638625Srvb * 11738625Srvb * Revision 1.5.14.1 1997/10/28 23:10:17 rvb 11838625Srvb * >64Meg; venus can be killed! 11938625Srvb * 12038625Srvb * Revision 1.5 1997/01/13 17:11:07 bnoble 12138625Srvb * Coda statfs needs to return something other than -1 for blocks avail. and 12238625Srvb * files available for wabi (and other windowsish) programs to install 12338625Srvb * there correctly. 12438625Srvb * 12538625Srvb * Revision 1.4 1996/12/12 22:11:00 bnoble 12638625Srvb * Fixed the "downcall invokes venus operation" deadlock in all known cases. 12738625Srvb * There may be more 12838625Srvb * 12938625Srvb * Revision 1.3 1996/11/08 18:06:12 bnoble 13038625Srvb * Minor changes in vnode operation signature, VOP_UPDATE signature, and 13138625Srvb * some newly defined bits in the include files. 13238625Srvb * 13338625Srvb * Revision 1.2 1996/01/02 16:57:04 bnoble 13438625Srvb * Added support for Coda MiniCache and raw inode calls (final commit) 13538625Srvb * 13638625Srvb * Revision 1.1.2.1 1995/12/20 01:57:32 bnoble 13739085Srvb * Added CODA-specific files 13838625Srvb * 13938625Srvb * Revision 3.1.1.1 1995/03/04 19:08:02 bnoble 14038625Srvb * Branch for NetBSD port revisions 14138625Srvb * 14238625Srvb * Revision 3.1 1995/03/04 19:08:01 bnoble 14338625Srvb * Bump to major revision 3 to prepare for NetBSD port 14438625Srvb * 14538625Srvb * Revision 2.4 1995/02/17 16:25:22 dcs 14638625Srvb * These versions represent several changes: 14738625Srvb * 1. Allow venus to restart even if outstanding references exist. 14838625Srvb * 2. Have only one ctlvp per client, as opposed to one per mounted cfs device.d 14938625Srvb * 3. Allow ody_expand to return many members, not just one. 15038625Srvb * 15138625Srvb * Revision 2.3 94/10/14 09:58:21 dcs 15238625Srvb * Made changes 'cause sun4s have braindead compilers 15338625Srvb * 15438625Srvb * Revision 2.2 94/10/12 16:46:33 dcs 15538625Srvb * Cleaned kernel/venus interface by removing XDR junk, plus 15638625Srvb * so cleanup to allow this code to be more easily ported. 15738625Srvb * 15838625Srvb * Revision 1.3 93/05/28 16:24:29 bnoble 15938625Srvb * *** empty log message *** 16038625Srvb * 16138625Srvb * Revision 1.2 92/10/27 17:58:24 lily 16238625Srvb * merge kernel/latest and alpha/src/cfs 16338625Srvb * 16438625Srvb * Revision 2.3 92/09/30 14:16:32 mja 16539085Srvb * Added call to coda_flush to coda_unmount. 16638625Srvb * [90/12/15 dcs] 16738625Srvb * 16838625Srvb * Added contributors blurb. 16938625Srvb * [90/12/13 jjk] 17038625Srvb * 17138625Srvb * Revision 2.2 90/07/05 11:26:40 mrt 17238625Srvb * Created for the Coda File System. 17338625Srvb * [90/05/23 dcs] 17438625Srvb * 17538625Srvb * Revision 1.3 90/05/31 17:01:42 dcs 17638625Srvb * Prepare for merge with facilities kernel. 17738625Srvb * 17838625Srvb * 17938625Srvb */ 18039085Srvb#include <vcoda.h> 18138625Srvb 18238625Srvb#include <sys/param.h> 18338625Srvb#include <sys/systm.h> 18438759Srvb#include <sys/kernel.h> 18538759Srvb#include <sys/proc.h> 18638625Srvb#include <sys/malloc.h> 18738625Srvb#include <sys/conf.h> 18838625Srvb#include <sys/namei.h> 18938625Srvb#include <sys/mount.h> 19038625Srvb#include <sys/select.h> 19138625Srvb 19238625Srvb#include <cfs/coda.h> 19338625Srvb#include <cfs/cnode.h> 19438625Srvb#include <cfs/cfs_vfsops.h> 19538625Srvb#include <cfs/cfs_venus.h> 19638625Srvb#include <cfs/cfs_subr.h> 19738625Srvb#include <cfs/coda_opstats.h> 19838759Srvb 19938625Srvb#include <miscfs/specfs/specdev.h> 20038625Srvb 20139085SrvbMALLOC_DEFINE(M_CODA, "CODA storage", "Various Coda Structures"); 20238625Srvb 20339085Srvbint codadebug = 0; 20439085Srvbint coda_vfsop_print_entry = 0; 20539085Srvb#define ENTRY if(coda_vfsop_print_entry) myprintf(("Entered %s\n",__FUNCTION__)) 20638625Srvb 20739085Srvbstruct vnode *coda_ctlvp; 20839085Srvbstruct coda_mntinfo coda_mnttbl[NVCODA]; /* indexed by minor device number */ 20938625Srvb 21038625Srvb/* structure to keep statistics of internally generated/satisfied calls */ 21138625Srvb 21239085Srvbstruct coda_op_stats coda_vfsopstats[CODA_VFSOPS_SIZE]; 21338625Srvb 21439085Srvb#define MARK_ENTRY(op) (coda_vfsopstats[op].entries++) 21539085Srvb#define MARK_INT_SAT(op) (coda_vfsopstats[op].sat_intrn++) 21639085Srvb#define MARK_INT_FAIL(op) (coda_vfsopstats[op].unsat_intrn++) 21739085Srvb#define MRAK_INT_GEN(op) (coda_vfsopstats[op].gen_intrn++) 21838625Srvb 21939085Srvbextern int coda_nc_initialized; /* Set if cache has been initialized */ 22038625Srvbextern int vc_nb_open __P((dev_t, int, int, struct proc *)); 22138625Srvb 22239085Srvbstruct vfsops coda_vfsops = { 22339085Srvb coda_mount, 22439085Srvb coda_start, 22539085Srvb coda_unmount, 22639085Srvb coda_root, 22739085Srvb coda_quotactl, 22839085Srvb coda_nb_statfs, 22939085Srvb coda_sync, 23039085Srvb coda_vget, 23138625Srvb (int (*) (struct mount *, struct fid *, struct sockaddr *, struct vnode **, 23238625Srvb int *, struct ucred **)) 23338625Srvb eopnotsupp, 23438625Srvb (int (*) (struct vnode *, struct fid *)) eopnotsupp, 23539085Srvb coda_init, 23638625Srvb}; 23738625Srvb 23839085SrvbVFS_SET(coda_vfsops, coda, VFCF_NETWORK); 23938625Srvb 24038625Srvbint 24139085Srvbcoda_vfsopstats_init(void) 24238625Srvb{ 24338625Srvb register int i; 24438625Srvb 24539085Srvb for (i=0;i<CODA_VFSOPS_SIZE;i++) { 24639085Srvb coda_vfsopstats[i].opcode = i; 24739085Srvb coda_vfsopstats[i].entries = 0; 24839085Srvb coda_vfsopstats[i].sat_intrn = 0; 24939085Srvb coda_vfsopstats[i].unsat_intrn = 0; 25039085Srvb coda_vfsopstats[i].gen_intrn = 0; 25138625Srvb } 25238625Srvb 25338625Srvb return 0; 25438625Srvb} 25538625Srvb 25638625Srvb/* 25738625Srvb * cfs mount vfsop 25838625Srvb * Set up mount info record and attach it to vfs struct. 25938625Srvb */ 26038625Srvb/*ARGSUSED*/ 26138625Srvbint 26239085Srvbcoda_mount(vfsp, path, data, ndp, p) 26338625Srvb struct mount *vfsp; /* Allocated and initialized by mount(2) */ 26438625Srvb char *path; /* path covered: ignored by the fs-layer */ 26538625Srvb caddr_t data; /* Need to define a data type for this in netbsd? */ 26638625Srvb struct nameidata *ndp; /* Clobber this to lookup the device name */ 26738625Srvb struct proc *p; /* The ever-famous proc pointer */ 26838625Srvb{ 26938625Srvb struct vnode *dvp; 27038625Srvb struct cnode *cp; 27138625Srvb dev_t dev; 27239085Srvb struct coda_mntinfo *mi; 27338625Srvb struct vnode *rootvp; 27438625Srvb ViceFid rootfid; 27538625Srvb ViceFid ctlfid; 27638625Srvb int error; 27738625Srvb 27838625Srvb ENTRY; 27938625Srvb 28039085Srvb coda_vfsopstats_init(); 28139085Srvb coda_vnodeopstats_init(); 28238625Srvb 28339085Srvb MARK_ENTRY(CODA_MOUNT_STATS); 28439085Srvb if (CODA_MOUNTED(vfsp)) { 28539085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 28638625Srvb return(EBUSY); 28738625Srvb } 28838625Srvb 28938625Srvb /* Validate mount device. Similar to getmdev(). */ 29038625Srvb 29138625Srvb NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, data, p); 29238625Srvb error = namei(ndp); 29338625Srvb dvp = ndp->ni_vp; 29438625Srvb 29538625Srvb if (error) { 29639085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 29738625Srvb return (error); 29838625Srvb } 29938625Srvb if (dvp->v_type != VCHR) { 30039085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 30138625Srvb vrele(dvp); 30238625Srvb return(ENXIO); 30338625Srvb } 30438625Srvb dev = dvp->v_specinfo->si_rdev; 30538625Srvb vrele(dvp); 30638625Srvb if (major(dev) >= nchrdev || major(dev) < 0) { 30739085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 30838625Srvb return(ENXIO); 30938625Srvb } 31038625Srvb 31138625Srvb /* 31238625Srvb * See if the device table matches our expectations. 31338625Srvb */ 31438625Srvb if (cdevsw[major(dev)]->d_open != vc_nb_open) 31538625Srvb { 31639085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 31738625Srvb return(ENXIO); 31838625Srvb } 31938625Srvb 32039085Srvb if (minor(dev) >= NVCODA || minor(dev) < 0) { 32139085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 32238625Srvb return(ENXIO); 32338625Srvb } 32438625Srvb 32538625Srvb /* 32638625Srvb * Initialize the mount record and link it to the vfs struct 32738625Srvb */ 32839085Srvb mi = &coda_mnttbl[minor(dev)]; 32938625Srvb 33038625Srvb if (!VC_OPEN(&mi->mi_vcomm)) { 33139085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 33238625Srvb return(ENODEV); 33338625Srvb } 33438625Srvb 33538625Srvb /* No initialization (here) of mi_vcomm! */ 33638625Srvb vfsp->mnt_data = (qaddr_t)mi; 33738625Srvb vfs_getnewfsid (vfsp); 33838625Srvb 33938625Srvb mi->mi_vfsp = vfsp; 34038625Srvb 34138625Srvb /* 34238625Srvb * Make a root vnode to placate the Vnode interface, but don't 34339085Srvb * actually make the CODA_ROOT call to venus until the first call 34439085Srvb * to coda_root in case a server is down while venus is starting. 34538625Srvb */ 34638625Srvb rootfid.Volume = 0; 34738625Srvb rootfid.Vnode = 0; 34838625Srvb rootfid.Unique = 0; 34939085Srvb cp = make_coda_node(&rootfid, vfsp, VDIR); 35038625Srvb rootvp = CTOV(cp); 35138625Srvb rootvp->v_flag |= VROOT; 35238625Srvb 35338625Srvb ctlfid.Volume = CTL_VOL; 35438625Srvb ctlfid.Vnode = CTL_VNO; 35538625Srvb ctlfid.Unique = CTL_UNI; 35639085Srvb/* cp = make_coda_node(&ctlfid, vfsp, VCHR); 35738625Srvb The above code seems to cause a loop in the cnode links. 35838625Srvb I don't totally understand when it happens, it is caught 35938625Srvb when closing down the system. 36038625Srvb */ 36139085Srvb cp = make_coda_node(&ctlfid, 0, VCHR); 36238625Srvb 36339085Srvb coda_ctlvp = CTOV(cp); 36438625Srvb 36538625Srvb /* Add vfs and rootvp to chain of vfs hanging off mntinfo */ 36638625Srvb mi->mi_vfsp = vfsp; 36738625Srvb mi->mi_rootvp = rootvp; 36838625Srvb 36938625Srvb /* set filesystem block size */ 37038625Srvb vfsp->mnt_stat.f_bsize = 8192; /* XXX -JJK */ 37138759Srvb 37238625Srvb /* Set f_iosize. XXX -- inamura@isl.ntt.co.jp. 37338625Srvb For vnode_pager_haspage() references. The value should be obtained 37438625Srvb from underlying UFS. */ 37538625Srvb /* Checked UFS. iosize is set as 8192 */ 37638625Srvb vfsp->mnt_stat.f_iosize = 8192; 37738625Srvb 37838625Srvb /* error is currently guaranteed to be zero, but in case some 37938625Srvb code changes... */ 38039085Srvb CODADEBUG(1, 38139085Srvb myprintf(("coda_mount returned %d\n",error));); 38238625Srvb if (error) 38339085Srvb MARK_INT_FAIL(CODA_MOUNT_STATS); 38438625Srvb else 38539085Srvb MARK_INT_SAT(CODA_MOUNT_STATS); 38638625Srvb 38738625Srvb return(error); 38838625Srvb} 38938625Srvb 39038625Srvbint 39139085Srvbcoda_start(vfsp, flags, p) 39238625Srvb struct mount *vfsp; 39338625Srvb int flags; 39438625Srvb struct proc *p; 39538625Srvb{ 39638625Srvb ENTRY; 39738625Srvb return (0); 39838625Srvb} 39938625Srvb 40038625Srvbint 40139085Srvbcoda_unmount(vfsp, mntflags, p) 40238625Srvb struct mount *vfsp; 40338625Srvb int mntflags; 40438625Srvb struct proc *p; 40538625Srvb{ 40639085Srvb struct coda_mntinfo *mi = vftomi(vfsp); 40738625Srvb int active, error = 0; 40838625Srvb 40938625Srvb ENTRY; 41039085Srvb MARK_ENTRY(CODA_UMOUNT_STATS); 41139085Srvb if (!CODA_MOUNTED(vfsp)) { 41239085Srvb MARK_INT_FAIL(CODA_UMOUNT_STATS); 41338625Srvb return(EINVAL); 41438625Srvb } 41538625Srvb 41638625Srvb if (mi->mi_vfsp == vfsp) { /* We found the victim */ 41738625Srvb if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp))) 41838625Srvb return (EBUSY); /* Venus is still running */ 41938625Srvb 42038625Srvb#ifdef DEBUG 42139085Srvb printf("coda_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp)); 42238625Srvb#endif 42338625Srvb vrele(mi->mi_rootvp); 42438625Srvb 42539085Srvb active = coda_kill(vfsp, NOT_DOWNCALL); 42638625Srvb error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE); 42739085Srvb printf("coda_unmount: active = %d, vflush active %d\n", active, error); 42838625Srvb error = 0; 42938625Srvb /* I'm going to take this out to allow lookups to go through. I'm 43038625Srvb * not sure it's important anyway. -- DCS 2/2/94 43138625Srvb */ 43238625Srvb /* vfsp->VFS_DATA = NULL; */ 43338625Srvb 43438625Srvb /* No more vfsp's to hold onto */ 43538625Srvb mi->mi_vfsp = NULL; 43638625Srvb mi->mi_rootvp = NULL; 43738625Srvb 43838625Srvb if (error) 43939085Srvb MARK_INT_FAIL(CODA_UMOUNT_STATS); 44038625Srvb else 44139085Srvb MARK_INT_SAT(CODA_UMOUNT_STATS); 44238625Srvb 44338625Srvb return(error); 44438625Srvb } 44538625Srvb return (EINVAL); 44638625Srvb} 44738625Srvb 44838625Srvb/* 44938625Srvb * find root of cfs 45038625Srvb */ 45138625Srvbint 45239085Srvbcoda_root(vfsp, vpp) 45338625Srvb struct mount *vfsp; 45438625Srvb struct vnode **vpp; 45538625Srvb{ 45639085Srvb struct coda_mntinfo *mi = vftomi(vfsp); 45738625Srvb struct vnode **result; 45838625Srvb int error; 45938625Srvb struct proc *p = curproc; /* XXX - bnoble */ 46038625Srvb ViceFid VFid; 46138625Srvb 46238625Srvb ENTRY; 46339085Srvb MARK_ENTRY(CODA_ROOT_STATS); 46438625Srvb result = NULL; 46538625Srvb 46638625Srvb if (vfsp == mi->mi_vfsp) { 46738625Srvb if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) || 46838625Srvb (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) || 46938625Srvb (VTOC(mi->mi_rootvp)->c_fid.Unique != 0)) 47038625Srvb { /* Found valid root. */ 47138625Srvb *vpp = mi->mi_rootvp; 47238625Srvb /* On Mach, this is vref. On NetBSD, VOP_LOCK */ 47338759Srvb#if 1 47438625Srvb vref(*vpp); 47538759Srvb vn_lock(*vpp, LK_EXCLUSIVE, p); 47638759Srvb#else 47738759Srvb vget(*vpp, LK_EXCLUSIVE, p); 47838759Srvb#endif 47939085Srvb MARK_INT_SAT(CODA_ROOT_STATS); 48038625Srvb return(0); 48138625Srvb } 48238625Srvb } 48338625Srvb 48438625Srvb error = venus_root(vftomi(vfsp), p->p_cred->pc_ucred, p, &VFid); 48538625Srvb 48638625Srvb if (!error) { 48738625Srvb /* 48838625Srvb * Save the new rootfid in the cnode, and rehash the cnode into the 48938625Srvb * cnode hash with the new fid key. 49038625Srvb */ 49139085Srvb coda_unsave(VTOC(mi->mi_rootvp)); 49238625Srvb VTOC(mi->mi_rootvp)->c_fid = VFid; 49339085Srvb coda_save(VTOC(mi->mi_rootvp)); 49438625Srvb 49538625Srvb *vpp = mi->mi_rootvp; 49638759Srvb#if 1 49738625Srvb vref(*vpp); 49838759Srvb vn_lock(*vpp, LK_EXCLUSIVE, p); 49938759Srvb#else 50038759Srvb vget(*vpp, LK_EXCLUSIVE, p); 50138759Srvb#endif 50238759Srvb 50339085Srvb MARK_INT_SAT(CODA_ROOT_STATS); 50438625Srvb goto exit; 50538625Srvb } else if (error == ENODEV) { 50638625Srvb /* Gross hack here! */ 50738625Srvb /* 50839085Srvb * If Venus fails to respond to the CODA_ROOT call, coda_call returns 50938625Srvb * ENODEV. Return the uninitialized root vnode to allow vfs 51038625Srvb * operations such as unmount to continue. Without this hack, 51138625Srvb * there is no way to do an unmount if Venus dies before a 51239085Srvb * successful CODA_ROOT call is done. All vnode operations 51338625Srvb * will fail. 51438625Srvb */ 51538625Srvb *vpp = mi->mi_rootvp; 51638759Srvb#if 1 51738625Srvb vref(*vpp); 51838759Srvb vn_lock(*vpp, LK_EXCLUSIVE, p); 51938759Srvb#else 52038759Srvb vget(*vpp, LK_EXCLUSIVE, p); 52138759Srvb#endif 52238759Srvb 52339085Srvb MARK_INT_FAIL(CODA_ROOT_STATS); 52438625Srvb error = 0; 52538625Srvb goto exit; 52638625Srvb } else { 52739085Srvb CODADEBUG( CODA_ROOT, myprintf(("error %d in CODA_ROOT\n", error)); ); 52839085Srvb MARK_INT_FAIL(CODA_ROOT_STATS); 52938625Srvb 53038625Srvb goto exit; 53138625Srvb } 53238759Srvb 53338625Srvb exit: 53438625Srvb return(error); 53538625Srvb} 53638625Srvb 53738625Srvbint 53839085Srvbcoda_quotactl(vfsp, cmd, uid, arg, p) 53938625Srvb struct mount *vfsp; 54038625Srvb int cmd; 54138625Srvb uid_t uid; 54238625Srvb caddr_t arg; 54338625Srvb struct proc *p; 54438625Srvb{ 54538625Srvb ENTRY; 54638625Srvb return (EOPNOTSUPP); 54738625Srvb} 54838625Srvb 54938625Srvb/* 55038625Srvb * Get file system statistics. 55138625Srvb */ 55238625Srvbint 55339085Srvbcoda_nb_statfs(vfsp, sbp, p) 55438625Srvb register struct mount *vfsp; 55538625Srvb struct statfs *sbp; 55638625Srvb struct proc *p; 55738625Srvb{ 55838625Srvb ENTRY; 55939085Srvb/* MARK_ENTRY(CODA_STATFS_STATS); */ 56039085Srvb if (!CODA_MOUNTED(vfsp)) { 56139085Srvb/* MARK_INT_FAIL(CODA_STATFS_STATS);*/ 56238625Srvb return(EINVAL); 56338625Srvb } 56438625Srvb 56538625Srvb bzero(sbp, sizeof(struct statfs)); 56638625Srvb /* XXX - what to do about f_flags, others? --bnoble */ 56738625Srvb /* Below This is what AFS does 56838625Srvb #define NB_SFS_SIZ 0x895440 56938625Srvb */ 57038625Srvb /* Note: Normal fs's have a bsize of 0x400 == 1024 */ 57138909Sbde sbp->f_type = vfsp->mnt_vfc->vfc_typenum; 57238625Srvb sbp->f_bsize = 8192; /* XXX */ 57338625Srvb sbp->f_iosize = 8192; /* XXX */ 57438625Srvb#define NB_SFS_SIZ 0x8AB75D 57538625Srvb sbp->f_blocks = NB_SFS_SIZ; 57638625Srvb sbp->f_bfree = NB_SFS_SIZ; 57738625Srvb sbp->f_bavail = NB_SFS_SIZ; 57838625Srvb sbp->f_files = NB_SFS_SIZ; 57938625Srvb sbp->f_ffree = NB_SFS_SIZ; 58038625Srvb bcopy((caddr_t)&(vfsp->mnt_stat.f_fsid), (caddr_t)&(sbp->f_fsid), sizeof (fsid_t)); 58138625Srvb strcpy(sbp->f_mntonname, "/coda"); 58239085Srvb strcpy(sbp->f_mntfromname, "CODA"); 58339085Srvb/* MARK_INT_SAT(CODA_STATFS_STATS); */ 58438625Srvb return(0); 58538625Srvb} 58638625Srvb 58738625Srvb/* 58838625Srvb * Flush any pending I/O. 58938625Srvb */ 59038625Srvbint 59139085Srvbcoda_sync(vfsp, waitfor, cred, p) 59238625Srvb struct mount *vfsp; 59338625Srvb int waitfor; 59438625Srvb struct ucred *cred; 59538625Srvb struct proc *p; 59638625Srvb{ 59738625Srvb ENTRY; 59839085Srvb MARK_ENTRY(CODA_SYNC_STATS); 59939085Srvb MARK_INT_SAT(CODA_SYNC_STATS); 60038625Srvb return(0); 60138625Srvb} 60238625Srvb 60338625Srvbint 60439085Srvbcoda_vget(vfsp, ino, vpp) 60538625Srvb struct mount *vfsp; 60638625Srvb ino_t ino; 60738625Srvb struct vnode **vpp; 60838625Srvb{ 60938625Srvb ENTRY; 61038625Srvb return (EOPNOTSUPP); 61138625Srvb} 61238625Srvb 61338625Srvb/* 61438625Srvb * fhtovp is now what vget used to be in 4.3-derived systems. For 61538625Srvb * some silly reason, vget is now keyed by a 32 bit ino_t, rather than 61638625Srvb * a type-specific fid. 61738625Srvb */ 61838625Srvbint 61939085Srvbcoda_fhtovp(vfsp, fhp, nam, vpp, exflagsp, creadanonp) 62038625Srvb register struct mount *vfsp; 62138625Srvb struct fid *fhp; 62238625Srvb struct mbuf *nam; 62338625Srvb struct vnode **vpp; 62438625Srvb int *exflagsp; 62538625Srvb struct ucred **creadanonp; 62638625Srvb{ 62738625Srvb struct cfid *cfid = (struct cfid *)fhp; 62838625Srvb struct cnode *cp = 0; 62938625Srvb int error; 63038625Srvb struct proc *p = curproc; /* XXX -mach */ 63138625Srvb ViceFid VFid; 63238625Srvb int vtype; 63338625Srvb 63438625Srvb ENTRY; 63538625Srvb 63639085Srvb MARK_ENTRY(CODA_VGET_STATS); 63738625Srvb /* Check for vget of control object. */ 63838625Srvb if (IS_CTL_FID(&cfid->cfid_fid)) { 63939085Srvb *vpp = coda_ctlvp; 64039085Srvb vref(coda_ctlvp); 64139085Srvb MARK_INT_SAT(CODA_VGET_STATS); 64238625Srvb return(0); 64338625Srvb } 64438625Srvb 64538625Srvb error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, p->p_cred->pc_ucred, p, &VFid, &vtype); 64638625Srvb 64738625Srvb if (error) { 64839085Srvb CODADEBUG(CODA_VGET, myprintf(("vget error %d\n",error));) 64938625Srvb *vpp = (struct vnode *)0; 65038625Srvb } else { 65139085Srvb CODADEBUG(CODA_VGET, 65238625Srvb myprintf(("vget: vol %lx vno %lx uni %lx type %d result %d\n", 65338625Srvb VFid.Volume, VFid.Vnode, VFid.Unique, vtype, error)); ) 65438625Srvb 65539085Srvb cp = make_coda_node(&VFid, vfsp, vtype); 65638625Srvb *vpp = CTOV(cp); 65738625Srvb } 65838625Srvb return(error); 65938625Srvb} 66038625Srvb 66138625Srvbint 66239085Srvbcoda_vptofh(vnp, fidp) 66338625Srvb struct vnode *vnp; 66438625Srvb struct fid *fidp; 66538625Srvb{ 66638625Srvb ENTRY; 66738625Srvb return (EOPNOTSUPP); 66838625Srvb} 66938625Srvb 67038625Srvbint 67139085Srvbcoda_init(struct vfsconf *vfsp) 67238625Srvb{ 67338625Srvb ENTRY; 67438625Srvb return 0; 67538625Srvb} 67638625Srvb 67738625Srvb/* 67838625Srvb * To allow for greater ease of use, some vnodes may be orphaned when 67938625Srvb * Venus dies. Certain operations should still be allowed to go 68038625Srvb * through, but without propagating ophan-ness. So this function will 68138625Srvb * get a new vnode for the file from the current run of Venus. */ 68238625Srvb 68338625Srvbint 68438625SrvbgetNewVnode(vpp) 68538625Srvb struct vnode **vpp; 68638625Srvb{ 68738625Srvb struct cfid cfid; 68839085Srvb struct coda_mntinfo *mi = vftomi((*vpp)->v_mount); 68938625Srvb 69038625Srvb ENTRY; 69138625Srvb 69238625Srvb cfid.cfid_len = (short)sizeof(ViceFid); 69338625Srvb cfid.cfid_fid = VTOC(*vpp)->c_fid; /* Structure assignment. */ 69438625Srvb /* XXX ? */ 69538625Srvb 69638625Srvb /* We're guessing that if set, the 1st element on the list is a 69738625Srvb * valid vnode to use. If not, return ENODEV as venus is dead. 69838625Srvb */ 69938625Srvb if (mi->mi_vfsp == NULL) 70038625Srvb return ENODEV; 70138625Srvb 70239085Srvb return coda_fhtovp(mi->mi_vfsp, (struct fid*)&cfid, NULL, vpp, 70338625Srvb NULL, NULL); 70438625Srvb} 70538625Srvb 70638625Srvb#include <ufs/ufs/quota.h> 70738625Srvb#include <ufs/ufs/ufsmount.h> 70838625Srvb/* get the mount structure corresponding to a given device. Assume 70938625Srvb * device corresponds to a UFS. Return NULL if no device is found. 71038625Srvb */ 71138625Srvbstruct mount *devtomp(dev) 71238625Srvb dev_t dev; 71338625Srvb{ 71438625Srvb struct mount *mp, *nmp; 71538625Srvb 71638625Srvb for (mp = mountlist.cqh_first; mp != (void*)&mountlist; mp = nmp) { 71738625Srvb nmp = mp->mnt_list.cqe_next; 71838759Srvb if (((VFSTOUFS(mp))->um_dev == (dev_t) dev)) { 71938625Srvb /* mount corresponds to UFS and the device matches one we want */ 72038625Srvb return(mp); 72138625Srvb } 72238625Srvb } 72338625Srvb /* mount structure wasn't found */ 72438625Srvb return(NULL); 72538625Srvb} 726