]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfscommon/BTree/BTreeNodeReserve.c
xnu-792.10.96.tar.gz
[apple/xnu.git] / bsd / hfs / hfscommon / BTree / BTreeNodeReserve.c
index c619d78a704add19b68db738b3c61b40607da77e..00874f229b3d1b4ec1fd2eb78a90042cbe3f9aed 100644 (file)
@@ -1,29 +1,27 @@
 /*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
  * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 #include "../headers/BTreesPrivate.h"
 #include "sys/malloc.h"
+#include <kern/locks.h>
 
 
 /*
@@ -56,7 +54,7 @@ struct nreserve {
        void  *nr_tag;                 /* unique tag (per thread) */
 };
 
-#define NR_GET_TAG()   (current_act())
+#define NR_GET_TAG()   (current_thread())
 
 #define        NR_CACHE 17
 
@@ -67,6 +65,11 @@ LIST_HEAD(nodereserve, nreserve) *nr_hashtbl;
 
 u_long nr_hashmask;
 
+lck_grp_t * nr_lck_grp;
+lck_grp_attr_t * nr_lck_grp_attr;
+lck_attr_t * nr_lck_attr;
+
+lck_mtx_t  nr_mutex;
 
 /* Internal Node Reserve Hash Routines (private) */
 static void nr_insert (struct vnode *, struct nreserve *nrp, int);
@@ -86,6 +89,13 @@ BTReserveSetup()
                panic("BTReserveSetup: nreserve size != opaque struct size");
 
        nr_hashtbl = hashinit(NR_CACHE, M_HFSMNT, &nr_hashmask);
+
+       nr_lck_grp_attr= lck_grp_attr_alloc_init();
+       nr_lck_grp  = lck_grp_alloc_init("btree_node_reserve", nr_lck_grp_attr);
+
+       nr_lck_attr = lck_attr_alloc_init();
+
+       lck_mtx_init(&nr_mutex, nr_lck_grp, nr_lck_attr);
 }
 
 
@@ -145,7 +155,7 @@ BTReserveSpace(FCB *file, int operations, void* data)
                totalNodes = rsrvNodes + btree->totalNodes - availNodes;
                
                /* See if we also need a map node */
-               if (totalNodes > CalcMapBits(btree))
+               if (totalNodes > (int)CalcMapBits(btree))
                        ++totalNodes;
                if ((err = ExtendBTree(btree, totalNodes)))
                        return (err);
@@ -182,7 +192,7 @@ BTReleaseReserve(FCB *file, void* data)
 }
 
 /*
- * BTUpdateReserve - update a node reserve for allocations that occured.
+ * BTUpdateReserve - update a node reserve for allocations that occurred.
  */
 __private_extern__
 void
@@ -212,11 +222,13 @@ nr_insert(struct vnode * btvp, struct nreserve *nrp, int nodecnt)
        /*
         * Check the cache - there may already be a reserve
         */
+       lck_mtx_lock(&nr_mutex);
        nrhead = NR_HASH(btvp, tag);
        for (tmp_nrp = nrhead->lh_first; tmp_nrp;
             tmp_nrp = tmp_nrp->nr_hash.le_next) {
                if ((tmp_nrp->nr_tag == tag) && (tmp_nrp->nr_btvp == btvp)) {
                        nrp->nr_tag = 0;
+                       lck_mtx_unlock(&nr_mutex);
                        return;
                }
        }
@@ -227,6 +239,7 @@ nr_insert(struct vnode * btvp, struct nreserve *nrp, int nodecnt)
        nrp->nr_tag = tag;
        LIST_INSERT_HEAD(nrhead, nrp, nr_hash);
        ++nrinserts;
+       lck_mtx_unlock(&nr_mutex);
 }
 
 /*
@@ -237,6 +250,7 @@ nr_delete(struct vnode * btvp, struct nreserve *nrp, int *nodecnt)
 {
        void * tag = NR_GET_TAG();
 
+       lck_mtx_lock(&nr_mutex);
        if (nrp->nr_tag) {
                if ((nrp->nr_tag != tag) || (nrp->nr_btvp != btvp))
                        panic("nr_delete: invalid NR (%08x)", nrp);
@@ -247,6 +261,7 @@ nr_delete(struct vnode * btvp, struct nreserve *nrp, int *nodecnt)
        } else {
                *nodecnt = 0;
        }
+       lck_mtx_unlock(&nr_mutex);
 }
 
 /*
@@ -259,16 +274,21 @@ nr_lookup(struct vnode * btvp)
        struct nreserve *nrp;
        void* tag = NR_GET_TAG();
 
+       lck_mtx_lock(&nr_mutex);
+
        nrhead = NR_HASH(btvp, tag);
        for (nrp = nrhead->lh_first; nrp; nrp = nrp->nr_hash.le_next) {
-               if ((nrp->nr_tag == tag) && (nrp->nr_btvp == btvp))
+               if ((nrp->nr_tag == tag) && (nrp->nr_btvp == btvp)) {
+                       lck_mtx_unlock(&nr_mutex);
                        return (nrp->nr_nodecnt - nrp->nr_newnodes);
+               }
        }
+       lck_mtx_unlock(&nr_mutex);
        return (0);
 }
 
 /*
- * Update a node reserve for any allocations that occured.
+ * Update a node reserve for any allocations that occurred.
  */
 static void
 nr_update(struct vnode * btvp, int nodecnt)
@@ -277,6 +297,8 @@ nr_update(struct vnode * btvp, int nodecnt)
        struct nreserve *nrp;
        void* tag = NR_GET_TAG();
 
+       lck_mtx_lock(&nr_mutex);
+
        nrhead = NR_HASH(btvp, tag);
        for (nrp = nrhead->lh_first; nrp; nrp = nrp->nr_hash.le_next) {
                if ((nrp->nr_tag == tag) && (nrp->nr_btvp == btvp)) {                   
@@ -284,4 +306,5 @@ nr_update(struct vnode * btvp, int nodecnt)
                        break;
                }
        }
+       lck_mtx_unlock(&nr_mutex);
 }