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: releng/9.0/sys/fs/coda/coda_subr.c 206210 2010-04-05 20:12:54Z rwatson $");
   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_ILOCK(mp);
  369         MNT_VNODE_FOREACH(vp, mp, nvp) {
  370                 VI_LOCK(vp);
  371                 if (vp->v_iflag & VI_DOOMED) {
  372                         VI_UNLOCK(vp);
  373                         continue;
  374                 }
  375                 cp = VTOC(vp);
  376                 count++;
  377                 if (!(cp->c_flags & C_UNMOUNTING)) {
  378                         bad++;
  379                         printf("vp %p, cp %p missed\n", vp, cp);
  380                         cp->c_flags |= C_UNMOUNTING;
  381                 }
  382                 VI_UNLOCK(vp);
  383         }
  384         MNT_IUNLOCK(mp);
  385 }
  386 
  387 void
  388 coda_cacheprint(struct mount *whoIam)
  389 {
  390         int hash;
  391         struct cnode *cp;
  392         int count = 0;
  393 
  394         printf("coda_cacheprint: coda_ctlvp %p, cp %p", coda_ctlvp,
  395             VTOC(coda_ctlvp));
  396 
  397 #if 0
  398         coda_nc_name(VTOC(coda_ctlvp));
  399 #endif
  400         printf("\n");
  401         for (hash = 0; hash < CODA_CACHESIZE; hash++) {
  402                 for (cp = coda_cache[hash]; cp != NULL;
  403                     cp = CNODE_NEXT(cp)) {
  404                         if (CTOV(cp)->v_mount == whoIam) {
  405                                 printf("coda_cacheprint: vp %p, cp %p",
  406                                     CTOV(cp), cp);
  407 #if 0
  408                                 coda_nc_name(cp);
  409 #endif
  410                                 printf("\n");
  411                                 count++;
  412                         }
  413                 }
  414         }
  415         printf("coda_cacheprint: count %d\n", count);
  416 }
  417 #endif
  418 
  419 /*-
  420  * There are 6 cases where invalidations occur.  The semantics of each is
  421  * listed here:
  422  *
  423  * CODA_FLUSH     -- Flush all entries from the name cache and the cnode
  424  *                   cache.
  425  *
  426  * CODA_PURGEUSER -- Flush all entries from the name cache for a specific
  427  *                   user.   This call is a result of token expiration.
  428  *
  429  * The next two are the result of callbacks on a file or directory:
  430  *
  431  * CODA_ZAPDIR    -- Flush the attributes for the dir from its cnode.  Zap
  432  *                   all children of this directory from the namecache.
  433  *
  434  * CODA_ZAPFILE   -- Flush the attributes for a file.
  435  *
  436  * The fifth is a result of Venus detecting an inconsistent file:
  437  *
  438  * CODA_PURGEFID  -- Flush the attribute for the file; if it is a dir (odd
  439  *                   vnode), purge its children from the namecache; remove
  440  *                   the file from the namecache.
  441  *
  442  * The sixth allows Venus to replace local fids with global ones during
  443  * reintegration.
  444  *
  445  * CODA_REPLACE   -- Replace one CodaFid with another throughout the name
  446  *                   cache.
  447  */
  448 int
  449 handleDownCall(struct coda_mntinfo *mnt, int opcode, union outputArgs *out)
  450 {
  451         int error;
  452 
  453         /*
  454          * Handle invalidate requests.
  455          */
  456         switch (opcode) {
  457         case CODA_FLUSH: {
  458                 coda_flush(mnt, IS_DOWNCALL);
  459 
  460                 /* Print any remaining cnodes. */
  461                 CODADEBUG(CODA_FLUSH, coda_testflush(););
  462                 return (0);
  463         }
  464 
  465         case CODA_PURGEUSER: {
  466                 coda_clstat.ncalls++;
  467                 coda_clstat.reqs[CODA_PURGEUSER]++;
  468 
  469                 /* XXX - need to prevent fsync's. */
  470 
  471                 /*
  472                  * Purge any access cache entries for the uid.
  473                  */
  474 #ifdef CODA_COMPAT_5
  475                 coda_acccache_purgeuser(mnt->mi_vfsp,
  476                     out->coda_purgeuser.cred.cr_uid);
  477 #else
  478                 coda_acccache_purgeuser(mnt->mi_vfsp,
  479                     out->coda_purgeuser.uid);
  480 #endif
  481                 return (0);
  482         }
  483 
  484         case CODA_ZAPFILE: {
  485                 struct cnode *cp;
  486 
  487                 error = 0;
  488                 coda_clstat.ncalls++;
  489                 coda_clstat.reqs[CODA_ZAPFILE]++;
  490                 cp = coda_find(&out->coda_zapfile.Fid);
  491                 if (cp != NULL) {
  492                         vref(CTOV(cp));
  493                         cache_purge(CTOV(cp));
  494                         cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
  495                         ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
  496                         if (CTOV(cp)->v_vflag & VV_TEXT)
  497                                 error = coda_vmflush(cp);
  498                         CODADEBUG(CODA_ZAPFILE,
  499                         myprintf(("zapfile: fid = %s, refcnt = %d, error = "
  500                             "%d\n", coda_f2s(&cp->c_fid),
  501                             CTOV(cp)->v_usecount - 1, error)););
  502                         if (vrefcnt(CTOV(cp)) == 1)
  503                                 cp->c_flags |= C_PURGING;
  504                         vrele(CTOV(cp));
  505                 }
  506                 return (error);
  507       }
  508 
  509       case CODA_ZAPDIR: {
  510                 struct cnode *cp;
  511 
  512                 coda_clstat.ncalls++;
  513                 coda_clstat.reqs[CODA_ZAPDIR]++;
  514                 cp = coda_find(&out->coda_zapdir.Fid);
  515                 if (cp != NULL) {
  516                         vref(CTOV(cp));
  517                         cache_purge(CTOV(cp));
  518                         cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
  519                         CODADEBUG(CODA_ZAPDIR, myprintf(("zapdir: fid = %s, "
  520                             "refcnt = %d\n", coda_f2s(&cp->c_fid),
  521                             CTOV(cp)->v_usecount - 1)););
  522                         if (vrefcnt(CTOV(cp)) == 1)
  523                                 cp->c_flags |= C_PURGING;
  524                         vrele(CTOV(cp));
  525                 }
  526                 return (0);
  527       }
  528 
  529       case CODA_PURGEFID: {
  530                 struct cnode *cp;
  531 
  532                 error = 0;
  533                 coda_clstat.ncalls++;
  534                 coda_clstat.reqs[CODA_PURGEFID]++;
  535                 cp = coda_find(&out->coda_purgefid.Fid);
  536                 if (cp != NULL) {
  537                         vref(CTOV(cp));
  538                         cache_purge(CTOV(cp));
  539                         cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
  540                         ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
  541                         if (!(IS_DIR(out->coda_purgefid.Fid))
  542                             && (CTOV(cp)->v_vflag & VV_TEXT))
  543                                 error = coda_vmflush(cp);
  544                         CODADEBUG(CODA_PURGEFID, myprintf(("purgefid: fid "
  545                             "= %s, refcnt = %d, error = %d\n",
  546                             coda_f2s(&cp->c_fid),
  547                             CTOV(cp)->v_usecount - 1, error)););
  548                         if (vrefcnt(CTOV(cp)) == 1)
  549                                 cp->c_flags |= C_PURGING;
  550                         vrele(CTOV(cp));
  551                 }
  552                 return (error);
  553         }
  554 
  555         case CODA_REPLACE: {
  556                 struct cnode *cp = NULL;
  557 
  558                 coda_clstat.ncalls++;
  559                 coda_clstat.reqs[CODA_REPLACE]++;
  560                 cp = coda_find(&out->coda_replace.OldFid);
  561                 if (cp != NULL) {
  562                         /*
  563                          * Remove the cnode from the hash table, replace the
  564                          * fid, and reinsert.  Clear the attribute cache as
  565                          * the "inode number" may have changed (it's just a
  566                          * hash of the fid, and the fid is changing).
  567                          */
  568                         vref(CTOV(cp));
  569                         coda_unsave(cp);
  570                         cp->c_fid = out->coda_replace.NewFid;
  571                         cp->c_flags &= ~C_VATTR;
  572                         coda_save(cp);
  573                         CODADEBUG(CODA_REPLACE, myprintf(("replace: oldfid "
  574                             "= %s, newfid = %s, cp = %p\n",
  575                             coda_f2s(&out->coda_replace.OldFid),
  576                             coda_f2s(&cp->c_fid), cp)););
  577                         vrele(CTOV(cp));
  578                 }
  579                 return (0);
  580         }
  581         default:
  582                 myprintf(("handleDownCall: unknown opcode %d\n", opcode));
  583                 return (EINVAL);
  584         }
  585 }
  586 
  587 int
  588 coda_vmflush(struct cnode *cp)
  589 {
  590 
  591         return (0);
  592 }
  593 
  594 /*
  595  * Kernel-internal debugging switches.
  596  */
  597 void
  598 coda_debugon(void)
  599 {
  600 
  601         codadebug = -1;
  602         coda_vnop_print_entry = 1;
  603         coda_psdev_print_entry = 1;
  604         coda_vfsop_print_entry = 1;
  605 }
  606 
  607 void
  608 coda_debugoff(void)
  609 {
  610 
  611         codadebug = 0;
  612         coda_vnop_print_entry = 0;
  613         coda_psdev_print_entry = 0;
  614         coda_vfsop_print_entry = 0;
  615 }
  616 
  617 /*-
  618  * Utilities used by both client and server
  619  * Standard levels:
  620  * 0) no debugging
  621  * 1) hard failures
  622  * 2) soft failures
  623  * 3) current test software
  624  * 4) main procedure entry points
  625  * 5) main procedure exit points
  626  * 6) utility procedure entry points
  627  * 7) utility procedure exit points
  628  * 8) obscure procedure entry points
  629  * 9) obscure procedure exit points
  630  * 10) random stuff
  631  * 11) all <= 1
  632  * 12) all <= 2
  633  * 13) all <= 3
  634  * ...
  635  */

Cache object: 05f1169fd750f2dc1742f532acd441f5


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