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/bsd/hfs/hfs_chash.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  * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 
   26 /*
   27  * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
   28  *      The Regents of the University of California.  All rights reserved.
   29  *
   30  * Redistribution and use in source and binary forms, with or without
   31  * modification, are permitted provided that the following conditions
   32  * are met:
   33  * 1. Redistributions of source code must retain the above copyright
   34  *        notice, this list of conditions and the following disclaimer.
   35  * 2. Redistributions in binary form must reproduce the above copyright
   36  *        notice, this list of conditions and the following disclaimer in the
   37  *        documentation and/or other materials provided with the distribution.
   38  * 3. All advertising materials mentioning features or use of this software
   39  *        must display the following acknowledgement:
   40  *      This product includes software developed by the University of
   41  *      California, Berkeley and its contributors.
   42  * 4. Neither the name of the University nor the names of its contributors
   43  *        may be used to endorse or promote products derived from this software
   44  *        without specific prior written permission.
   45  *
   46  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   49  * ARE DISCLAIMED.      IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   50  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   51  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   52  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   54  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   56  * SUCH DAMAGE.
   57  *
   58  *      @(#)hfs_chash.c
   59  *      derived from @(#)ufs_ihash.c    8.7 (Berkeley) 5/17/95
   60  */
   61 
   62 #include <sys/param.h>
   63 #include <sys/systm.h>
   64 #include <sys/vnode.h>
   65 #include <sys/malloc.h>
   66 #include <sys/proc.h>
   67 #include <sys/queue.h>
   68 
   69 #include "hfs_cnode.h"
   70 
   71 
   72 /*
   73  * Structures associated with cnode caching.
   74  */
   75 LIST_HEAD(cnodehashhead, cnode) *cnodehashtbl;
   76 u_long  cnodehash;              /* size of hash table - 1 */
   77 #define CNODEHASH(device, inum) (&cnodehashtbl[((device) + (inum)) & cnodehash])
   78 struct slock hfs_chash_slock;
   79 
   80 /*
   81  * Initialize cnode hash table.
   82  */
   83 __private_extern__
   84 void
   85 hfs_chashinit()
   86 {
   87         cnodehashtbl = hashinit(desiredvnodes, M_HFSMNT, &cnodehash);
   88         simple_lock_init(&hfs_chash_slock);
   89 }
   90 
   91 
   92 /*
   93  * Use the device, inum pair to find the incore cnode.
   94  *
   95  * If it is in core, but locked, wait for it.
   96  *
   97  * If the requested vnode (fork) is not available, then
   98  * take a reference on the other vnode (fork) so that
   99  * the upcoming getnewvnode can not aquire it.
  100  */
  101 __private_extern__
  102 struct cnode *
  103 hfs_chashget(dev_t dev, ino_t inum, int wantrsrc,
  104                 struct vnode **vpp, struct vnode **rvpp)
  105 {
  106         struct proc *p = current_proc();
  107         struct cnode *cp;
  108         struct vnode *vp;
  109         int error;
  110 
  111         *vpp = NULLVP;
  112         *rvpp = NULLVP;
  113         /* 
  114          * Go through the hash list
  115          * If a cnode is in the process of being cleaned out or being
  116          * allocated, wait for it to be finished and then try again.
  117          */
  118 loop:
  119         simple_lock(&hfs_chash_slock);
  120         for (cp = CNODEHASH(dev, inum)->lh_first; cp; cp = cp->c_hash.le_next) {
  121                 if ((cp->c_fileid != inum) || (cp->c_dev != dev))
  122                         continue;
  123                 if (ISSET(cp->c_flag, C_ALLOC)) {
  124                         /*
  125                          * cnode is being created. Wait for it to finish.
  126                          */
  127                         SET(cp->c_flag, C_WALLOC);
  128                         simple_unlock(&hfs_chash_slock);
  129                         (void) tsleep((caddr_t)cp, PINOD, "hfs_chashget-1", 0);
  130                         goto loop;
  131                 }       
  132                 if (ISSET(cp->c_flag, C_TRANSIT)) {
  133                         /*
  134                          * cnode is getting reclaimed wait for
  135                          * the operation to complete and return
  136                          * error
  137                          */
  138                         SET(cp->c_flag, C_WTRANSIT);
  139                         simple_unlock(&hfs_chash_slock);
  140                         (void)tsleep((caddr_t)cp, PINOD, "hfs_chashget-2", 0);
  141                         goto loop;
  142                 }
  143                 if (cp->c_flag & (C_NOEXISTS | C_DELETED))
  144                         continue;
  145 
  146                 /*
  147                  * Try getting the desired vnode first.  If
  148                  * it isn't available then take a reference
  149                  * on the other vnode.
  150                  */
  151                 vp = wantrsrc ? cp->c_rsrc_vp : cp->c_vp;
  152                 if (vp == NULLVP)
  153                         vp = wantrsrc ? cp->c_vp : cp->c_rsrc_vp;
  154                 if (vp == NULLVP)
  155                         panic("hfs_chashget: orphaned cnode in hash");
  156 
  157                 simple_lock(&vp->v_interlock);
  158                 simple_unlock(&hfs_chash_slock);
  159                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
  160                         goto loop;
  161                 else if (cp->c_flag & C_NOEXISTS) {
  162                         /*
  163                          * While we were blocked the cnode got deleted.
  164                          */
  165                         vput(vp);
  166                         goto loop;
  167                 }
  168 
  169                 if (VNODE_IS_RSRC(vp))
  170                         *rvpp = vp;
  171                 else
  172                         *vpp = vp;
  173                 /*
  174                  * Note that vget can block before aquiring the
  175                  * cnode lock.  So we need to check if the vnode
  176                  * we wanted was created while we blocked.
  177                  */
  178                 if (wantrsrc && *rvpp == NULL && cp->c_rsrc_vp) {
  179                         error = vget(cp->c_rsrc_vp, 0, p);
  180                         vrele(*vpp);    /* ref no longer needed */
  181                         *vpp = NULL;
  182                         if (error)
  183                                 goto loop;
  184                         *rvpp = cp->c_rsrc_vp;
  185 
  186                 } else if (!wantrsrc && *vpp == NULL && cp->c_vp) {
  187                         error = vget(cp->c_vp, 0, p);
  188                         vrele(*rvpp);   /* ref no longer needed */
  189                         *rvpp = NULL;
  190                         if (error)
  191                                 goto loop;
  192                         *vpp = cp->c_vp;
  193                 }
  194                 return (cp);
  195         }
  196         simple_unlock(&hfs_chash_slock);
  197         return (NULL);
  198 }
  199 
  200 
  201 /*
  202  * Insert a cnode into the hash table.
  203  */
  204 __private_extern__
  205 void
  206 hfs_chashinsert(struct cnode *cp)
  207 {
  208         if (cp->c_fileid != 0) {
  209                 simple_lock(&hfs_chash_slock);
  210                 LIST_INSERT_HEAD(CNODEHASH(cp->c_dev, cp->c_fileid), cp, c_hash);
  211                 simple_unlock(&hfs_chash_slock);
  212         }
  213 }
  214 
  215 
  216 /*
  217  * Remove a cnode from the hash table.
  218  */
  219 __private_extern__
  220 void
  221 hfs_chashremove(struct cnode *cp)
  222 {
  223         simple_lock(&hfs_chash_slock);
  224         LIST_REMOVE(cp, c_hash);
  225         cp->c_hash.le_next = NULL;
  226         cp->c_hash.le_prev = NULL;
  227         simple_unlock(&hfs_chash_slock);
  228 }
  229 

Cache object: 809b87f0c005c42db7cae9fb83a07764


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