xref: /haiku/src/add-ons/kernel/file_systems/websearchfs/vnidpool.c (revision 96e28a400a120f6f1289929c8c92f68bb2dbaf93)
1*96e28a40SPulkoMandy /*
2*96e28a40SPulkoMandy  * Copyright 2004-2008, François Revol, <revol@free.fr>.
3*96e28a40SPulkoMandy  * Distributed under the terms of the MIT License.
4*96e28a40SPulkoMandy  */
5*96e28a40SPulkoMandy 
6*96e28a40SPulkoMandy #include <malloc.h>
7*96e28a40SPulkoMandy #include <string.h>
8*96e28a40SPulkoMandy #include <KernelExport.h>
9*96e28a40SPulkoMandy #include "vnidpool.h"
10*96e28a40SPulkoMandy 
11*96e28a40SPulkoMandy #include <stdio.h>
12*96e28a40SPulkoMandy 
13*96e28a40SPulkoMandy /* primary type for the bitmap */
14*96e28a40SPulkoMandy #define BMT uint32
15*96e28a40SPulkoMandy 
16*96e28a40SPulkoMandy #define BM_BYTE(p, vnid) (p->bitmap[(vnid % p->bmsize) / sizeof(BMT)])
17*96e28a40SPulkoMandy #define BM_ISSET(p, vnid) (BM_BYTE(p, vnid) & (1 << (p->nextvnid % sizeof(BMT))))
18*96e28a40SPulkoMandy #define BM_SET(p, vnid) (BM_BYTE(p, vnid) |= (1 << (p->nextvnid % sizeof(BMT))))
19*96e28a40SPulkoMandy #define BM_UNSET(p, vnid) (BM_BYTE(p, vnid) &= ~(1 << (p->nextvnid % sizeof(BMT))))
20*96e28a40SPulkoMandy 
vnidpool_alloc(struct vnidpool ** pool,size_t size)21*96e28a40SPulkoMandy status_t vnidpool_alloc(struct vnidpool **pool, size_t size)
22*96e28a40SPulkoMandy {
23*96e28a40SPulkoMandy 	struct vnidpool *p;
24*96e28a40SPulkoMandy 	if (size < 2)
25*96e28a40SPulkoMandy 		return EINVAL;
26*96e28a40SPulkoMandy 	if (!pool)
27*96e28a40SPulkoMandy 		return EINVAL;
28*96e28a40SPulkoMandy 	size = (size + sizeof(BMT) - 1) / sizeof(BMT);
29*96e28a40SPulkoMandy 	size *= sizeof(BMT);
30*96e28a40SPulkoMandy 	p = malloc(sizeof(struct vnidpool) + size / sizeof(BMT));
31*96e28a40SPulkoMandy 	if (!p)
32*96e28a40SPulkoMandy 		return B_NO_MEMORY;
33*96e28a40SPulkoMandy 	new_lock(&p->lock, "vnidpool lock");
34*96e28a40SPulkoMandy 	p->nextvnid = 1LL;
35*96e28a40SPulkoMandy 	p->bitmap = (BMT *)(p + 1);
36*96e28a40SPulkoMandy 	p->bmsize = size;
37*96e28a40SPulkoMandy 	memset(p->bitmap, 0, size / sizeof(BMT));
38*96e28a40SPulkoMandy 	fprintf(stderr, "vnidpool_alloc: pool @ %p, bitmap @ %p, size %ld\n", p, p->bitmap, p->bmsize);
39*96e28a40SPulkoMandy 	*pool = p;
40*96e28a40SPulkoMandy 	return B_OK;
41*96e28a40SPulkoMandy }
42*96e28a40SPulkoMandy 
vnidpool_free(struct vnidpool * pool)43*96e28a40SPulkoMandy status_t vnidpool_free(struct vnidpool *pool) {
44*96e28a40SPulkoMandy 	unsigned int i;
45*96e28a40SPulkoMandy 	fprintf(stderr, "vnidpool_free: pool @ %p\n", pool);
46*96e28a40SPulkoMandy 	if (!pool)
47*96e28a40SPulkoMandy 		return EINVAL;
48*96e28a40SPulkoMandy 	if (LOCK(&pool->lock) < B_OK)
49*96e28a40SPulkoMandy 		return B_ERROR;
50*96e28a40SPulkoMandy 	/* make sure no vnid is left in use */
51*96e28a40SPulkoMandy 	for (i = 0; i < (pool->bmsize % sizeof(BMT)); i++) {
52*96e28a40SPulkoMandy 		if (pool->bitmap[i])
53*96e28a40SPulkoMandy 			fprintf(stderr, "WARNING: vnidpool_free called with vnids still in use!!!\n");
54*96e28a40SPulkoMandy 			//panic("vnidpool_free: vnids still in use");
55*96e28a40SPulkoMandy 	}
56*96e28a40SPulkoMandy 	free_lock(&pool->lock);
57*96e28a40SPulkoMandy 	free(pool);
58*96e28a40SPulkoMandy 	return B_OK;
59*96e28a40SPulkoMandy }
60*96e28a40SPulkoMandy 
vnidpool_get(struct vnidpool * pool,ino_t * vnid)61*96e28a40SPulkoMandy status_t vnidpool_get(struct vnidpool *pool, ino_t *vnid)
62*96e28a40SPulkoMandy {
63*96e28a40SPulkoMandy 	status_t err = B_ERROR;
64*96e28a40SPulkoMandy 	uint32 i;
65*96e28a40SPulkoMandy 	if (!pool)
66*96e28a40SPulkoMandy 		return EINVAL;
67*96e28a40SPulkoMandy 	if (LOCK(&pool->lock) < B_OK)
68*96e28a40SPulkoMandy 		return B_ERROR;
69*96e28a40SPulkoMandy 	for (i = 0; BM_ISSET(pool, pool->nextvnid) && i < pool->bmsize; pool->nextvnid++, i++) {
70*96e28a40SPulkoMandy 		/* avoid 0 as vnid */
71*96e28a40SPulkoMandy 		if (!pool->nextvnid)
72*96e28a40SPulkoMandy 			continue;
73*96e28a40SPulkoMandy 	}
74*96e28a40SPulkoMandy 	if (BM_ISSET(pool, pool->nextvnid))
75*96e28a40SPulkoMandy 		err = ENOBUFS;
76*96e28a40SPulkoMandy 	else {
77*96e28a40SPulkoMandy 		BM_SET(pool, pool->nextvnid);
78*96e28a40SPulkoMandy 		*vnid = pool->nextvnid++;
79*96e28a40SPulkoMandy 		err = B_OK;
80*96e28a40SPulkoMandy 	}
81*96e28a40SPulkoMandy 	UNLOCK(&pool->lock);
82*96e28a40SPulkoMandy 	return err;
83*96e28a40SPulkoMandy }
84*96e28a40SPulkoMandy 
vnidpool_put(struct vnidpool * pool,ino_t vnid)85*96e28a40SPulkoMandy status_t vnidpool_put(struct vnidpool *pool, ino_t vnid)
86*96e28a40SPulkoMandy {
87*96e28a40SPulkoMandy 	status_t err = B_ERROR;
88*96e28a40SPulkoMandy 	if (!pool)
89*96e28a40SPulkoMandy 		return EINVAL;
90*96e28a40SPulkoMandy 	if (LOCK(&pool->lock) < B_OK)
91*96e28a40SPulkoMandy 		return B_ERROR;
92*96e28a40SPulkoMandy 	if (!BM_ISSET(pool, vnid))
93*96e28a40SPulkoMandy 		err = EINVAL;
94*96e28a40SPulkoMandy 	else {
95*96e28a40SPulkoMandy 		BM_UNSET(pool, vnid);
96*96e28a40SPulkoMandy 		err = B_OK;
97*96e28a40SPulkoMandy 	}
98*96e28a40SPulkoMandy 	UNLOCK(&pool->lock);
99*96e28a40SPulkoMandy 	return err;
100*96e28a40SPulkoMandy }
101*96e28a40SPulkoMandy 
102