1*14c96698Smaxv /* $NetBSD: ntfs_ihash.c,v 1.11 2015/02/20 17:08:13 maxv Exp $ */
29accf4dfSjdolecek
39accf4dfSjdolecek /*
49accf4dfSjdolecek * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
59accf4dfSjdolecek * The Regents of the University of California. All rights reserved.
69accf4dfSjdolecek *
79accf4dfSjdolecek * Redistribution and use in source and binary forms, with or without
89accf4dfSjdolecek * modification, are permitted provided that the following conditions
99accf4dfSjdolecek * are met:
109accf4dfSjdolecek * 1. Redistributions of source code must retain the above copyright
119accf4dfSjdolecek * notice, this list of conditions and the following disclaimer.
129accf4dfSjdolecek * 2. Redistributions in binary form must reproduce the above copyright
139accf4dfSjdolecek * notice, this list of conditions and the following disclaimer in the
149accf4dfSjdolecek * documentation and/or other materials provided with the distribution.
15aad01611Sagc * 3. Neither the name of the University nor the names of its contributors
169accf4dfSjdolecek * may be used to endorse or promote products derived from this software
179accf4dfSjdolecek * without specific prior written permission.
189accf4dfSjdolecek *
199accf4dfSjdolecek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
209accf4dfSjdolecek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
219accf4dfSjdolecek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
229accf4dfSjdolecek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
239accf4dfSjdolecek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
249accf4dfSjdolecek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
259accf4dfSjdolecek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
269accf4dfSjdolecek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
279accf4dfSjdolecek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
289accf4dfSjdolecek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
299accf4dfSjdolecek * SUCH DAMAGE.
309accf4dfSjdolecek *
319accf4dfSjdolecek * @(#)ufs_ihash.c 8.7 (Berkeley) 5/17/95
329accf4dfSjdolecek * Id: ntfs_ihash.c,v 1.5 1999/05/12 09:42:58 semenu Exp
339accf4dfSjdolecek */
349accf4dfSjdolecek
359accf4dfSjdolecek #include <sys/cdefs.h>
36*14c96698Smaxv __KERNEL_RCSID(0, "$NetBSD: ntfs_ihash.c,v 1.11 2015/02/20 17:08:13 maxv Exp $");
379accf4dfSjdolecek
389accf4dfSjdolecek #include <sys/param.h>
399accf4dfSjdolecek #include <sys/systm.h>
409accf4dfSjdolecek #include <sys/kernel.h>
419accf4dfSjdolecek #include <sys/lock.h>
429accf4dfSjdolecek #include <sys/vnode.h>
439accf4dfSjdolecek #include <sys/mount.h>
44e62ee4d4Spara #include <sys/mallocvar.h>
459accf4dfSjdolecek
469accf4dfSjdolecek #include <fs/ntfs/ntfs.h>
479accf4dfSjdolecek #include <fs/ntfs/ntfs_inode.h>
489accf4dfSjdolecek #include <fs/ntfs/ntfs_ihash.h>
499accf4dfSjdolecek
509accf4dfSjdolecek /*
519accf4dfSjdolecek * Structures associated with inode cacheing.
529accf4dfSjdolecek */
539accf4dfSjdolecek static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl;
549accf4dfSjdolecek static u_long ntfs_nthash; /* size of hash table - 1 */
559accf4dfSjdolecek #define NTNOHASH(device, inum) ((minor(device) + (inum)) & ntfs_nthash)
569abeea58Sad static kmutex_t ntfs_nthash_lock;
579abeea58Sad kmutex_t ntfs_hashlock;
589accf4dfSjdolecek
599accf4dfSjdolecek /*
609accf4dfSjdolecek * Initialize inode hash table.
619accf4dfSjdolecek */
629accf4dfSjdolecek void
ntfs_nthashinit(void)63b8817e4aScegger ntfs_nthashinit(void)
649accf4dfSjdolecek {
659abeea58Sad mutex_init(&ntfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
669abeea58Sad mutex_init(&ntfs_nthash_lock, MUTEX_DEFAULT, IPL_NONE);
67e071d39cSad ntfs_nthashtbl = hashinit(desiredvnodes, HASH_LIST, true, &ntfs_nthash);
689accf4dfSjdolecek }
699accf4dfSjdolecek
709accf4dfSjdolecek /*
719accf4dfSjdolecek * Reinitialize inode hash table.
729accf4dfSjdolecek */
739accf4dfSjdolecek
749accf4dfSjdolecek void
ntfs_nthashreinit(void)75b8817e4aScegger ntfs_nthashreinit(void)
769accf4dfSjdolecek {
779accf4dfSjdolecek struct ntnode *ip;
789accf4dfSjdolecek struct nthashhead *oldhash, *hash;
799accf4dfSjdolecek u_long oldmask, mask, val;
809accf4dfSjdolecek int i;
819accf4dfSjdolecek
82e071d39cSad hash = hashinit(desiredvnodes, HASH_LIST, true, &mask);
839accf4dfSjdolecek
849abeea58Sad mutex_enter(&ntfs_nthash_lock);
859accf4dfSjdolecek oldhash = ntfs_nthashtbl;
869accf4dfSjdolecek oldmask = ntfs_nthash;
879accf4dfSjdolecek ntfs_nthashtbl = hash;
889accf4dfSjdolecek ntfs_nthash = mask;
899accf4dfSjdolecek for (i = 0; i <= oldmask; i++) {
909accf4dfSjdolecek while ((ip = LIST_FIRST(&oldhash[i])) != NULL) {
919accf4dfSjdolecek LIST_REMOVE(ip, i_hash);
929accf4dfSjdolecek val = NTNOHASH(ip->i_dev, ip->i_number);
939accf4dfSjdolecek LIST_INSERT_HEAD(&hash[val], ip, i_hash);
949accf4dfSjdolecek }
959accf4dfSjdolecek }
969abeea58Sad mutex_exit(&ntfs_nthash_lock);
97e071d39cSad hashdone(oldhash, HASH_LIST, oldmask);
989accf4dfSjdolecek }
999accf4dfSjdolecek
1009accf4dfSjdolecek /*
1019accf4dfSjdolecek * Free the inode hash table. Called from ntfs_done(), only needed
1029accf4dfSjdolecek * on NetBSD.
1039accf4dfSjdolecek */
1049accf4dfSjdolecek void
ntfs_nthashdone(void)105b8817e4aScegger ntfs_nthashdone(void)
1069accf4dfSjdolecek {
107e071d39cSad hashdone(ntfs_nthashtbl, HASH_LIST, ntfs_nthash);
108b89010bfSad mutex_destroy(&ntfs_hashlock);
109b89010bfSad mutex_destroy(&ntfs_nthash_lock);
1109accf4dfSjdolecek }
1119accf4dfSjdolecek
1129accf4dfSjdolecek /*
1139accf4dfSjdolecek * Use the device/inum pair to find the incore inode, and return a pointer
1149accf4dfSjdolecek * to it. If it is in core, return it, even if it is locked.
1159accf4dfSjdolecek */
1169accf4dfSjdolecek struct ntnode *
ntfs_nthashlookup(dev_t dev,ino_t inum)117454af1c0Sdsl ntfs_nthashlookup(dev_t dev, ino_t inum)
1189accf4dfSjdolecek {
1199accf4dfSjdolecek struct ntnode *ip;
1209accf4dfSjdolecek struct nthashhead *ipp;
1219accf4dfSjdolecek
1229abeea58Sad mutex_enter(&ntfs_nthash_lock);
1239accf4dfSjdolecek ipp = &ntfs_nthashtbl[NTNOHASH(dev, inum)];
1249accf4dfSjdolecek LIST_FOREACH(ip, ipp, i_hash) {
1259accf4dfSjdolecek if (inum == ip->i_number && dev == ip->i_dev)
1269accf4dfSjdolecek break;
1279accf4dfSjdolecek }
1289abeea58Sad mutex_exit(&ntfs_nthash_lock);
1299accf4dfSjdolecek
1309accf4dfSjdolecek return (ip);
1319accf4dfSjdolecek }
1329accf4dfSjdolecek
1339accf4dfSjdolecek /*
1349accf4dfSjdolecek * Insert the ntnode into the hash table.
1359accf4dfSjdolecek */
1369accf4dfSjdolecek void
ntfs_nthashins(struct ntnode * ip)137454af1c0Sdsl ntfs_nthashins(struct ntnode *ip)
1389accf4dfSjdolecek {
1399accf4dfSjdolecek struct nthashhead *ipp;
1409accf4dfSjdolecek
1419abeea58Sad mutex_enter(&ntfs_nthash_lock);
1429accf4dfSjdolecek ipp = &ntfs_nthashtbl[NTNOHASH(ip->i_dev, ip->i_number)];
1439accf4dfSjdolecek LIST_INSERT_HEAD(ipp, ip, i_hash);
1449accf4dfSjdolecek ip->i_flag |= IN_HASHED;
1459abeea58Sad mutex_exit(&ntfs_nthash_lock);
1469accf4dfSjdolecek }
1479accf4dfSjdolecek
1489accf4dfSjdolecek /*
1499accf4dfSjdolecek * Remove the inode from the hash table.
1509accf4dfSjdolecek */
1519accf4dfSjdolecek void
ntfs_nthashrem(struct ntnode * ip)152454af1c0Sdsl ntfs_nthashrem(struct ntnode *ip)
1539accf4dfSjdolecek {
1549abeea58Sad mutex_enter(&ntfs_nthash_lock);
1559accf4dfSjdolecek if (ip->i_flag & IN_HASHED) {
1569accf4dfSjdolecek ip->i_flag &= ~IN_HASHED;
1579accf4dfSjdolecek LIST_REMOVE(ip, i_hash);
1589accf4dfSjdolecek }
1599abeea58Sad mutex_exit(&ntfs_nthash_lock);
1609accf4dfSjdolecek }
161