The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/coda/coda_vfsops.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 4f0ce37e4fbd16c855645aa89c74dc0e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.