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_subr.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/coda/coda_subr.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  * HISTORY
   48  * $Log: coda_subr.c,v $
   49  * Revision 1.9  1999/01/17 20:25:15  peter
   50  * Clean up the KLD/LKM goop a bit.
   51  *
   52  * Revision 1.8  1998/10/28 19:33:50  rvb
   53  * Venus must be passed O_CREAT flag on VOP_OPEN iff this is
   54  * a creat so that we can will allow a mode 444 file to be
   55  * written into.  Sync with the latest coda.h and deal with
   56  * collateral damage.
   57  *
   58  * Revision 1.7  1998/09/29 20:19:45  rvb
   59  * Fixes for lkm:
   60  * 1. use VFS_LKM vs ACTUALLY_LKM_NOT_KERNEL
   61  * 2. don't pass -DCODA to lkm build
   62  *
   63  * Revision 1.6  1998/09/25 17:38:31  rvb
   64  * Put "stray" printouts under DIAGNOSTIC.  Make everything build
   65  * with DEBUG on.  Add support for lkm.  (The macro's don't work
   66  * for me; for a good chuckle look at the end of coda_fbsd.c.)
   67  *
   68  * Revision 1.5  1998/09/13 13:57:59  rvb
   69  * Finish conversion of cfs -> coda
   70  *
   71  * Revision 1.4  1998/09/11 18:50:17  rvb
   72  * All the references to cfs, in symbols, structs, and strings
   73  * have been changed to coda.  (Same for CFS.)
   74  *
   75  * Revision 1.2  1998/09/02 19:09:53  rvb
   76  * Pass2 complete
   77  *
   78  * Revision 1.1.1.1  1998/08/29 21:14:52  rvb
   79  * Very Preliminary Coda
   80  *
   81  * Revision 1.11  1998/08/28 18:12:18  rvb
   82  * Now it also works on FreeBSD -current.  This code will be
   83  * committed to the FreeBSD -current and NetBSD -current
   84  * trees.  It will then be tailored to the particular platform
   85  * by flushing conditional code.
   86  *
   87  * Revision 1.10  1998/08/18 17:05:16  rvb
   88  * Don't use __RCSID now
   89  *
   90  * Revision 1.9  1998/08/18 16:31:41  rvb
   91  * Sync the code for NetBSD -current; test on 1.3 later
   92  *
   93  * Revision 1.8  98/01/31  20:53:12  rvb
   94  * First version that works on FreeBSD 2.2.5
   95  * 
   96  * Revision 1.7  98/01/23  11:53:42  rvb
   97  * Bring RVB_CODA1_1 to HEAD
   98  * 
   99  * Revision 1.6.2.3  98/01/23  11:21:05  rvb
  100  * Sync with 2.2.5
  101  * 
  102  * Revision 1.6.2.2  97/12/16  12:40:06  rvb
  103  * Sync with 1.3
  104  * 
  105  * Revision 1.6.2.1  97/12/06  17:41:21  rvb
  106  * Sync with peters coda.h
  107  * 
  108  * Revision 1.6  97/12/05  10:39:17  rvb
  109  * Read CHANGES
  110  * 
  111  * Revision 1.5.4.8  97/11/26  15:28:58  rvb
  112  * Cant make downcall pbuf == union cfs_downcalls yet
  113  * 
  114  * Revision 1.5.4.7  97/11/20  11:46:42  rvb
  115  * Capture current cfs_venus
  116  * 
  117  * Revision 1.5.4.6  97/11/18  10:27:16  rvb
  118  * cfs_nbsd.c is DEAD!!!; integrated into cfs_vf/vnops.c
  119  * cfs_nb_foo and cfs_foo are joined
  120  * 
  121  * Revision 1.5.4.5  97/11/13  22:03:00  rvb
  122  * pass2 cfs_NetBSD.h mt
  123  * 
  124  * Revision 1.5.4.4  97/11/12  12:09:39  rvb
  125  * reorg pass1
  126  * 
  127  * Revision 1.5.4.3  97/11/06  21:02:38  rvb
  128  * first pass at ^c ^z
  129  * 
  130  * Revision 1.5.4.2  97/10/29  16:06:27  rvb
  131  * Kill DYING
  132  * 
  133  * Revision 1.5.4.1  97/10/28 23:10:16  rvb
  134  * >64Meg; venus can be killed!
  135  *
  136  * Revision 1.5  97/08/05  11:08:17  lily
  137  * Removed cfsnc_replace, replaced it with a coda_find, unhash, and
  138  * rehash.  This fixes a cnode leak and a bug in which the fid is
  139  * not actually replaced.  (cfs_namecache.c, cfsnc.h, cfs_subr.c)
  140  * 
  141  * Revision 1.4  96/12/12  22:10:59  bnoble
  142  * Fixed the "downcall invokes venus operation" deadlock in all known cases. 
  143  * There may be more
  144  * 
  145  * Revision 1.3  1996/12/05 16:20:15  bnoble
  146  * Minor debugging aids
  147  *
  148  * Revision 1.2  1996/01/02 16:57:01  bnoble
  149  * Added support for Coda MiniCache and raw inode calls (final commit)
  150  *
  151  * Revision 1.1.2.1  1995/12/20 01:57:27  bnoble
  152  * Added CODA-specific files
  153  *
  154  * Revision 3.1.1.1  1995/03/04  19:07:59  bnoble
  155  * Branch for NetBSD port revisions
  156  *
  157  * Revision 3.1  1995/03/04  19:07:58  bnoble
  158  * Bump to major revision 3 to prepare for NetBSD port
  159  *
  160  * Revision 2.8  1995/03/03  17:00:04  dcs
  161  * Fixed kernel bug involving sleep and upcalls. Basically if you killed
  162  * a job waiting on venus, the venus upcall queues got trashed. Depending
  163  * on luck, you could kill the kernel or not.
  164  * (mods to cfs_subr.c and cfs_mach.d)
  165  *
  166  * Revision 2.7  95/03/02  22:45:21  dcs
  167  * Sun4 compatibility
  168  * 
  169  * Revision 2.6  95/02/17  16:25:17  dcs
  170  * These versions represent several changes:
  171  * 1. Allow venus to restart even if outstanding references exist.
  172  * 2. Have only one ctlvp per client, as opposed to one per mounted cfs device.d
  173  * 3. Allow ody_expand to return many members, not just one.
  174  * 
  175  * Revision 2.5  94/11/09  15:56:26  dcs
  176  * Had the thread sleeping on the wrong thing!
  177  * 
  178  * Revision 2.4  94/10/14  09:57:57  dcs
  179  * Made changes 'cause sun4s have braindead compilers
  180  * 
  181  * Revision 2.3  94/10/12  16:46:26  dcs
  182  * Cleaned kernel/venus interface by removing XDR junk, plus
  183  * so cleanup to allow this code to be more easily ported.
  184  * 
  185  * Revision 1.2  92/10/27  17:58:22  lily
  186  * merge kernel/latest and alpha/src/cfs
  187  * 
  188  * Revision 2.4  92/09/30  14:16:26  mja
  189  *      Incorporated Dave Steere's fix for the GNU-Emacs bug.
  190  *      Also, included his coda_flush routine in place of the former coda_nc_flush.
  191  *      [91/02/07            jjk]
  192  * 
  193  *      Added contributors blurb.
  194  *      [90/12/13            jjk]
  195  * 
  196  *      Hack to allow users to keep coda venus calls uninterruptible. THis
  197  *      basically prevents the Gnu-emacs bug from appearing, in which a call
  198  *      was being interrupted, and return EINTR, but gnu didn't check for the
  199  *      error and figured the file was buggered.
  200  *      [90/12/09            dcs]
  201  * 
  202  * Revision 2.3  90/08/10  10:23:20  mrt
  203  *      Removed include of vm/vm_page.h as it no longer exists.
  204  *      [90/08/10            mrt]
  205  * 
  206  * Revision 2.2  90/07/05  11:26:35  mrt
  207  *      Initialize name cache on first call to vcopen.
  208  *      [90/05/23            dcs]
  209  * 
  210  *      Created for the Coda File System.
  211  *      [90/05/23            dcs]
  212  * 
  213  * Revision 1.5  90/05/31  17:01:35  dcs
  214  * Prepare for merge with facilities kernel.
  215  * 
  216  * Revision 1.2  90/03/19  15:56:25  dcs
  217  * Initialize name cache on first call to vcopen.
  218  * 
  219  * Revision 1.1  90/03/15  10:43:26  jjk
  220  * Initial revision
  221  * 
  222  */ 
  223 
  224 /* NOTES: rvb
  225  * 1.   Added coda_unmounting to mark all cnodes as being UNMOUNTING.  This has to
  226  *       be done before dounmount is called.  Because some of the routines that
  227  *       dounmount calls before coda_unmounted might try to force flushes to venus.
  228  *       The vnode pager does this.
  229  * 2.   coda_unmounting marks all cnodes scanning coda_cache.
  230  * 3.   cfs_checkunmounting (under DEBUG) checks all cnodes by chasing the vnodes
  231  *       under the /coda mount point.
  232  * 4.   coda_cacheprint (under DEBUG) prints names with vnode/cnode address
  233  */
  234 
  235 #include <vcoda.h>
  236 
  237 #include <sys/param.h>
  238 #include <sys/systm.h>
  239 #include <sys/proc.h>
  240 #include <sys/malloc.h>
  241 #include <sys/select.h>
  242 #include <sys/mount.h>
  243 
  244 #include <coda/coda.h>
  245 #include <coda/cnode.h>
  246 #include <coda/coda_subr.h>
  247 #include <coda/coda_namecache.h>
  248 
  249 int coda_active = 0;
  250 int coda_reuse = 0;
  251 int coda_new = 0;
  252 
  253 struct cnode *coda_freelist = NULL;
  254 struct cnode *coda_cache[CODA_CACHESIZE];
  255 
  256 #define coda_hash(fid) (((fid)->Volume + (fid)->Vnode) & (CODA_CACHESIZE-1))
  257 #define CNODE_NEXT(cp)  ((cp)->c_next)
  258 #define ODD(vnode)        ((vnode) & 0x1)
  259 
  260 /*
  261  * Allocate a cnode.
  262  */
  263 struct cnode *
  264 coda_alloc(void)
  265 {
  266     struct cnode *cp;
  267 
  268     if (coda_freelist) {
  269         cp = coda_freelist;
  270         coda_freelist = CNODE_NEXT(cp);
  271         coda_reuse++;
  272     }
  273     else {
  274         CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
  275         /* NetBSD vnodes don't have any Pager info in them ('cause there are
  276            no external pagers, duh!) */
  277 #define VNODE_VM_INFO_INIT(vp)         /* MT */
  278         VNODE_VM_INFO_INIT(CTOV(cp));
  279         coda_new++;
  280     }
  281     bzero(cp, sizeof (struct cnode));
  282 
  283     return(cp);
  284 }
  285 
  286 /*
  287  * Deallocate a cnode.
  288  */
  289 void
  290 coda_free(cp)
  291      register struct cnode *cp;
  292 {
  293 
  294     CNODE_NEXT(cp) = coda_freelist;
  295     coda_freelist = cp;
  296 }
  297 
  298 /*
  299  * Put a cnode in the hash table
  300  */
  301 void
  302 coda_save(cp)
  303      struct cnode *cp;
  304 {
  305         CNODE_NEXT(cp) = coda_cache[coda_hash(&cp->c_fid)];
  306         coda_cache[coda_hash(&cp->c_fid)] = cp;
  307 }
  308 
  309 /*
  310  * Remove a cnode from the hash table
  311  */
  312 void
  313 coda_unsave(cp)
  314      struct cnode *cp;
  315 {
  316     struct cnode *ptr;
  317     struct cnode *ptrprev = NULL;
  318     
  319     ptr = coda_cache[coda_hash(&cp->c_fid)]; 
  320     while (ptr != NULL) { 
  321         if (ptr == cp) { 
  322             if (ptrprev == NULL) {
  323                 coda_cache[coda_hash(&cp->c_fid)] 
  324                     = CNODE_NEXT(ptr);
  325             } else {
  326                 CNODE_NEXT(ptrprev) = CNODE_NEXT(ptr);
  327             }
  328             CNODE_NEXT(cp) = (struct cnode *)NULL;
  329             
  330             return; 
  331         }       
  332         ptrprev = ptr;
  333         ptr = CNODE_NEXT(ptr);
  334     }   
  335 }
  336 
  337 /*
  338  * Lookup a cnode by fid. If the cnode is dying, it is bogus so skip it.
  339  * NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95
  340  */
  341 struct cnode *
  342 coda_find(fid) 
  343      ViceFid *fid;
  344 {
  345     struct cnode *cp;
  346 
  347     cp = coda_cache[coda_hash(fid)];
  348     while (cp) {
  349         if ((cp->c_fid.Vnode == fid->Vnode) &&
  350             (cp->c_fid.Volume == fid->Volume) &&
  351             (cp->c_fid.Unique == fid->Unique) &&
  352             (!IS_UNMOUNTING(cp)))
  353             {
  354                 coda_active++;
  355                 return(cp); 
  356             }               
  357         cp = CNODE_NEXT(cp);
  358     }
  359     return(NULL);
  360 }
  361 
  362 /*
  363  * coda_kill is called as a side effect to vcopen. To prevent any
  364  * cnodes left around from an earlier run of a venus or warden from
  365  * causing problems with the new instance, mark any outstanding cnodes
  366  * as dying. Future operations on these cnodes should fail (excepting
  367  * coda_inactive of course!). Since multiple venii/wardens can be
  368  * running, only kill the cnodes for a particular entry in the
  369  * coda_mnttbl. -- DCS 12/1/94 */
  370 
  371 int
  372 coda_kill(whoIam, dcstat)
  373         struct mount *whoIam;
  374         enum dc_status dcstat;
  375 {
  376         int hash, count = 0;
  377         struct cnode *cp;
  378         
  379         /* 
  380          * Algorithm is as follows: 
  381          *     Second, flush whatever vnodes we can from the name cache.
  382          * 
  383          *     Finally, step through whatever is left and mark them dying.
  384          *        This prevents any operation at all.
  385          */
  386         
  387         /* This is slightly overkill, but should work. Eventually it'd be
  388          * nice to only flush those entries from the namecache that
  389          * reference a vnode in this vfs.  */
  390         coda_nc_flush(dcstat);
  391         
  392         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  393                 for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
  394                         if (CTOV(cp)->v_mount == whoIam) {
  395 #ifdef  DEBUG
  396                                 printf("coda_kill: vp %p, cp %p\n", CTOV(cp), cp);
  397 #endif
  398                                 count++;
  399                                 CODADEBUG(CODA_FLUSH, 
  400                                          myprintf(("Live cnode fid %lx.%lx.%lx flags %d count %d\n",
  401                                                    (cp->c_fid).Volume,
  402                                                    (cp->c_fid).Vnode,
  403                                                    (cp->c_fid).Unique, 
  404                                                    cp->c_flags,
  405                                                    CTOV(cp)->v_usecount)); );
  406                         }
  407                 }
  408         }
  409         return count;
  410 }
  411 
  412 /*
  413  * There are two reasons why a cnode may be in use, it may be in the
  414  * name cache or it may be executing.  
  415  */
  416 void
  417 coda_flush(dcstat)
  418         enum dc_status dcstat;
  419 {
  420     int hash;
  421     struct cnode *cp;
  422     
  423     coda_clstat.ncalls++;
  424     coda_clstat.reqs[CODA_FLUSH]++;
  425     
  426     coda_nc_flush(dcstat);          /* flush files from the name cache */
  427 
  428     for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  429         for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {  
  430             if (!ODD(cp->c_fid.Vnode)) /* only files can be executed */
  431                 coda_vmflush(cp);
  432         }
  433     }
  434 }
  435 
  436 /*
  437  * As a debugging measure, print out any cnodes that lived through a
  438  * name cache flush.  
  439  */
  440 void
  441 coda_testflush(void)
  442 {
  443     int hash;
  444     struct cnode *cp;
  445     
  446     for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  447         for (cp = coda_cache[hash];
  448              cp != NULL;
  449              cp = CNODE_NEXT(cp)) {  
  450             myprintf(("Live cnode fid %lx.%lx.%lx count %d\n",
  451                       (cp->c_fid).Volume,(cp->c_fid).Vnode,
  452                       (cp->c_fid).Unique, CTOV(cp)->v_usecount));
  453         }
  454     }
  455 }
  456 
  457 /*
  458  *     First, step through all cnodes and mark them unmounting.
  459  *         NetBSD kernels may try to fsync them now that venus
  460  *         is dead, which would be a bad thing.
  461  *
  462  */
  463 void
  464 coda_unmounting(whoIam)
  465         struct mount *whoIam;
  466 {       
  467         int hash;
  468         struct cnode *cp;
  469 
  470         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  471                 for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
  472                         if (CTOV(cp)->v_mount == whoIam) {
  473                                 if (cp->c_flags & (C_LOCKED|C_WANTED)) {
  474                                         printf("coda_unmounting: Unlocking %p\n", cp);
  475                                         cp->c_flags &= ~(C_LOCKED|C_WANTED);
  476                                         wakeup((caddr_t) cp);
  477                                 }
  478                                 cp->c_flags |= C_UNMOUNTING;
  479                         }
  480                 }
  481         }
  482 }
  483 
  484 #ifdef  DEBUG
  485 void
  486 coda_checkunmounting(mp)
  487         struct mount *mp;
  488 {       
  489         register struct vnode *vp, *nvp;
  490         struct cnode *cp;
  491         int count = 0, bad = 0;
  492 loop:
  493         for (vp = mp->mnt_vnodelist.lh_first; vp; vp = nvp) {
  494                 if (vp->v_mount != mp)
  495                         goto loop;
  496                 nvp = vp->v_mntvnodes.le_next;
  497                 cp = VTOC(vp);
  498                 count++;
  499                 if (!(cp->c_flags & C_UNMOUNTING)) {
  500                         bad++;
  501                         printf("vp %p, cp %p missed\n", vp, cp);
  502                         cp->c_flags |= C_UNMOUNTING;
  503                 }
  504         }
  505 }
  506 
  507 void
  508 coda_cacheprint(whoIam)
  509         struct mount *whoIam;
  510 {       
  511         int hash;
  512         struct cnode *cp;
  513         int count = 0;
  514 
  515         printf("coda_cacheprint: coda_ctlvp %p, cp %p", coda_ctlvp, VTOC(coda_ctlvp));
  516         coda_nc_name(VTOC(coda_ctlvp));
  517         printf("\n");
  518 
  519         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  520                 for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
  521                         if (CTOV(cp)->v_mount == whoIam) {
  522                                 printf("coda_cacheprint: vp %p, cp %p", CTOV(cp), cp);
  523                                 coda_nc_name(cp);
  524                                 printf("\n");
  525                                 count++;
  526                         }
  527                 }
  528         }
  529         printf("coda_cacheprint: count %d\n", count);
  530 }
  531 #endif
  532 
  533 /*
  534  * There are 6 cases where invalidations occur. The semantics of each
  535  * is listed here.
  536  *
  537  * CODA_FLUSH     -- flush all entries from the name cache and the cnode cache.
  538  * CODA_PURGEUSER -- flush all entries from the name cache for a specific user
  539  *                  This call is a result of token expiration.
  540  *
  541  * The next two are the result of callbacks on a file or directory.
  542  * CODA_ZAPDIR    -- flush the attributes for the dir from its cnode.
  543  *                  Zap all children of this directory from the namecache.
  544  * CODA_ZAPFILE   -- flush the attributes for a file.
  545  *
  546  * The fifth is a result of Venus detecting an inconsistent file.
  547  * CODA_PURGEFID  -- flush the attribute for the file
  548  *                  If it is a dir (odd vnode), purge its 
  549  *                  children from the namecache
  550  *                  remove the file from the namecache.
  551  *
  552  * The sixth allows Venus to replace local fids with global ones
  553  * during reintegration.
  554  *
  555  * CODA_REPLACE -- replace one ViceFid with another throughout the name cache 
  556  */
  557 
  558 int handleDownCall(opcode, out)
  559      int opcode; union outputArgs *out;
  560 {
  561     int error;
  562 
  563     /* Handle invalidate requests. */
  564     switch (opcode) {
  565       case CODA_FLUSH : {
  566 
  567           coda_flush(IS_DOWNCALL);
  568           
  569           CODADEBUG(CODA_FLUSH,coda_testflush();)    /* print remaining cnodes */
  570               return(0);
  571       }
  572         
  573       case CODA_PURGEUSER : {
  574           coda_clstat.ncalls++;
  575           coda_clstat.reqs[CODA_PURGEUSER]++;
  576           
  577           /* XXX - need to prevent fsync's */
  578           coda_nc_purge_user(out->coda_purgeuser.cred.cr_uid, IS_DOWNCALL);
  579           return(0);
  580       }
  581         
  582       case CODA_ZAPFILE : {
  583           struct cnode *cp;
  584 
  585           error = 0;
  586           coda_clstat.ncalls++;
  587           coda_clstat.reqs[CODA_ZAPFILE]++;
  588           
  589           cp = coda_find(&out->coda_zapfile.CodaFid);
  590           if (cp != NULL) {
  591               vref(CTOV(cp));
  592               
  593               cp->c_flags &= ~C_VATTR;
  594               if (CTOV(cp)->v_flag & VTEXT)
  595                   error = coda_vmflush(cp);
  596               CODADEBUG(CODA_ZAPFILE, myprintf(("zapfile: fid = (%lx.%lx.%lx), 
  597                                               refcnt = %d, error = %d\n",
  598                                               cp->c_fid.Volume, 
  599                                               cp->c_fid.Vnode, 
  600                                               cp->c_fid.Unique, 
  601                                               CTOV(cp)->v_usecount - 1, error)););
  602               if (CTOV(cp)->v_usecount == 1) {
  603                   cp->c_flags |= C_PURGING;
  604               }
  605               vrele(CTOV(cp));
  606           }
  607           
  608           return(error);
  609       }
  610         
  611       case CODA_ZAPDIR : {
  612           struct cnode *cp;
  613 
  614           coda_clstat.ncalls++;
  615           coda_clstat.reqs[CODA_ZAPDIR]++;
  616           
  617           cp = coda_find(&out->coda_zapdir.CodaFid);
  618           if (cp != NULL) {
  619               vref(CTOV(cp));
  620               
  621               cp->c_flags &= ~C_VATTR;
  622               coda_nc_zapParentfid(&out->coda_zapdir.CodaFid, IS_DOWNCALL);     
  623               
  624               CODADEBUG(CODA_ZAPDIR, myprintf(("zapdir: fid = (%lx.%lx.%lx), 
  625                                           refcnt = %d\n",cp->c_fid.Volume, 
  626                                              cp->c_fid.Vnode, 
  627                                              cp->c_fid.Unique, 
  628                                              CTOV(cp)->v_usecount - 1)););
  629               if (CTOV(cp)->v_usecount == 1) {
  630                   cp->c_flags |= C_PURGING;
  631               }
  632               vrele(CTOV(cp));
  633           }
  634           
  635           return(0);
  636       }
  637         
  638       case CODA_PURGEFID : {
  639           struct cnode *cp;
  640 
  641           error = 0;
  642           coda_clstat.ncalls++;
  643           coda_clstat.reqs[CODA_PURGEFID]++;
  644 
  645           cp = coda_find(&out->coda_purgefid.CodaFid);
  646           if (cp != NULL) {
  647               vref(CTOV(cp));
  648               if (ODD(out->coda_purgefid.CodaFid.Vnode)) { /* Vnode is a directory */
  649                   coda_nc_zapParentfid(&out->coda_purgefid.CodaFid,
  650                                      IS_DOWNCALL);     
  651               }
  652               cp->c_flags &= ~C_VATTR;
  653               coda_nc_zapfid(&out->coda_purgefid.CodaFid, IS_DOWNCALL);
  654               if (!(ODD(out->coda_purgefid.CodaFid.Vnode)) 
  655                   && (CTOV(cp)->v_flag & VTEXT)) {
  656                   
  657                   error = coda_vmflush(cp);
  658               }
  659               CODADEBUG(CODA_PURGEFID, myprintf(("purgefid: fid = (%lx.%lx.%lx), refcnt = %d, error = %d\n",
  660                                             cp->c_fid.Volume, cp->c_fid.Vnode,
  661                                             cp->c_fid.Unique, 
  662                                             CTOV(cp)->v_usecount - 1, error)););
  663               if (CTOV(cp)->v_usecount == 1) {
  664                   cp->c_flags |= C_PURGING;
  665               }
  666               vrele(CTOV(cp));
  667           }
  668           return(error);
  669       }
  670 
  671       case CODA_REPLACE : {
  672           struct cnode *cp = NULL;
  673 
  674           coda_clstat.ncalls++;
  675           coda_clstat.reqs[CODA_REPLACE]++;
  676           
  677           cp = coda_find(&out->coda_replace.OldFid);
  678           if (cp != NULL) { 
  679               /* remove the cnode from the hash table, replace the fid, and reinsert */
  680               vref(CTOV(cp));
  681               coda_unsave(cp);
  682               cp->c_fid = out->coda_replace.NewFid;
  683               coda_save(cp);
  684 
  685               CODADEBUG(CODA_REPLACE, myprintf(("replace: oldfid = (%lx.%lx.%lx), newfid = (%lx.%lx.%lx), cp = %p\n",
  686                                            out->coda_replace.OldFid.Volume,
  687                                            out->coda_replace.OldFid.Vnode,
  688                                            out->coda_replace.OldFid.Unique,
  689                                            cp->c_fid.Volume, cp->c_fid.Vnode, 
  690                                            cp->c_fid.Unique, cp));)
  691               vrele(CTOV(cp));
  692           }
  693           return (0);
  694       }
  695       default:
  696         myprintf(("handleDownCall: unknown opcode %d\n", opcode));
  697         return (EINVAL);
  698     }
  699 }
  700 
  701 /* coda_grab_vnode: lives in either cfs_mach.c or cfs_nbsd.c */
  702 
  703 int
  704 coda_vmflush(cp)
  705      struct cnode *cp;
  706 {
  707     return 0;
  708 }
  709 
  710 
  711 /* 
  712  * kernel-internal debugging switches
  713  */
  714 void coda_debugon(void)
  715 {
  716     codadebug = -1;
  717     coda_nc_debug = -1;
  718     coda_vnop_print_entry = 1;
  719     coda_psdev_print_entry = 1;
  720     coda_vfsop_print_entry = 1;
  721 }
  722 
  723 void coda_debugoff(void)
  724 {
  725     codadebug = 0;
  726     coda_nc_debug = 0;
  727     coda_vnop_print_entry = 0;
  728     coda_psdev_print_entry = 0;
  729     coda_vfsop_print_entry = 0;
  730 }
  731 
  732 /*
  733  * Utilities used by both client and server
  734  * Standard levels:
  735  * 0) no debugging
  736  * 1) hard failures
  737  * 2) soft failures
  738  * 3) current test software
  739  * 4) main procedure entry points
  740  * 5) main procedure exit points
  741  * 6) utility procedure entry points
  742  * 7) utility procedure exit points
  743  * 8) obscure procedure entry points
  744  * 9) obscure procedure exit points
  745  * 10) random stuff
  746  * 11) all <= 1
  747  * 12) all <= 2
  748  * 13) all <= 3
  749  * ...
  750  */

Cache object: ef3a61faee4f8041988e0f72786d27c9


[ 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.