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/fs/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  *             Coda: an Experimental Distributed File System
    3  *                              Release 3.1
    4  *
    5  *           Copyright (c) 1987-1998 Carnegie Mellon University
    6  *                          All Rights Reserved
    7  *
    8  * Permission  to  use, copy, modify and distribute this software and its
    9  * documentation is hereby granted,  provided  that  both  the  copyright
   10  * notice  and  this  permission  notice  appear  in  all  copies  of the
   11  * software, derivative works or  modified  versions,  and  any  portions
   12  * thereof, and that both notices appear in supporting documentation, and
   13  * that credit is given to Carnegie Mellon University  in  all  documents
   14  * and publicity pertaining to direct or indirect use of this code or its
   15  * derivatives.
   16  *
   17  * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS  KNOWN  TO  HAVE  BUGS,
   18  * SOME  OF  WHICH MAY HAVE SERIOUS CONSEQUENCES.  CARNEGIE MELLON ALLOWS
   19  * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.   CARNEGIE  MELLON
   20  * DISCLAIMS  ANY  LIABILITY  OF  ANY  KIND  FOR  ANY  DAMAGES WHATSOEVER
   21  * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE  OR  OF
   22  * ANY DERIVATIVE WORK.
   23  *
   24  * Carnegie  Mellon  encourages  users  of  this  software  to return any
   25  * improvements or extensions that  they  make,  and  to  grant  Carnegie
   26  * Mellon the rights to redistribute these changes without encumbrance.
   27  *
   28  *      @(#) src/sys/coda/coda_subr.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
   29  */
   30 
   31 /*-
   32  * Mach Operating System
   33  * Copyright (c) 1989 Carnegie-Mellon University
   34  * All rights reserved.  The CMU software License Agreement specifies
   35  * the terms and conditions for use and redistribution.
   36  */
   37 
   38 /*
   39  * This code was written for the Coda filesystem at Carnegie Mellon
   40  * University.  Contributers include David Steere, James Kistler, and
   41  * M. Satyanarayanan.
   42  */
   43 
   44 /*-
   45  * NOTES: rvb
   46  * 1.   Added coda_unmounting to mark all cnodes as being UNMOUNTING.  This
   47  *      has to be done before dounmount is called.  Because some of the
   48  *      routines that dounmount calls before coda_unmounted might try to
   49  *      force flushes to venus.  The vnode pager does this.
   50  * 2.   coda_unmounting marks all cnodes scanning coda_cache.
   51  * 3.   cfs_checkunmounting (under DEBUG) checks all cnodes by chasing the
   52  *      vnodes under the /coda mount point.
   53  * 4.   coda_cacheprint (under DEBUG) prints names with vnode/cnode address.
   54  */
   55 
   56 #include <sys/cdefs.h>
   57 __FBSDID("$FreeBSD$");
   58 
   59 #include <sys/param.h>
   60 #include <sys/systm.h>
   61 #include <sys/lock.h>
   62 #include <sys/malloc.h>
   63 #include <sys/mutex.h>
   64 #include <sys/mount.h>
   65 
   66 #include <fs/coda/coda.h>
   67 #include <fs/coda/cnode.h>
   68 #include <fs/coda/coda_subr.h>
   69 
   70 static int coda_active = 0;
   71 static int coda_reuse = 0;
   72 static int coda_new = 0;
   73 
   74 static struct cnode *coda_freelist = NULL;
   75 static struct cnode *coda_cache[CODA_CACHESIZE];
   76 
   77 #define CNODE_NEXT(cp)  ((cp)->c_next)
   78 
   79 #ifdef CODA_COMPAT_5
   80 #define coda_hash(fid)  (((fid)->Volume + (fid)->Vnode) & (CODA_CACHESIZE-1))
   81 #define IS_DIR(cnode)   (cnode.Vnode & 0x1)
   82 #else
   83 #define coda_hash(fid)  (coda_f2i(fid) & (CODA_CACHESIZE-1))
   84 #define IS_DIR(cnode)   (cnode.opaque[2] & 0x1)
   85 #endif
   86 
   87 /*
   88  * Allocate a cnode.
   89  */
   90 struct cnode *
   91 coda_alloc(void)
   92 {
   93         struct cnode *cp;
   94 
   95         if (coda_freelist != NULL) {
   96                 cp = coda_freelist;
   97                 coda_freelist = CNODE_NEXT(cp);
   98                 coda_reuse++;
   99         } else {
  100                 CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
  101 
  102                 /*
  103                  * FreeBSD vnodes don't have any Pager info in them ('cause
  104                  * there are no external pagers, duh!).
  105                  */
  106 #define VNODE_VM_INFO_INIT(vp)         /* MT */
  107                 VNODE_VM_INFO_INIT(CTOV(cp));
  108                 coda_new++;
  109         }
  110         bzero(cp, sizeof (struct cnode));
  111         return (cp);
  112 }
  113 
  114 /*
  115  * Deallocate a cnode.
  116  */
  117 void
  118 coda_free(struct cnode *cp)
  119 {
  120 
  121         CNODE_NEXT(cp) = coda_freelist;
  122         coda_freelist = cp;
  123 }
  124 
  125 /*
  126  * Put a cnode in the hash table.
  127  */
  128 void
  129 coda_save(struct cnode *cp)
  130 {
  131 
  132         CNODE_NEXT(cp) = coda_cache[coda_hash(&cp->c_fid)];
  133         coda_cache[coda_hash(&cp->c_fid)] = cp;
  134 }
  135 
  136 /*
  137  * Remove a cnode from the hash table.
  138  */
  139 void
  140 coda_unsave(struct cnode *cp)
  141 {
  142         struct cnode *ptr;
  143         struct cnode *ptrprev = NULL;
  144 
  145         ptr = coda_cache[coda_hash(&cp->c_fid)];
  146         while (ptr != NULL) {
  147                 if (ptr == cp) {
  148                         if (ptrprev == NULL)
  149                                 coda_cache[coda_hash(&cp->c_fid)] =
  150                                     CNODE_NEXT(ptr);
  151                         else
  152                                 CNODE_NEXT(ptrprev) = CNODE_NEXT(ptr);
  153                         CNODE_NEXT(cp) = (struct cnode *)NULL;
  154                         return;
  155                 }
  156                 ptrprev = ptr;
  157                 ptr = CNODE_NEXT(ptr);
  158         }
  159 }
  160 
  161 /*
  162  * Lookup a cnode by fid. If the cnode is dying, it is bogus so skip it.
  163  *
  164  * NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95
  165  */
  166 struct cnode *
  167 coda_find(struct CodaFid *fid)
  168 {
  169         struct cnode *cp;
  170 
  171         cp = coda_cache[coda_hash(fid)];
  172         while (cp) {
  173                 if (coda_fid_eq(&(cp->c_fid), fid) && (!IS_UNMOUNTING(cp))) {
  174                         coda_active++;
  175                         return (cp);
  176                 }
  177                 cp = CNODE_NEXT(cp);
  178         }
  179         return (NULL);
  180 }
  181 
  182 /*
  183  * Clear all cached access control decisions from Coda.
  184  */
  185 static void
  186 coda_acccache_purge(struct mount *mnt)
  187 {
  188         struct cnode *cp;
  189         int hash;
  190 
  191         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  192                 for (cp = coda_cache[hash]; cp != NULL;
  193                     cp = CNODE_NEXT(cp)) {
  194                         if (CTOV(cp)->v_mount == mnt && VALID_ACCCACHE(cp)) {
  195                                 CODADEBUG(CODA_FLUSH, myprintf(("acccache "
  196                                     "purge fid %s uid %d mode 0x%x\n",
  197                                     coda_f2s(&cp->c_fid), cp->c_cached_uid,
  198                                     (int)cp->c_cached_mode)););
  199                                 cp->c_flags &= ~C_ACCCACHE;
  200                         }
  201                 }
  202         }
  203 }
  204 
  205 /*
  206  * When a user loses their tokens (or other related events), we invalidate
  207  * any cached access rights in the access cache.  In the Linux version of
  208  * Coda, we maintain a global epoch and simply bump it to invalidate all
  209  * cached results generated in the epoch.  For now, we walk all cnodes and
  210  * manually invalidate just that uid in FreeBSD.
  211  */
  212 static void
  213 coda_acccache_purgeuser(struct mount *mnt, uid_t uid)
  214 {
  215         struct cnode *cp;
  216         int hash;
  217 
  218         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  219                 for (cp = coda_cache[hash]; cp != NULL;
  220                     cp = CNODE_NEXT(cp)) {
  221                         if (CTOV(cp)->v_mount == mnt &&
  222                             VALID_ACCCACHE(cp) && (cp->c_cached_uid == uid)) {
  223                                 CODADEBUG(CODA_PURGEUSER, myprintf((
  224                                     "acccache purgeuser fid %s uid %d mode "
  225                                     "0x%x\n", coda_f2s(&cp->c_fid),
  226                                     cp->c_cached_uid, (int)cp->c_cached_mode)););
  227                                 cp->c_flags &= ~C_ACCCACHE;
  228                         }
  229                 }
  230         }
  231 }
  232 
  233 /*
  234  * coda_kill is called as a side effect to vcopen.  To prevent any cnodes
  235  * left around from an earlier run of a venus or warden from causing problems
  236  * with the new instance, mark any outstanding cnodes as dying.  Future
  237  * operations on these cnodes should fail (excepting coda_inactive of
  238  * course!).  Since multiple venii/wardens can be running, only kill the
  239  * cnodes for a particular entry in the coda_mnttbl. -- DCS 12/1/94
  240  *
  241  * XXX: I don't believe any special behavior is required with respect to the
  242  * global namecache here, as /coda will have unmounted and hence cache_flush
  243  * will have run...?
  244  */
  245 int
  246 coda_kill(struct mount *whoIam, enum dc_status dcstat)
  247 {
  248         int hash, count = 0;
  249         struct cnode *cp;
  250 
  251         /*-
  252          * Algorithm is as follows:
  253          *     Second, flush whatever vnodes we can from the name cache.
  254          *
  255          *     Finally, step through whatever is left and mark them dying.
  256          *        This prevents any operation at all.
  257          *
  258          * This is slightly overkill, but should work.  Eventually it'd be
  259          * nice to only flush those entries from the namecache that reference
  260          * a vnode in this vfs.
  261          *
  262          * XXXRW: Perhaps we no longer need to purge the name cache when
  263          * using the VFS name cache, as unmount will do that.
  264          */
  265         cache_purgevfs(whoIam);
  266         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  267                 for (cp = coda_cache[hash];cp != NULL;
  268                     cp = CNODE_NEXT(cp)) {
  269                         if (CTOV(cp)->v_mount == whoIam) {
  270 #ifdef DEBUG
  271                                 printf("coda_kill: vp %p, cp %p\n", CTOV(cp),
  272                                     cp);
  273 #endif
  274                                 count++;
  275                                 CODADEBUG(CODA_FLUSH, myprintf(("Live cnode "
  276                                     "fid %s flags %d count %d\n",
  277                                     coda_f2s(&cp->c_fid), cp->c_flags,
  278                                     vrefcnt(CTOV(cp)))););
  279                         }
  280                 }
  281         }
  282         return (count);
  283 }
  284 
  285 /*
  286  * There are two reasons why a cnode may be in use, it may be in the name
  287  * cache or it may be executing.
  288  */
  289 void
  290 coda_flush(struct coda_mntinfo *mnt, enum dc_status dcstat)
  291 {
  292         int hash;
  293         struct cnode *cp;
  294 
  295         coda_clstat.ncalls++;
  296         coda_clstat.reqs[CODA_FLUSH]++;
  297 
  298         coda_acccache_purge(mnt->mi_vfsp);
  299         cache_purgevfs(mnt->mi_vfsp);
  300         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  301                 for (cp = coda_cache[hash]; cp != NULL;
  302                     cp = CNODE_NEXT(cp)) {
  303                         /*
  304                          * Only files that can be executed need to be flushed
  305                          * from the VM.
  306                          *
  307                          * NOTE: Currently this doesn't do anything, but
  308                          * perhaps it should?
  309                          */
  310                         if (!IS_DIR(cp->c_fid))
  311                                 coda_vmflush(cp);
  312                 }
  313         }
  314 }
  315 
  316 /*
  317  * As a debugging measure, print out any cnodes that lived through a name
  318  * cache flush.
  319  */
  320 void
  321 coda_testflush(void)
  322 {
  323         int hash;
  324         struct cnode *cp;
  325 
  326         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  327                 for (cp = coda_cache[hash]; cp != NULL;
  328                     cp = CNODE_NEXT(cp))
  329                         myprintf(("Live cnode fid %s count %d\n",
  330                             coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount));
  331         }
  332 }
  333 
  334 /*
  335  * First, step through all cnodes and mark them unmounting.  FreeBSD kernels
  336  * may try to fsync them now that venus is dead, which would be a bad thing.
  337  */
  338 void
  339 coda_unmounting(struct mount *whoIam)
  340 {
  341         int hash;
  342         struct cnode *cp;
  343 
  344         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  345                 for (cp = coda_cache[hash]; cp != NULL;
  346                     cp = CNODE_NEXT(cp)) {
  347                         if (CTOV(cp)->v_mount == whoIam) {
  348                                 if (cp->c_flags & (C_LOCKED|C_WANTED)) {
  349                                         printf("coda_unmounting: Unlocking "
  350                                             "%p\n", cp);
  351                                         cp->c_flags &= ~(C_LOCKED|C_WANTED);
  352                                         wakeup((caddr_t) cp);
  353                                 }
  354                                 cp->c_flags |= C_UNMOUNTING;
  355                         }
  356                 }
  357         }
  358 }
  359 
  360 #ifdef DEBUG
  361 void
  362 coda_checkunmounting(struct mount *mp)
  363 {
  364         struct vnode *vp, *nvp;
  365         struct cnode *cp;
  366         int count = 0, bad = 0;
  367 
  368         MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
  369                 cp = VTOC(vp);
  370                 count++;
  371                 if (!(cp->c_flags & C_UNMOUNTING)) {
  372                         bad++;
  373                         printf("vp %p, cp %p missed\n", vp, cp);
  374                         cp->c_flags |= C_UNMOUNTING;
  375                 }
  376                 VI_UNLOCK(vp);
  377         }
  378 }
  379 
  380 void
  381 coda_cacheprint(struct mount *whoIam)
  382 {
  383         int hash;
  384         struct cnode *cp;
  385         int count = 0;
  386 
  387         printf("coda_cacheprint: coda_ctlvp %p, cp %p", coda_ctlvp,
  388             VTOC(coda_ctlvp));
  389 
  390 #if 0
  391         coda_nc_name(VTOC(coda_ctlvp));
  392 #endif
  393         printf("\n");
  394         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  395                 for (cp = coda_cache[hash]; cp != NULL;
  396                     cp = CNODE_NEXT(cp)) {
  397                         if (CTOV(cp)->v_mount == whoIam) {
  398                                 printf("coda_cacheprint: vp %p, cp %p",
  399                                     CTOV(cp), cp);
  400 #if 0
  401                                 coda_nc_name(cp);
  402 #endif
  403                                 printf("\n");
  404                                 count++;
  405                         }
  406                 }
  407         }
  408         printf("coda_cacheprint: count %d\n", count);
  409 }
  410 #endif
  411 
  412 /*-
  413  * There are 6 cases where invalidations occur.  The semantics of each is
  414  * listed here:
  415  *
  416  * CODA_FLUSH     -- Flush all entries from the name cache and the cnode
  417  *                   cache.
  418  *
  419  * CODA_PURGEUSER -- Flush all entries from the name cache for a specific
  420  *                   user.   This call is a result of token expiration.
  421  *
  422  * The next two are the result of callbacks on a file or directory:
  423  *
  424  * CODA_ZAPDIR    -- Flush the attributes for the dir from its cnode.  Zap
  425  *                   all children of this directory from the namecache.
  426  *
  427  * CODA_ZAPFILE   -- Flush the attributes for a file.
  428  *
  429  * The fifth is a result of Venus detecting an inconsistent file:
  430  *
  431  * CODA_PURGEFID  -- Flush the attribute for the file; if it is a dir (odd
  432  *                   vnode), purge its children from the namecache; remove
  433  *                   the file from the namecache.
  434  *
  435  * The sixth allows Venus to replace local fids with global ones during
  436  * reintegration.
  437  *
  438  * CODA_REPLACE   -- Replace one CodaFid with another throughout the name
  439  *                   cache.
  440  */
  441 int
  442 handleDownCall(struct coda_mntinfo *mnt, int opcode, union outputArgs *out)
  443 {
  444         int error;
  445 
  446         /*
  447          * Handle invalidate requests.
  448          */
  449         switch (opcode) {
  450         case CODA_FLUSH: {
  451                 coda_flush(mnt, IS_DOWNCALL);
  452 
  453                 /* Print any remaining cnodes. */
  454                 CODADEBUG(CODA_FLUSH, coda_testflush(););
  455                 return (0);
  456         }
  457 
  458         case CODA_PURGEUSER: {
  459                 coda_clstat.ncalls++;
  460                 coda_clstat.reqs[CODA_PURGEUSER]++;
  461 
  462                 /* XXX - need to prevent fsync's. */
  463 
  464                 /*
  465                  * Purge any access cache entries for the uid.
  466                  */
  467 #ifdef CODA_COMPAT_5
  468                 coda_acccache_purgeuser(mnt->mi_vfsp,
  469                     out->coda_purgeuser.cred.cr_uid);
  470 #else
  471                 coda_acccache_purgeuser(mnt->mi_vfsp,
  472                     out->coda_purgeuser.uid);
  473 #endif
  474                 return (0);
  475         }
  476 
  477         case CODA_ZAPFILE: {
  478                 struct cnode *cp;
  479 
  480                 error = 0;
  481                 coda_clstat.ncalls++;
  482                 coda_clstat.reqs[CODA_ZAPFILE]++;
  483                 cp = coda_find(&out->coda_zapfile.Fid);
  484                 if (cp != NULL) {
  485                         vref(CTOV(cp));
  486                         cache_purge(CTOV(cp));
  487                         cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
  488                         ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
  489                         if (VOP_IS_TEXT(CTOV(cp)))
  490                                 error = coda_vmflush(cp);
  491                         CODADEBUG(CODA_ZAPFILE,
  492                         myprintf(("zapfile: fid = %s, refcnt = %d, error = "
  493                             "%d\n", coda_f2s(&cp->c_fid),
  494                             CTOV(cp)->v_usecount - 1, error)););
  495                         if (vrefcnt(CTOV(cp)) == 1)
  496                                 cp->c_flags |= C_PURGING;
  497                         vrele(CTOV(cp));
  498                 }
  499                 return (error);
  500       }
  501 
  502       case CODA_ZAPDIR: {
  503                 struct cnode *cp;
  504 
  505                 coda_clstat.ncalls++;
  506                 coda_clstat.reqs[CODA_ZAPDIR]++;
  507                 cp = coda_find(&out->coda_zapdir.Fid);
  508                 if (cp != NULL) {
  509                         vref(CTOV(cp));
  510                         cache_purge(CTOV(cp));
  511                         cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
  512                         CODADEBUG(CODA_ZAPDIR, myprintf(("zapdir: fid = %s, "
  513                             "refcnt = %d\n", coda_f2s(&cp->c_fid),
  514                             CTOV(cp)->v_usecount - 1)););
  515                         if (vrefcnt(CTOV(cp)) == 1)
  516                                 cp->c_flags |= C_PURGING;
  517                         vrele(CTOV(cp));
  518                 }
  519                 return (0);
  520       }
  521 
  522       case CODA_PURGEFID: {
  523                 struct cnode *cp;
  524 
  525                 error = 0;
  526                 coda_clstat.ncalls++;
  527                 coda_clstat.reqs[CODA_PURGEFID]++;
  528                 cp = coda_find(&out->coda_purgefid.Fid);
  529                 if (cp != NULL) {
  530                         vref(CTOV(cp));
  531                         cache_purge(CTOV(cp));
  532                         cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
  533                         ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
  534                         if (!(IS_DIR(out->coda_purgefid.Fid))
  535                             && VOP_IS_TEXT(CTOV(cp)))
  536                                 error = coda_vmflush(cp);
  537                         CODADEBUG(CODA_PURGEFID, myprintf(("purgefid: fid "
  538                             "= %s, refcnt = %d, error = %d\n",
  539                             coda_f2s(&cp->c_fid),
  540                             CTOV(cp)->v_usecount - 1, error)););
  541                         if (vrefcnt(CTOV(cp)) == 1)
  542                                 cp->c_flags |= C_PURGING;
  543                         vrele(CTOV(cp));
  544                 }
  545                 return (error);
  546         }
  547 
  548         case CODA_REPLACE: {
  549                 struct cnode *cp = NULL;
  550 
  551                 coda_clstat.ncalls++;
  552                 coda_clstat.reqs[CODA_REPLACE]++;
  553                 cp = coda_find(&out->coda_replace.OldFid);
  554                 if (cp != NULL) {
  555                         /*
  556                          * Remove the cnode from the hash table, replace the
  557                          * fid, and reinsert.  Clear the attribute cache as
  558                          * the "inode number" may have changed (it's just a
  559                          * hash of the fid, and the fid is changing).
  560                          */
  561                         vref(CTOV(cp));
  562                         coda_unsave(cp);
  563                         cp->c_fid = out->coda_replace.NewFid;
  564                         cp->c_flags &= ~C_VATTR;
  565                         coda_save(cp);
  566                         CODADEBUG(CODA_REPLACE, myprintf(("replace: oldfid "
  567                             "= %s, newfid = %s, cp = %p\n",
  568                             coda_f2s(&out->coda_replace.OldFid),
  569                             coda_f2s(&cp->c_fid), cp)););
  570                         vrele(CTOV(cp));
  571                 }
  572                 return (0);
  573         }
  574         default:
  575                 myprintf(("handleDownCall: unknown opcode %d\n", opcode));
  576                 return (EINVAL);
  577         }
  578 }
  579 
  580 int
  581 coda_vmflush(struct cnode *cp)
  582 {
  583 
  584         return (0);
  585 }
  586 
  587 /*
  588  * Kernel-internal debugging switches.
  589  */
  590 void
  591 coda_debugon(void)
  592 {
  593 
  594         codadebug = -1;
  595         coda_vnop_print_entry = 1;
  596         coda_psdev_print_entry = 1;
  597         coda_vfsop_print_entry = 1;
  598 }
  599 
  600 void
  601 coda_debugoff(void)
  602 {
  603 
  604         codadebug = 0;
  605         coda_vnop_print_entry = 0;
  606         coda_psdev_print_entry = 0;
  607         coda_vfsop_print_entry = 0;
  608 }
  609 
  610 /*-
  611  * Utilities used by both client and server
  612  * Standard levels:
  613  * 0) no debugging
  614  * 1) hard failures
  615  * 2) soft failures
  616  * 3) current test software
  617  * 4) main procedure entry points
  618  * 5) main procedure exit points
  619  * 6) utility procedure entry points
  620  * 7) utility procedure exit points
  621  * 8) obscure procedure entry points
  622  * 9) obscure procedure exit points
  623  * 10) random stuff
  624  * 11) all <= 1
  625  * 12) all <= 2
  626  * 13) all <= 3
  627  * ...
  628  */

Cache object: 214bd2c25d0b9245b87960614f5abc1b


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