1/*	$NetBSD: chfs_vnode_cache.c,v 1.2 2012/08/10 09:26:58 ttoth Exp $	*/
2
3/*-
4 * Copyright (c) 2010 Department of Software Engineering,
5 *		      University of Szeged, Hungary
6 * Copyright (C) 2010 Tamas Toth <ttoth@inf.u-szeged.hu>
7 * Copyright (C) 2010 Adam Hoka <ahoka@NetBSD.org>
8 * All rights reserved.
9 *
10 * This code is derived from software contributed to The NetBSD Foundation
11 * by the Department of Software Engineering, University of Szeged, Hungary
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include "chfs.h"
36#include <sys/pool.h>
37
38/* vnode cache is a hashtable for vnodes */
39
40/* chfs_vnocache_hash_init - initializing the hashtable */
41struct chfs_vnode_cache **
42chfs_vnocache_hash_init(void)
43{
44	return kmem_zalloc(VNODECACHE_SIZE *
45	    sizeof(struct chfs_vnode_cache *), KM_SLEEP);
46}
47
48/*
49 * chfs_vnode_cache_get - get a vnode_cache from the hashtable
50 * Returns the vnode_cache.
51 */
52struct chfs_vnode_cache *
53chfs_vnode_cache_get(struct chfs_mount *chmp, ino_t vno)
54{
55	struct chfs_vnode_cache* ret;
56
57	KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
58
59	ret = chmp->chm_vnocache_hash[vno % VNODECACHE_SIZE];
60
61	if (ret == NULL) {
62		return NULL;
63	}
64
65	while (ret && ret->vno < vno) {
66		ret = ret->next;
67	}
68
69	if (ret && ret->vno != vno) {
70		ret = NULL;
71	}
72
73	return ret;
74}
75
76/* chfs_vnode_cache_add - add a vnode_cache to the hashtable */
77void
78chfs_vnode_cache_add(struct chfs_mount *chmp,
79    struct chfs_vnode_cache* new)
80{
81	struct chfs_vnode_cache** prev;
82
83	KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
84
85	if (!new->vno) {
86		new->vno = ++chmp->chm_max_vno;
87	}
88
89	prev = &chmp->chm_vnocache_hash[new->vno % VNODECACHE_SIZE];
90
91	while ((*prev) && (*prev)->vno < new->vno) {
92		prev = &((*prev)->next);
93	}
94	new->next = *prev;
95	*prev = new;
96}
97
98/* chfs_vnode_cache_remove - removes a vnode_cache from the hashtable */
99void
100chfs_vnode_cache_remove(struct chfs_mount *chmp,
101    struct chfs_vnode_cache* old)
102{
103	struct chfs_vnode_cache** prev;
104
105	KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
106
107	prev = &chmp->chm_vnocache_hash[old->vno % VNODECACHE_SIZE];
108	while ((*prev) && (*prev)->vno < old->vno) {
109		prev = &(*prev)->next;
110	}
111
112	if ((*prev) == old) {
113		*prev = old->next;
114	}
115
116	if (old->state != VNO_STATE_READING &&
117	    old->state != VNO_STATE_CLEARING) {
118		chfs_vnode_cache_free(old);
119	}
120}
121
122/* chfs_vnocache_hash_destroy - destroying the vnode cache */
123void
124chfs_vnocache_hash_destroy(struct chfs_vnode_cache **hash)
125{
126	struct chfs_vnode_cache *this, *next;
127	int i;
128
129	/* free every row */
130	for (i = 0; i < VNODECACHE_SIZE; i++) {
131		this = hash[i];
132		while (this) {
133			next = this->next;
134			chfs_vnode_cache_free(this);
135			this = next;
136		}
137		hash[i] = NULL;
138	}
139}
140
141