coda_vfsops.c revision 38625
138625Srvb/* 238625Srvb 338625Srvb Coda: an Experimental Distributed File System 438625Srvb Release 3.1 538625Srvb 638625Srvb Copyright (c) 1987-1998 Carnegie Mellon University 738625Srvb All Rights Reserved 838625Srvb 938625SrvbPermission to use, copy, modify and distribute this software and its 1038625Srvbdocumentation is hereby granted, provided that both the copyright 1138625Srvbnotice and this permission notice appear in all copies of the 1238625Srvbsoftware, derivative works or modified versions, and any portions 1338625Srvbthereof, and that both notices appear in supporting documentation, and 1438625Srvbthat credit is given to Carnegie Mellon University in all documents 1538625Srvband publicity pertaining to direct or indirect use of this code or its 1638625Srvbderivatives. 1738625Srvb 1838625SrvbCODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS, 1938625SrvbSOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS 2038625SrvbFREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON 2138625SrvbDISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER 2238625SrvbRESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF 2338625SrvbANY DERIVATIVE WORK. 2438625Srvb 2538625SrvbCarnegie Mellon encourages users of this software to return any 2638625Srvbimprovements or extensions that they make, and to grant Carnegie 2738625SrvbMellon the rights to redistribute these changes without encumbrance. 2838625Srvb*/ 2938625Srvb 3038625Srvb/* $Header: /afs/cs/project/coda-src/cvs/coda/kernel-src/vfs/freebsd/cfs/cfs_vfsops.c,v 1.11 1998/08/28 18:12:22 rvb Exp $ */ 3138625Srvb 3238625Srvb/* 3338625Srvb * Mach Operating System 3438625Srvb * Copyright (c) 1989 Carnegie-Mellon University 3538625Srvb * All rights reserved. The CMU software License Agreement specifies 3638625Srvb * the terms and conditions for use and redistribution. 3738625Srvb */ 3838625Srvb 3938625Srvb/* 4038625Srvb * This code was written for the Coda file system at Carnegie Mellon 4138625Srvb * University. Contributers include David Steere, James Kistler, and 4238625Srvb * M. Satyanarayanan. 4338625Srvb */ 4438625Srvb 4538625Srvb/* 4638625Srvb * HISTORY 4738625Srvb * $Log: cfs_vfsops.c,v $ 4838625Srvb * Revision 1.11 1998/08/28 18:12:22 rvb 4938625Srvb * Now it also works on FreeBSD -current. This code will be 5038625Srvb * committed to the FreeBSD -current and NetBSD -current 5138625Srvb * trees. It will then be tailored to the particular platform 5238625Srvb * by flushing conditional code. 5338625Srvb * 5438625Srvb * Revision 1.10 1998/08/18 17:05:19 rvb 5538625Srvb * Don't use __RCSID now 5638625Srvb * 5738625Srvb * Revision 1.9 1998/08/18 16:31:44 rvb 5838625Srvb * Sync the code for NetBSD -current; test on 1.3 later 5938625Srvb * 6038625Srvb * Revision 1.8 98/02/24 22:22:48 rvb 6138625Srvb * Fixes up mainly to flush iopen and friends 6238625Srvb * 6338625Srvb * Revision 1.7 98/01/23 11:53:45 rvb 6438625Srvb * Bring RVB_CFS1_1 to HEAD 6538625Srvb * 6638625Srvb * Revision 1.6.2.6 98/01/23 11:21:07 rvb 6738625Srvb * Sync with 2.2.5 6838625Srvb * 6938625Srvb * Revision 1.6.2.5 98/01/22 13:05:33 rvb 7038625Srvb * Move makecfsnode ctlfid later so vfsp is known 7138625Srvb * 7238625Srvb * Revision 1.6.2.4 97/12/19 14:26:05 rvb 7338625Srvb * session id 7438625Srvb * 7538625Srvb * Revision 1.6.2.3 97/12/16 12:40:11 rvb 7638625Srvb * Sync with 1.3 7738625Srvb * 7838625Srvb * Revision 1.6.2.2 97/12/10 11:40:25 rvb 7938625Srvb * No more ody 8038625Srvb * 8138625Srvb * Revision 1.6.2.1 97/12/06 17:41:24 rvb 8238625Srvb * Sync with peters coda.h 8338625Srvb * 8438625Srvb * Revision 1.6 97/12/05 10:39:21 rvb 8538625Srvb * Read CHANGES 8638625Srvb * 8738625Srvb * Revision 1.5.14.8 97/11/24 15:44:46 rvb 8838625Srvb * Final cfs_venus.c w/o macros, but one locking bug 8938625Srvb * 9038625Srvb * Revision 1.5.14.7 97/11/21 13:22:03 rvb 9138625Srvb * Catch a few cfscalls in cfs_vfsops.c 9238625Srvb * 9338625Srvb * Revision 1.5.14.6 97/11/20 11:46:48 rvb 9438625Srvb * Capture current cfs_venus 9538625Srvb * 9638625Srvb * Revision 1.5.14.5 97/11/18 10:27:17 rvb 9738625Srvb * cfs_nbsd.c is DEAD!!!; integrated into cfs_vf/vnops.c 9838625Srvb * cfs_nb_foo and cfs_foo are joined 9938625Srvb * 10038625Srvb * Revision 1.5.14.4 97/11/13 22:03:01 rvb 10138625Srvb * pass2 cfs_NetBSD.h mt 10238625Srvb * 10338625Srvb * Revision 1.5.14.3 97/11/12 12:09:40 rvb 10438625Srvb * reorg pass1 10538625Srvb * 10638625Srvb * Revision 1.5.14.2 97/10/29 16:06:28 rvb 10738625Srvb * Kill DYING 10838625Srvb * 10938625Srvb * Revision 1.5.14.1 1997/10/28 23:10:17 rvb 11038625Srvb * >64Meg; venus can be killed! 11138625Srvb * 11238625Srvb * Revision 1.5 1997/01/13 17:11:07 bnoble 11338625Srvb * Coda statfs needs to return something other than -1 for blocks avail. and 11438625Srvb * files available for wabi (and other windowsish) programs to install 11538625Srvb * there correctly. 11638625Srvb * 11738625Srvb * Revision 1.4 1996/12/12 22:11:00 bnoble 11838625Srvb * Fixed the "downcall invokes venus operation" deadlock in all known cases. 11938625Srvb * There may be more 12038625Srvb * 12138625Srvb * Revision 1.3 1996/11/08 18:06:12 bnoble 12238625Srvb * Minor changes in vnode operation signature, VOP_UPDATE signature, and 12338625Srvb * some newly defined bits in the include files. 12438625Srvb * 12538625Srvb * Revision 1.2 1996/01/02 16:57:04 bnoble 12638625Srvb * Added support for Coda MiniCache and raw inode calls (final commit) 12738625Srvb * 12838625Srvb * Revision 1.1.2.1 1995/12/20 01:57:32 bnoble 12938625Srvb * Added CFS-specific files 13038625Srvb * 13138625Srvb * Revision 3.1.1.1 1995/03/04 19:08:02 bnoble 13238625Srvb * Branch for NetBSD port revisions 13338625Srvb * 13438625Srvb * Revision 3.1 1995/03/04 19:08:01 bnoble 13538625Srvb * Bump to major revision 3 to prepare for NetBSD port 13638625Srvb * 13738625Srvb * Revision 2.4 1995/02/17 16:25:22 dcs 13838625Srvb * These versions represent several changes: 13938625Srvb * 1. Allow venus to restart even if outstanding references exist. 14038625Srvb * 2. Have only one ctlvp per client, as opposed to one per mounted cfs device.d 14138625Srvb * 3. Allow ody_expand to return many members, not just one. 14238625Srvb * 14338625Srvb * Revision 2.3 94/10/14 09:58:21 dcs 14438625Srvb * Made changes 'cause sun4s have braindead compilers 14538625Srvb * 14638625Srvb * Revision 2.2 94/10/12 16:46:33 dcs 14738625Srvb * Cleaned kernel/venus interface by removing XDR junk, plus 14838625Srvb * so cleanup to allow this code to be more easily ported. 14938625Srvb * 15038625Srvb * Revision 1.3 93/05/28 16:24:29 bnoble 15138625Srvb * *** empty log message *** 15238625Srvb * 15338625Srvb * Revision 1.2 92/10/27 17:58:24 lily 15438625Srvb * merge kernel/latest and alpha/src/cfs 15538625Srvb * 15638625Srvb * Revision 2.3 92/09/30 14:16:32 mja 15738625Srvb * Added call to cfs_flush to cfs_unmount. 15838625Srvb * [90/12/15 dcs] 15938625Srvb * 16038625Srvb * Added contributors blurb. 16138625Srvb * [90/12/13 jjk] 16238625Srvb * 16338625Srvb * Revision 2.2 90/07/05 11:26:40 mrt 16438625Srvb * Created for the Coda File System. 16538625Srvb * [90/05/23 dcs] 16638625Srvb * 16738625Srvb * Revision 1.3 90/05/31 17:01:42 dcs 16838625Srvb * Prepare for merge with facilities kernel. 16938625Srvb * 17038625Srvb * 17138625Srvb */ 17238625Srvb#include <vcfs.h> 17338625Srvb 17438625Srvb#include <sys/param.h> 17538625Srvb#include <sys/systm.h> 17638625Srvb#include <sys/malloc.h> 17738625Srvb#include <sys/conf.h> 17838625Srvb#include <sys/namei.h> 17938625Srvb#include <sys/mount.h> 18038625Srvb#include <sys/proc.h> 18138625Srvb#include <sys/select.h> 18238625Srvb 18338625Srvb#include <cfs/coda.h> 18438625Srvb#include <cfs/cnode.h> 18538625Srvb#include <cfs/cfs_vfsops.h> 18638625Srvb#include <cfs/cfs_venus.h> 18738625Srvb#include <cfs/cfs_subr.h> 18838625Srvb#include <cfs/coda_opstats.h> 18938625Srvb/* for VN_RDEV */ 19038625Srvb#include <miscfs/specfs/specdev.h> 19138625Srvb 19238625Srvb#ifdef __FreeBSD__ 19338625Srvb#ifdef __FreeBSD_version 19438625SrvbMALLOC_DEFINE(M_CFS, "CFS storage", "Various Coda Structures"); 19538625Srvb#endif 19638625Srvb#endif 19738625Srvb 19838625Srvbint cfsdebug = 0; 19938625Srvb 20038625Srvbint cfs_vfsop_print_entry = 0; 20138625Srvb#ifdef __GNUC__ 20238625Srvb#define ENTRY \ 20338625Srvb if(cfs_vfsop_print_entry) myprintf(("Entered %s\n",__FUNCTION__)) 20438625Srvb#else 20538625Srvb#define ENTRY 20638625Srvb#endif 20738625Srvb 20838625Srvb 20938625Srvbstruct vnode *cfs_ctlvp; 21038625Srvbstruct cfs_mntinfo cfs_mnttbl[NVCFS]; /* indexed by minor device number */ 21138625Srvb 21238625Srvb/* structure to keep statistics of internally generated/satisfied calls */ 21338625Srvb 21438625Srvbstruct cfs_op_stats cfs_vfsopstats[CFS_VFSOPS_SIZE]; 21538625Srvb 21638625Srvb#define MARK_ENTRY(op) (cfs_vfsopstats[op].entries++) 21738625Srvb#define MARK_INT_SAT(op) (cfs_vfsopstats[op].sat_intrn++) 21838625Srvb#define MARK_INT_FAIL(op) (cfs_vfsopstats[op].unsat_intrn++) 21938625Srvb#define MRAK_INT_GEN(op) (cfs_vfsopstats[op].gen_intrn++) 22038625Srvb 22138625Srvbextern int cfsnc_initialized; /* Set if cache has been initialized */ 22238625Srvbextern int vc_nb_open __P((dev_t, int, int, struct proc *)); 22338625Srvb#ifdef __NetBSD__ 22438625Srvbextern struct cdevsw cdevsw[]; /* For sanity check in cfs_mount */ 22538625Srvb#endif 22638625Srvb/* NetBSD interface to statfs */ 22738625Srvb 22838625Srvb#if defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 5) 22938625Srvbextern struct vnodeopv_desc cfs_vnodeop_opv_desc; 23038625Srvb 23138625Srvbstruct vnodeopv_desc *cfs_vnodeopv_descs[] = { 23238625Srvb &cfs_vnodeop_opv_desc, 23338625Srvb NULL, 23438625Srvb}; 23538625Srvb 23638625Srvbstruct vfsops cfs_vfsops = { 23738625Srvb MOUNT_CFS, 23838625Srvb cfs_mount, 23938625Srvb cfs_start, 24038625Srvb cfs_unmount, 24138625Srvb cfs_root, 24238625Srvb cfs_quotactl, 24338625Srvb cfs_nb_statfs, 24438625Srvb cfs_sync, 24538625Srvb cfs_vget, 24638625Srvb (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **, 24738625Srvb int *, struct ucred **)) 24838625Srvb eopnotsupp, 24938625Srvb (int (*) (struct vnode *, struct fid *)) eopnotsupp, 25038625Srvb cfs_init, 25138625Srvb#if (NetBSD1_3 >= 7) 25238625Srvb cfs_sysctl, 25338625Srvb#endif 25438625Srvb (int (*)(void)) eopnotsupp, 25538625Srvb cfs_vnodeopv_descs, 25638625Srvb 0 25738625Srvb}; 25838625Srvb#elif defined(__NetBSD__) 25938625Srvbstruct vfsops cfs_vfsops = { 26038625Srvb MOUNT_CFS, 26138625Srvb cfs_mount, 26238625Srvb cfs_start, 26338625Srvb cfs_unmount, 26438625Srvb cfs_root, 26538625Srvb cfs_quotactl, 26638625Srvb cfs_nb_statfs, 26738625Srvb cfs_sync, 26838625Srvb cfs_vget, 26938625Srvb (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **, 27038625Srvb int *, struct ucred **)) 27138625Srvb eopnotsupp, 27238625Srvb (int (*) (struct vnode *, struct fid *)) eopnotsupp, 27338625Srvb cfs_init, 27438625Srvb#ifdef NetBSD1_3 27538625Srvb (int (*)(void)) eopnotsupp, 27638625Srvb#endif 27738625Srvb 0 27838625Srvb}; 27938625Srvb 28038625Srvb#elif defined(__FreeBSD__) 28138625Srvb#ifdef __FreeBSD_version 28238625Srvbstruct vfsops cfs_vfsops = { 28338625Srvb cfs_mount, 28438625Srvb cfs_start, 28538625Srvb cfs_unmount, 28638625Srvb cfs_root, 28738625Srvb cfs_quotactl, 28838625Srvb cfs_nb_statfs, 28938625Srvb cfs_sync, 29038625Srvb cfs_vget, 29138625Srvb (int (*) (struct mount *, struct fid *, struct sockaddr *, struct vnode **, 29238625Srvb int *, struct ucred **)) 29338625Srvb eopnotsupp, 29438625Srvb (int (*) (struct vnode *, struct fid *)) eopnotsupp, 29538625Srvb cfs_init, 29638625Srvb}; 29738625Srvb 29838625Srvb#else 29938625Srvbstruct vfsops cfs_vfsops = { 30038625Srvb cfs_mount, 30138625Srvb cfs_start, 30238625Srvb cfs_unmount, 30338625Srvb cfs_root, 30438625Srvb cfs_quotactl, 30538625Srvb cfs_nb_statfs, 30638625Srvb cfs_sync, 30738625Srvb cfs_vget, 30838625Srvb (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **, 30938625Srvb int *, struct ucred **)) 31038625Srvb eopnotsupp, 31138625Srvb (int (*) (struct vnode *, struct fid *)) eopnotsupp, 31238625Srvb cfs_init, 31338625Srvb}; 31438625Srvb 31538625Srvb#endif 31638625Srvb 31738625Srvb 31838625Srvb#include <sys/kernel.h> 31938625SrvbVFS_SET(cfs_vfsops, cfs, MOUNT_CFS, VFCF_NETWORK); 32038625Srvb#endif 32138625Srvb 32238625Srvbint 32338625Srvbcfs_vfsopstats_init(void) 32438625Srvb{ 32538625Srvb register int i; 32638625Srvb 32738625Srvb for (i=0;i<CFS_VFSOPS_SIZE;i++) { 32838625Srvb cfs_vfsopstats[i].opcode = i; 32938625Srvb cfs_vfsopstats[i].entries = 0; 33038625Srvb cfs_vfsopstats[i].sat_intrn = 0; 33138625Srvb cfs_vfsopstats[i].unsat_intrn = 0; 33238625Srvb cfs_vfsopstats[i].gen_intrn = 0; 33338625Srvb } 33438625Srvb 33538625Srvb return 0; 33638625Srvb} 33738625Srvb 33838625Srvb 33938625Srvb/* 34038625Srvb * cfs mount vfsop 34138625Srvb * Set up mount info record and attach it to vfs struct. 34238625Srvb */ 34338625Srvb/*ARGSUSED*/ 34438625Srvbint 34538625Srvbcfs_mount(vfsp, path, data, ndp, p) 34638625Srvb struct mount *vfsp; /* Allocated and initialized by mount(2) */ 34738625Srvb#ifdef NetBSD1_3 34838625Srvb const char *path; /* path covered: ignored by the fs-layer */ 34938625Srvb void *data; /* Need to define a data type for this in netbsd? */ 35038625Srvb#else 35138625Srvb char *path; /* path covered: ignored by the fs-layer */ 35238625Srvb caddr_t data; /* Need to define a data type for this in netbsd? */ 35338625Srvb#endif 35438625Srvb struct nameidata *ndp; /* Clobber this to lookup the device name */ 35538625Srvb struct proc *p; /* The ever-famous proc pointer */ 35638625Srvb{ 35738625Srvb struct vnode *dvp; 35838625Srvb struct cnode *cp; 35938625Srvb dev_t dev; 36038625Srvb struct cfs_mntinfo *mi; 36138625Srvb struct vnode *rootvp; 36238625Srvb ViceFid rootfid; 36338625Srvb ViceFid ctlfid; 36438625Srvb int error; 36538625Srvb 36638625Srvb ENTRY; 36738625Srvb 36838625Srvb cfs_vfsopstats_init(); 36938625Srvb cfs_vnodeopstats_init(); 37038625Srvb 37138625Srvb MARK_ENTRY(CFS_MOUNT_STATS); 37238625Srvb if (CFS_MOUNTED(vfsp)) { 37338625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 37438625Srvb return(EBUSY); 37538625Srvb } 37638625Srvb 37738625Srvb /* Validate mount device. Similar to getmdev(). */ 37838625Srvb 37938625Srvb NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, data, p); 38038625Srvb error = namei(ndp); 38138625Srvb dvp = ndp->ni_vp; 38238625Srvb 38338625Srvb if (error) { 38438625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 38538625Srvb return (error); 38638625Srvb } 38738625Srvb if (dvp->v_type != VCHR) { 38838625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 38938625Srvb vrele(dvp); 39038625Srvb return(ENXIO); 39138625Srvb } 39238625Srvb dev = dvp->v_specinfo->si_rdev; 39338625Srvb vrele(dvp); 39438625Srvb if (major(dev) >= nchrdev || major(dev) < 0) { 39538625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 39638625Srvb return(ENXIO); 39738625Srvb } 39838625Srvb 39938625Srvb /* 40038625Srvb * See if the device table matches our expectations. 40138625Srvb */ 40238625Srvb#ifdef __NetBSD__ 40338625Srvb if (cdevsw[major(dev)].d_open != vc_nb_open) 40438625Srvb#elif defined(__FreeBSD__) 40538625Srvb if (cdevsw[major(dev)]->d_open != vc_nb_open) 40638625Srvb#endif 40738625Srvb { 40838625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 40938625Srvb return(ENXIO); 41038625Srvb } 41138625Srvb 41238625Srvb if (minor(dev) >= NVCFS || minor(dev) < 0) { 41338625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 41438625Srvb return(ENXIO); 41538625Srvb } 41638625Srvb 41738625Srvb /* 41838625Srvb * Initialize the mount record and link it to the vfs struct 41938625Srvb */ 42038625Srvb mi = &cfs_mnttbl[minor(dev)]; 42138625Srvb 42238625Srvb if (!VC_OPEN(&mi->mi_vcomm)) { 42338625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 42438625Srvb return(ENODEV); 42538625Srvb } 42638625Srvb 42738625Srvb /* No initialization (here) of mi_vcomm! */ 42838625Srvb vfsp->mnt_data = (qaddr_t)mi; 42938625Srvb#ifdef __NetBSD__ 43038625Srvb vfsp->mnt_stat.f_fsid.val[0] = 0; 43138625Srvb vfsp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_CFS); 43238625Srvb#elif defined(__FreeBSD__) && defined(__FreeBSD_version) 43338625Srvb 43438625Srvb vfs_getnewfsid (vfsp); 43538625Srvb 43638625Srvb#elif defined(__FreeBSD__) 43738625Srvb /* Seems a bit overkill, since usualy /coda is the only mount point 43838625Srvb * for cfs. 43938625Srvb */ 44038625Srvb getnewfsid (vfsp, MOUNT_CFS); 44138625Srvb#endif 44238625Srvb mi->mi_vfsp = vfsp; 44338625Srvb 44438625Srvb /* 44538625Srvb * Make a root vnode to placate the Vnode interface, but don't 44638625Srvb * actually make the CFS_ROOT call to venus until the first call 44738625Srvb * to cfs_root in case a server is down while venus is starting. 44838625Srvb */ 44938625Srvb rootfid.Volume = 0; 45038625Srvb rootfid.Vnode = 0; 45138625Srvb rootfid.Unique = 0; 45238625Srvb cp = makecfsnode(&rootfid, vfsp, VDIR); 45338625Srvb rootvp = CTOV(cp); 45438625Srvb rootvp->v_flag |= VROOT; 45538625Srvb 45638625Srvb ctlfid.Volume = CTL_VOL; 45738625Srvb ctlfid.Vnode = CTL_VNO; 45838625Srvb ctlfid.Unique = CTL_UNI; 45938625Srvb/* cp = makecfsnode(&ctlfid, vfsp, VCHR); 46038625Srvb The above code seems to cause a loop in the cnode links. 46138625Srvb I don't totally understand when it happens, it is caught 46238625Srvb when closing down the system. 46338625Srvb */ 46438625Srvb cp = makecfsnode(&ctlfid, 0, VCHR); 46538625Srvb 46638625Srvb cfs_ctlvp = CTOV(cp); 46738625Srvb 46838625Srvb /* Add vfs and rootvp to chain of vfs hanging off mntinfo */ 46938625Srvb mi->mi_vfsp = vfsp; 47038625Srvb mi->mi_rootvp = rootvp; 47138625Srvb 47238625Srvb /* set filesystem block size */ 47338625Srvb vfsp->mnt_stat.f_bsize = 8192; /* XXX -JJK */ 47438625Srvb#ifdef __FreeBSD__ 47538625Srvb /* Set f_iosize. XXX -- inamura@isl.ntt.co.jp. 47638625Srvb For vnode_pager_haspage() references. The value should be obtained 47738625Srvb from underlying UFS. */ 47838625Srvb /* Checked UFS. iosize is set as 8192 */ 47938625Srvb vfsp->mnt_stat.f_iosize = 8192; 48038625Srvb#endif 48138625Srvb 48238625Srvb /* error is currently guaranteed to be zero, but in case some 48338625Srvb code changes... */ 48438625Srvb CFSDEBUG(1, 48538625Srvb myprintf(("cfs_mount returned %d\n",error));); 48638625Srvb if (error) 48738625Srvb MARK_INT_FAIL(CFS_MOUNT_STATS); 48838625Srvb else 48938625Srvb MARK_INT_SAT(CFS_MOUNT_STATS); 49038625Srvb 49138625Srvb return(error); 49238625Srvb} 49338625Srvb 49438625Srvbint 49538625Srvbcfs_start(vfsp, flags, p) 49638625Srvb struct mount *vfsp; 49738625Srvb int flags; 49838625Srvb struct proc *p; 49938625Srvb{ 50038625Srvb ENTRY; 50138625Srvb return (0); 50238625Srvb} 50338625Srvb 50438625Srvbint 50538625Srvbcfs_unmount(vfsp, mntflags, p) 50638625Srvb struct mount *vfsp; 50738625Srvb int mntflags; 50838625Srvb struct proc *p; 50938625Srvb{ 51038625Srvb struct cfs_mntinfo *mi = vftomi(vfsp); 51138625Srvb int active, error = 0; 51238625Srvb 51338625Srvb ENTRY; 51438625Srvb MARK_ENTRY(CFS_UMOUNT_STATS); 51538625Srvb if (!CFS_MOUNTED(vfsp)) { 51638625Srvb MARK_INT_FAIL(CFS_UMOUNT_STATS); 51738625Srvb return(EINVAL); 51838625Srvb } 51938625Srvb 52038625Srvb if (mi->mi_vfsp == vfsp) { /* We found the victim */ 52138625Srvb if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp))) 52238625Srvb return (EBUSY); /* Venus is still running */ 52338625Srvb 52438625Srvb#ifdef DEBUG 52538625Srvb printf("cfs_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp)); 52638625Srvb#endif 52738625Srvb vrele(mi->mi_rootvp); 52838625Srvb 52938625Srvb#ifdef NetBSD1_3 53038625Srvb active = cfs_kill(vfsp, NOT_DOWNCALL); 53138625Srvb 53238625Srvb#if defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 7) 53338625Srvb if (1) 53438625Srvb#else 53538625Srvb if ((error = vfs_busy(mi->mi_vfsp)) == 0) 53638625Srvb#endif 53738625Srvb { 53838625Srvb error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE); 53938625Srvb printf("cfs_unmount: active = %d, vflush active %d\n", active, error); 54038625Srvb error = 0; 54138625Srvb } else { 54238625Srvb printf("cfs_unmount: busy\n"); 54338625Srvb } 54438625Srvb#else /* FreeBSD I guess */ 54538625Srvb active = cfs_kill(vfsp, NOT_DOWNCALL); 54638625Srvb error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE); 54738625Srvb printf("cfs_unmount: active = %d, vflush active %d\n", active, error); 54838625Srvb error = 0; 54938625Srvb#endif 55038625Srvb /* I'm going to take this out to allow lookups to go through. I'm 55138625Srvb * not sure it's important anyway. -- DCS 2/2/94 55238625Srvb */ 55338625Srvb /* vfsp->VFS_DATA = NULL; */ 55438625Srvb 55538625Srvb /* No more vfsp's to hold onto */ 55638625Srvb mi->mi_vfsp = NULL; 55738625Srvb mi->mi_rootvp = NULL; 55838625Srvb 55938625Srvb if (error) 56038625Srvb MARK_INT_FAIL(CFS_UMOUNT_STATS); 56138625Srvb else 56238625Srvb MARK_INT_SAT(CFS_UMOUNT_STATS); 56338625Srvb 56438625Srvb return(error); 56538625Srvb } 56638625Srvb return (EINVAL); 56738625Srvb} 56838625Srvb 56938625Srvb/* 57038625Srvb * find root of cfs 57138625Srvb */ 57238625Srvbint 57338625Srvbcfs_root(vfsp, vpp) 57438625Srvb struct mount *vfsp; 57538625Srvb struct vnode **vpp; 57638625Srvb{ 57738625Srvb struct cfs_mntinfo *mi = vftomi(vfsp); 57838625Srvb struct vnode **result; 57938625Srvb int error; 58038625Srvb struct proc *p = curproc; /* XXX - bnoble */ 58138625Srvb ViceFid VFid; 58238625Srvb 58338625Srvb ENTRY; 58438625Srvb MARK_ENTRY(CFS_ROOT_STATS); 58538625Srvb result = NULL; 58638625Srvb 58738625Srvb if (vfsp == mi->mi_vfsp) { 58838625Srvb if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) || 58938625Srvb (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) || 59038625Srvb (VTOC(mi->mi_rootvp)->c_fid.Unique != 0)) 59138625Srvb { /* Found valid root. */ 59238625Srvb *vpp = mi->mi_rootvp; 59338625Srvb /* On Mach, this is vref. On NetBSD, VOP_LOCK */ 59438625Srvb vref(*vpp); 59538625Srvb VOP_X_LOCK(*vpp, LK_EXCLUSIVE); 59638625Srvb MARK_INT_SAT(CFS_ROOT_STATS); 59738625Srvb return(0); 59838625Srvb } 59938625Srvb } 60038625Srvb 60138625Srvb error = venus_root(vftomi(vfsp), p->p_cred->pc_ucred, p, &VFid); 60238625Srvb 60338625Srvb if (!error) { 60438625Srvb /* 60538625Srvb * Save the new rootfid in the cnode, and rehash the cnode into the 60638625Srvb * cnode hash with the new fid key. 60738625Srvb */ 60838625Srvb cfs_unsave(VTOC(mi->mi_rootvp)); 60938625Srvb VTOC(mi->mi_rootvp)->c_fid = VFid; 61038625Srvb cfs_save(VTOC(mi->mi_rootvp)); 61138625Srvb 61238625Srvb *vpp = mi->mi_rootvp; 61338625Srvb vref(*vpp); 61438625Srvb VOP_X_LOCK(*vpp, LK_EXCLUSIVE); 61538625Srvb MARK_INT_SAT(CFS_ROOT_STATS); 61638625Srvb goto exit; 61738625Srvb } else if (error == ENODEV) { 61838625Srvb /* Gross hack here! */ 61938625Srvb /* 62038625Srvb * If Venus fails to respond to the CFS_ROOT call, cfscall returns 62138625Srvb * ENODEV. Return the uninitialized root vnode to allow vfs 62238625Srvb * operations such as unmount to continue. Without this hack, 62338625Srvb * there is no way to do an unmount if Venus dies before a 62438625Srvb * successful CFS_ROOT call is done. All vnode operations 62538625Srvb * will fail. 62638625Srvb */ 62738625Srvb *vpp = mi->mi_rootvp; 62838625Srvb vref(*vpp); 62938625Srvb VOP_X_LOCK(*vpp, LK_EXCLUSIVE); 63038625Srvb MARK_INT_FAIL(CFS_ROOT_STATS); 63138625Srvb error = 0; 63238625Srvb goto exit; 63338625Srvb } else { 63438625Srvb CFSDEBUG( CFS_ROOT, myprintf(("error %d in CFS_ROOT\n", error)); ); 63538625Srvb MARK_INT_FAIL(CFS_ROOT_STATS); 63638625Srvb 63738625Srvb goto exit; 63838625Srvb } 63938625Srvb exit: 64038625Srvb return(error); 64138625Srvb} 64238625Srvb 64338625Srvbint 64438625Srvbcfs_quotactl(vfsp, cmd, uid, arg, p) 64538625Srvb struct mount *vfsp; 64638625Srvb int cmd; 64738625Srvb uid_t uid; 64838625Srvb caddr_t arg; 64938625Srvb struct proc *p; 65038625Srvb{ 65138625Srvb ENTRY; 65238625Srvb return (EOPNOTSUPP); 65338625Srvb} 65438625Srvb 65538625Srvb/* 65638625Srvb * Get file system statistics. 65738625Srvb */ 65838625Srvbint 65938625Srvbcfs_nb_statfs(vfsp, sbp, p) 66038625Srvb register struct mount *vfsp; 66138625Srvb struct statfs *sbp; 66238625Srvb struct proc *p; 66338625Srvb{ 66438625Srvb ENTRY; 66538625Srvb/* MARK_ENTRY(CFS_STATFS_STATS); */ 66638625Srvb if (!CFS_MOUNTED(vfsp)) { 66738625Srvb/* MARK_INT_FAIL(CFS_STATFS_STATS);*/ 66838625Srvb return(EINVAL); 66938625Srvb } 67038625Srvb 67138625Srvb bzero(sbp, sizeof(struct statfs)); 67238625Srvb /* XXX - what to do about f_flags, others? --bnoble */ 67338625Srvb /* Below This is what AFS does 67438625Srvb #define NB_SFS_SIZ 0x895440 67538625Srvb */ 67638625Srvb /* Note: Normal fs's have a bsize of 0x400 == 1024 */ 67738625Srvb#ifdef __NetBSD__ 67838625Srvb sbp->f_type = 0; 67938625Srvb#elif defined(__FreeBSD__) 68038625Srvb sbp->f_type = MOUNT_CFS; 68138625Srvb#endif 68238625Srvb sbp->f_bsize = 8192; /* XXX */ 68338625Srvb sbp->f_iosize = 8192; /* XXX */ 68438625Srvb#define NB_SFS_SIZ 0x8AB75D 68538625Srvb sbp->f_blocks = NB_SFS_SIZ; 68638625Srvb sbp->f_bfree = NB_SFS_SIZ; 68738625Srvb sbp->f_bavail = NB_SFS_SIZ; 68838625Srvb sbp->f_files = NB_SFS_SIZ; 68938625Srvb sbp->f_ffree = NB_SFS_SIZ; 69038625Srvb bcopy((caddr_t)&(vfsp->mnt_stat.f_fsid), (caddr_t)&(sbp->f_fsid), sizeof (fsid_t)); 69138625Srvb#ifdef __NetBSD__ 69238625Srvb strncpy(sbp->f_fstypename, MOUNT_CFS, MFSNAMELEN-1); 69338625Srvb#endif 69438625Srvb strcpy(sbp->f_mntonname, "/coda"); 69538625Srvb strcpy(sbp->f_mntfromname, "CFS"); 69638625Srvb/* MARK_INT_SAT(CFS_STATFS_STATS); */ 69738625Srvb return(0); 69838625Srvb} 69938625Srvb 70038625Srvb/* 70138625Srvb * Flush any pending I/O. 70238625Srvb */ 70338625Srvbint 70438625Srvbcfs_sync(vfsp, waitfor, cred, p) 70538625Srvb struct mount *vfsp; 70638625Srvb int waitfor; 70738625Srvb struct ucred *cred; 70838625Srvb struct proc *p; 70938625Srvb{ 71038625Srvb ENTRY; 71138625Srvb MARK_ENTRY(CFS_SYNC_STATS); 71238625Srvb MARK_INT_SAT(CFS_SYNC_STATS); 71338625Srvb return(0); 71438625Srvb} 71538625Srvb 71638625Srvbint 71738625Srvbcfs_vget(vfsp, ino, vpp) 71838625Srvb struct mount *vfsp; 71938625Srvb ino_t ino; 72038625Srvb struct vnode **vpp; 72138625Srvb{ 72238625Srvb ENTRY; 72338625Srvb return (EOPNOTSUPP); 72438625Srvb} 72538625Srvb 72638625Srvb/* 72738625Srvb * fhtovp is now what vget used to be in 4.3-derived systems. For 72838625Srvb * some silly reason, vget is now keyed by a 32 bit ino_t, rather than 72938625Srvb * a type-specific fid. 73038625Srvb */ 73138625Srvbint 73238625Srvbcfs_fhtovp(vfsp, fhp, nam, vpp, exflagsp, creadanonp) 73338625Srvb register struct mount *vfsp; 73438625Srvb struct fid *fhp; 73538625Srvb struct mbuf *nam; 73638625Srvb struct vnode **vpp; 73738625Srvb int *exflagsp; 73838625Srvb struct ucred **creadanonp; 73938625Srvb{ 74038625Srvb struct cfid *cfid = (struct cfid *)fhp; 74138625Srvb struct cnode *cp = 0; 74238625Srvb int error; 74338625Srvb struct proc *p = curproc; /* XXX -mach */ 74438625Srvb ViceFid VFid; 74538625Srvb int vtype; 74638625Srvb 74738625Srvb ENTRY; 74838625Srvb 74938625Srvb MARK_ENTRY(CFS_VGET_STATS); 75038625Srvb /* Check for vget of control object. */ 75138625Srvb if (IS_CTL_FID(&cfid->cfid_fid)) { 75238625Srvb *vpp = cfs_ctlvp; 75338625Srvb vref(cfs_ctlvp); 75438625Srvb MARK_INT_SAT(CFS_VGET_STATS); 75538625Srvb return(0); 75638625Srvb } 75738625Srvb 75838625Srvb error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, p->p_cred->pc_ucred, p, &VFid, &vtype); 75938625Srvb 76038625Srvb if (error) { 76138625Srvb CFSDEBUG(CFS_VGET, myprintf(("vget error %d\n",error));) 76238625Srvb *vpp = (struct vnode *)0; 76338625Srvb } else { 76438625Srvb CFSDEBUG(CFS_VGET, 76538625Srvb myprintf(("vget: vol %lx vno %lx uni %lx type %d result %d\n", 76638625Srvb VFid.Volume, VFid.Vnode, VFid.Unique, vtype, error)); ) 76738625Srvb 76838625Srvb cp = makecfsnode(&VFid, vfsp, vtype); 76938625Srvb *vpp = CTOV(cp); 77038625Srvb } 77138625Srvb return(error); 77238625Srvb} 77338625Srvb 77438625Srvbint 77538625Srvbcfs_vptofh(vnp, fidp) 77638625Srvb struct vnode *vnp; 77738625Srvb struct fid *fidp; 77838625Srvb{ 77938625Srvb ENTRY; 78038625Srvb return (EOPNOTSUPP); 78138625Srvb} 78238625Srvb 78338625Srvb#ifdef __NetBSD__ 78438625Srvbvoid 78538625Srvbcfs_init(void) 78638625Srvb{ 78738625Srvb ENTRY; 78838625Srvb} 78938625Srvb#elif defined(__FreeBSD__) 79038625Srvb#ifdef __FreeBSD_version 79138625Srvbint 79238625Srvbcfs_init(struct vfsconf *vfsp) 79338625Srvb{ 79438625Srvb ENTRY; 79538625Srvb return 0; 79638625Srvb} 79738625Srvb#else 79838625Srvbint 79938625Srvbcfs_init(void) 80038625Srvb{ 80138625Srvb ENTRY; 80238625Srvb return 0; 80338625Srvb} 80438625Srvb#endif 80538625Srvb#endif 80638625Srvb 80738625Srvb#if defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 7) 80838625Srvbint 80938625Srvbcfs_sysctl(name, namelen, oldp, oldlp, newp, newl, p) 81038625Srvb int *name; 81138625Srvb u_int namelen; 81238625Srvb void *oldp; 81338625Srvb size_t *oldlp; 81438625Srvb void *newp; 81538625Srvb size_t newl; 81638625Srvb struct proc *p; 81738625Srvb{ 81838625Srvb 81938625Srvb /* all sysctl names at this level are terminal */ 82038625Srvb if (namelen != 1) 82138625Srvb return (ENOTDIR); /* overloaded */ 82238625Srvb 82338625Srvb switch (name[0]) { 82438625Srvb/* 82538625Srvb case FFS_CLUSTERREAD: 82638625Srvb return (sysctl_int(oldp, oldlp, newp, newl, &doclusterread)); 82738625Srvb */ 82838625Srvb default: 82938625Srvb return (EOPNOTSUPP); 83038625Srvb } 83138625Srvb /* NOTREACHED */ 83238625Srvb} 83338625Srvb#endif 83438625Srvb 83538625Srvb/* 83638625Srvb * To allow for greater ease of use, some vnodes may be orphaned when 83738625Srvb * Venus dies. Certain operations should still be allowed to go 83838625Srvb * through, but without propagating ophan-ness. So this function will 83938625Srvb * get a new vnode for the file from the current run of Venus. */ 84038625Srvb 84138625Srvbint 84238625SrvbgetNewVnode(vpp) 84338625Srvb struct vnode **vpp; 84438625Srvb{ 84538625Srvb struct cfid cfid; 84638625Srvb struct cfs_mntinfo *mi = vftomi((*vpp)->v_mount); 84738625Srvb 84838625Srvb ENTRY; 84938625Srvb 85038625Srvb cfid.cfid_len = (short)sizeof(ViceFid); 85138625Srvb cfid.cfid_fid = VTOC(*vpp)->c_fid; /* Structure assignment. */ 85238625Srvb /* XXX ? */ 85338625Srvb 85438625Srvb /* We're guessing that if set, the 1st element on the list is a 85538625Srvb * valid vnode to use. If not, return ENODEV as venus is dead. 85638625Srvb */ 85738625Srvb if (mi->mi_vfsp == NULL) 85838625Srvb return ENODEV; 85938625Srvb 86038625Srvb return cfs_fhtovp(mi->mi_vfsp, (struct fid*)&cfid, NULL, vpp, 86138625Srvb NULL, NULL); 86238625Srvb} 86338625Srvb 86438625Srvb#include <ufs/ufs/quota.h> 86538625Srvb#include <ufs/ufs/ufsmount.h> 86638625Srvb/* get the mount structure corresponding to a given device. Assume 86738625Srvb * device corresponds to a UFS. Return NULL if no device is found. 86838625Srvb */ 86938625Srvbstruct mount *devtomp(dev) 87038625Srvb dev_t dev; 87138625Srvb{ 87238625Srvb struct mount *mp, *nmp; 87338625Srvb 87438625Srvb for (mp = mountlist.cqh_first; mp != (void*)&mountlist; mp = nmp) { 87538625Srvb nmp = mp->mnt_list.cqe_next; 87638625Srvb if ( 87738625Srvb#ifdef __NetBSD__ 87838625Srvb (!strcmp(mp->mnt_op->vfs_name, MOUNT_UFS)) && 87938625Srvb#endif 88038625Srvb ((VFSTOUFS(mp))->um_dev == (dev_t) dev)) { 88138625Srvb /* mount corresponds to UFS and the device matches one we want */ 88238625Srvb return(mp); 88338625Srvb } 88438625Srvb } 88538625Srvb /* mount structure wasn't found */ 88638625Srvb return(NULL); 88738625Srvb} 888