2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use is subject to license terms.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * are met:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/types.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/queue.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <bitmap.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <fcntl.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdlib.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <string.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <time.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <unistd.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <tlm.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Hash table size.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_HASH_SIZE 64
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Maximum number of chunk that can be cached.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CHUNK_MAX 128
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Size of bitmap table.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_MAX 256
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Bit_MAP Word SIZE. This should be equal to 'sizeof (int)'.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_WSIZE (sizeof (int))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Bit_MAP Bit Per Word.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_BPW (BMAP_WSIZE * 8)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_BPW_SHIFT 5
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_BPW_MASK (~(~0 << BMAP_BPW_SHIFT))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Chunk of bit map in each node.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CHUNK_WORDS 1024
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CHUNK_BYTES (BMAP_CHUNK_WORDS * BMAP_WSIZE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CHUNK_BITS (BMAP_CHUNK_WORDS * BMAP_BPW)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CHUNK_NO(p) ((p) / BMAP_CHUNK_BITS)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CHUNK_OFF(p) (BMAP_CHUNK_NO(p) * BMAP_CHUNK_BITS)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Bitmap flags.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_BINIT_ONES 0x00000001 /* initial value of bits is 1 */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_INUSE 0x00000002 /* slot is in use */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Macros of bitmap flags.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_SET_FLAGS(b, f) ((b)->bm_flags |= (f))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_UNSET_FLAGS(b, f) ((b)->bm_flags &= ~(f))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_IS_INIT_ONES(b) ((b)->bm_flags & BMAP_BINIT_ONES)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_IS_INUSE(b) ((b)->bm_flags & BMAP_INUSE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define HASH(p) (((p) / BMAP_CHUNK_BITS) % BMAP_HASH_SIZE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Calculate the memory size in bytes needed for the specified length
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of bitmap.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define ROUNDUP(n, d) (((n) + (d) - 1) / (d))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define MEM_LEN(l) (ROUNDUP((l), BMAP_BPW) * BMAP_WSIZE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Chunk flags.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CSET_DIRTY(cp) (cp)->c_flags |= BMAP_CDIRTY
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CDIRTY 0x00000001 /* the chunk is dirty */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Macros on chunk flags.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_CIS_DIRTY(cp) ((cp)->c_flags & BMAP_CDIRTY)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * When loading a bitmap chunk, if it is new set the bitmap
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * can be set according to the initial value of bits.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Otherwise, it should be loaded from the file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_NEW_CHUNK 1
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define BMAP_OLD_CHUNK 0
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Each chunk holds the followin information:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - A flag showing the status of the chunk, like being ditry or not.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Its offset in bits from the beginning of the vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Its length in bits.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Its memory length in use in bytes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The bitmap vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In addition to the above information, each chunk can be on two lists:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * one the hash list, the other LRU list. The hash list is a MRU list,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * meaning the MRU entry is at the head of the list.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * All the chunks are in the LRU list. When a chunk is needed and there is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * no more room for allocating chunks, the first entry of this list is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reclaimed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct dbmap_chunk {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_ENTRY(dbmap_chunk) c_hash;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_ENTRY(dbmap_chunk) c_lru;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t c_flags;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t c_off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t c_clen;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t c_mlen;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t *c_bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} dbmap_chunk_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza SabdarTAILQ_HEAD(dbmap_list, dbmap_chunk);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct dbmap_list dbmap_list_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct dbitmap {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *bm_fname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int bm_fd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bm_flags;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bm_len; /* bitmap length */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bm_cmax; /* maximum number of cached chunks */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bm_ccur; /* current number of cached chunks */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_list_t bm_hash[BMAP_HASH_SIZE]; /* MRU hash table */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_list_t bm_lru; /* LRU list */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} dbitmap_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Disk bitmap table. Upon allocating a dbitmap, one slot
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of this table will be used.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic dbitmap_t dbitmap[BMAP_MAX];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Each chunk holds the followin information:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Its offset in bits from the beginning of the vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Its length in bits.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Its memory length in use in bytes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The bitmap vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In addition to the above information, each chunk can be on a list:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * one the hash list. The hash list is a MRU list, meaning that the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * MRU entry is at the head of the list.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct bmap_chunk {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_ENTRY(bmap_chunk) c_hash;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t c_off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t c_clen;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t c_mlen;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t *c_bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} bmap_chunk_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza SabdarTAILQ_HEAD(bmap_list, bmap_chunk);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct bmap_list bmap_list_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct bitmap {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bm_flags;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bm_len; /* bitmap length */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bm_cmax; /* maximum number of cached chunks */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bm_ccur; /* current number of cached chunks */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_list_t bm_hash[BMAP_HASH_SIZE]; /* MRU hash table */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} bitmap_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Statistics gathering structure.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct bitmap_stats {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_alloc_cnt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_alloc_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_free_cnt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_set_applied;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_unset_applied;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_cache_hit;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_cache_miss;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_chunk_new;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_chunk_flush;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ulong_t bs_chunk_reclaim;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bs_get;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bs_get_bits;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bs_set;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bs_set_bits;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bs_unset;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bs_unset_bits;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} bitmap_stats_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Disk bitmap table. Upon allocating a bitmap, one slot
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of this table will be used.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic bitmap_t bitmap[BMAP_MAX];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Global instance of statistics variable.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbitmap_stats_t bitmap_stats;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmd2bmp
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Convert bitmap descriptor to bitmap pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic bitmap_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmd2bmp(int bmd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmd < 0 || bmd >= BMAP_MAX)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (&bitmap[bmd]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmd_alloc
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate a bitmap descriptor. Sets the INUSE flag of the slot.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmd_alloc(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bitmap;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < BMAP_MAX; bmp++, i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!BMAP_IS_INUSE(bmp)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_SET_FLAGS(bmp, BMAP_INUSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (i);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmd_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Free a bitmap descriptor. Clears the INUSE flag of the slot.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmd_free(int bmd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2bmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_UNSET_FLAGS(bmp, BMAP_INUSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmp_set
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function to set bit in a chunk. This can set or unset the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * specified bit.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic inline int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmp_set(bmap_chunk_t *cp, u_quad_t bn, uint_t *vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t mask;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t *ip;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t v;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn -= cp->c_off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn < cp->c_clen) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mask = 1 <<(bn & BMAP_BPW_MASK);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ip = &cp->c_bmp[bn >> BMAP_BPW_SHIFT];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar v = (*vp <<(bn & BMAP_BPW_MASK)) & mask;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ip = (*ip & ~mask) | v;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -ERANGE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmp_get
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function to get bit in a chunk.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic inline int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmp_get(bmap_chunk_t *cp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bit;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn -= cp->c_off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn < cp->c_clen) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bit = 1 <<(bn & BMAP_BPW_MASK);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = (cp->c_bmp[bn >> BMAP_BPW_SHIFT] & bit) != 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -ERANGE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_chuck_setup
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set up the properties of the new chunk and position it in the hash list.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic bmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_chunk_setup(bitmap_t *bmp, bmap_chunk_t *cp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int h;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t off, l;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t cl, ml;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_list_t *hp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar off = BMAP_CHUNK_OFF(bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar l = bmp->bm_len - off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (l >= BMAP_CHUNK_BITS) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cl = BMAP_CHUNK_BITS;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ml = BMAP_CHUNK_BYTES;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cl = l;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ml = MEM_LEN(l);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (BMAP_IS_INIT_ONES(bmp))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(cp->c_bmp, 0xff, ml);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(cp->c_bmp, 0x00, ml);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar h = HASH(bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hp = &bmp->bm_hash[h];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INSERT_HEAD(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_off = off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_clen = cl;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_mlen = ml;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_chunk_new
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Create a new chunk and keep track of memory used.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic bmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_chunk_new(bitmap_t *bmp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_chunk_new++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = ndmp_malloc(sizeof (bmap_chunk_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (cp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_bmp = ndmp_malloc(sizeof (uint_t) * BMAP_CHUNK_WORDS);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!cp->c_bmp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) bm_chunk_setup(bmp, cp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_ccur++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_chunk_alloc
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate a chunk and return it. If the cache for the chunks is not
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * fully used, a new chunk is created.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic bmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_chunk_alloc(bitmap_t *bmp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmp->bm_ccur < bmp->bm_cmax)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = bm_chunk_new(bmp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * hash_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Free all chunks on the hash list.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarhash_free(bmap_list_t *hp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!hp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (!TAILQ_EMPTY(hp)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = TAILQ_FIRST(hp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_REMOVE(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp->c_bmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_chunks_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Release the memory allocated for the chunks.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_chunks_free(bmap_list_t *hp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < BMAP_HASH_SIZE; hp++, i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hash_free(hp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_chunk_repositions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Re-position the chunk in the MRU hash table.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_chunk_reposition(bitmap_t *bmp, bmap_list_t *hp, bmap_chunk_t *cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bmp || !hp || !cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (TAILQ_FIRST(hp) != cp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_REMOVE(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INSERT_HEAD(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_chunk_find
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Find and return the chunks which holds the specified bit. Allocate
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the chunk if necessary and re-position it in the hash table lists.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic bmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_chunk_find(bitmap_t *bmp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int h;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_list_t *hp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar h = HASH(bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hp = &bmp->bm_hash[h];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_FOREACH(cp, hp, c_hash) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn >= cp->c_off && bn < (cp->c_off + cp->c_clen)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_cache_hit++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_chunk_reposition(bmp, hp, cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_cache_miss++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bm_chunk_alloc(bmp, bn));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmp_setval
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set a range of bits in the bitmap specified by the vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmp_setval(bitmap_t *bmp, bm_iovec_t *vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t cl;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bn;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t max;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn = vp->bmv_base;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar max = bn + vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn >= bmp->bm_len || max > bmp->bm_len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-EINVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*vp->bmv_val) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_set++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_set_bits += vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_unset++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_unset_bits += vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = bm_chunk_find(bmp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-ERANGE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (cl = cp->c_off + cp->c_clen; bn < cl && bn < max; bn++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = bmp_set(cp, bn, vp->bmv_val);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (bn < max);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmp_getval
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get a range of bits in the bitmap specified by the vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmp_getval(bitmap_t *bmp, bm_iovec_t *vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t cnt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t *ip;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t cl;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bn;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t max;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn = vp->bmv_base;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar max = bn + vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn >= bmp->bm_len || max > bmp->bm_len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-EINVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_get++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_get_bits += 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cnt = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ip = vp->bmv_val;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ip = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = bm_chunk_find(bmp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-ERANGE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (cl = cp->c_off + cp->c_clen; bn < cl && bn < max; bn++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = bmp_get(cp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ip |= rv << cnt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (++cnt >= BMAP_BPW) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *++ip = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cnt = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (bn < max);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * hash_init
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Initialize the hash table lists head.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarhash_init(bmap_list_t *hp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < BMAP_HASH_SIZE; hp++, i++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INIT(hp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_alloc
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate a bit map and return a handle to it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The hash table list are empty at this point. They are allocated
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * on demand.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_alloc(u_quad_t len, int set)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int bmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (len == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = bmd_alloc();
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmd < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2bmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_alloc_cnt++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_alloc_size += len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (set)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_SET_FLAGS(bmp, BMAP_BINIT_ONES);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_UNSET_FLAGS(bmp, BMAP_BINIT_ONES);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_len = len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_ccur = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_cmax = BMAP_CHUNK_MAX;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hash_init(bmp->bm_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Free memory allocated for the bitmap.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_free(int bmd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2bmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmp && BMAP_IS_INUSE(bmp)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_free_cnt++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_chunks_free(bmp->bm_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd_free(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_getiov
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get bits specified by the array of vectors.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_getiov(int bmd, bm_io_t *iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t *vp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (!(bmp = bmd2bmp(bmd)))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (iop->bmio_iovcnt <= 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar vp = iop->bmio_iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < iop->bmio_iovcnt; vp++, i++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-EINVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv |= bmp_getval(bmp, vp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_setiov
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set bits specified by the array of vectors.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_setiov(int bmd, bm_io_t *iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t *vp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (!(bmp = bmd2bmp(bmd)))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (iop->bmio_iovcnt <= 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (!iop->bmio_iov)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar vp = iop->bmio_iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < iop->bmio_iovcnt; vp++, i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv |= bmp_setval(bmp, vp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bmd2dbmp
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Convert bitmap descriptor to bitmap pointer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic dbitmap_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbmd2dbmp(int bmd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmd < 0 || bmd >= BMAP_MAX)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (&dbitmap[bmd]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmp2bmd
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Convert bitmap pointer to bitmap descriptor.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmp2bmd(dbitmap_t *bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int bmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = bmp - dbitmap;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmd < 0 || bmd >= BMAP_MAX)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmd_alloc
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate a bitmap descriptor.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Sets the INUSE flag of the slot.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmd_alloc(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = dbitmap;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < BMAP_MAX; bmp++, i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!BMAP_IS_INUSE(bmp)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_SET_FLAGS(bmp, BMAP_INUSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (i);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmd_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Free a bitmap descriptor.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Clears the INUSE flag of the slot.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmd_free(int bmd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2dbmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_UNSET_FLAGS(bmp, BMAP_INUSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmp_set
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function to set bit in a chunk. This can
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * set or unset the specified bit.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic inline int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmp_set(dbmap_chunk_t *cp, u_quad_t bn, uint_t *vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t mask;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t *ip;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t v;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn -= cp->c_off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn < cp->c_clen) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mask = 1 <<(bn & BMAP_BPW_MASK);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ip = &cp->c_bmp[bn >> BMAP_BPW_SHIFT];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar v = (*vp <<(bn & BMAP_BPW_MASK)) & mask;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ip = (*ip & ~mask) | v;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_CSET_DIRTY(cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -ERANGE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmp_getlen
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get length of the bitmap.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic u_quad_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmp_getlen(dbitmap_t *bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bmp ? bmp->bm_len : 0LL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmp_get
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Generic function to get bit in a chunk.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic inline int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmp_get(dbmap_chunk_t *cp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t bit;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn -= cp->c_off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn < cp->c_clen) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bit = 1 <<(bn & BMAP_BPW_MASK);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = (cp->c_bmp[bn >> BMAP_BPW_SHIFT] & bit) != 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -ERANGE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_seek
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Seek in the file where the chunk is saved or should be saved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_seek(dbitmap_t *bmp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar off_t off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar off = BMAP_CHUNK_NO(bn) * BMAP_CHUNK_BYTES;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = (lseek(bmp->bm_fd, off, SEEK_SET) != off) ? -1 : 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_flush
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Save a chunk to file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_flush(dbitmap_t *bmp, dbmap_chunk_t *cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_chunk_flush++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bmp || !cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (dbm_chunk_seek(bmp, cp->c_off) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (write(bmp->bm_fd, cp->c_bmp, cp->c_mlen) != cp->c_mlen)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_load
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Load a chunk from a file. If the chunk is a new one,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * instead of reading from the disk, the memory for the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * chunk is set to either all zeros or to all ones.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Otherwise, if the chunk is not a new one, it's read
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * from the disk.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The new chunk is positioned in the LRU and hash table
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * after its data is ready.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic dbmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_load(dbitmap_t *bmp, dbmap_chunk_t *cp, u_quad_t bn, int new)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int h;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t off, l;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t cl, ml;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_list_t *hp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar off = BMAP_CHUNK_OFF(bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar l = bmp->bm_len - off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (l >= BMAP_CHUNK_BITS) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cl = BMAP_CHUNK_BITS;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ml = BMAP_CHUNK_BYTES;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cl = l;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ml = MEM_LEN(l);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (new == BMAP_NEW_CHUNK) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (BMAP_IS_INIT_ONES(bmp))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(cp->c_bmp, 0xff, ml);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(cp->c_bmp, 0x00, ml);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else { /* BMAP_OLD_CHUNK */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (dbm_chunk_seek(bmp, bn) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (read(bmp->bm_fd, cp->c_bmp, ml) != ml)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (cp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INSERT_TAIL(&bmp->bm_lru, cp, c_lru);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar h = HASH(bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hp = &bmp->bm_hash[h];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INSERT_HEAD(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_flags = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_off = off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_clen = cl;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_mlen = ml;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_new
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Create a new chunk and keep track of memory used.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic dbmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_new(dbitmap_t *bmp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_chunk_new++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = ndmp_malloc(sizeof (dbmap_chunk_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (cp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp->c_bmp = ndmp_malloc(sizeof (uint_t) * BMAP_CHUNK_WORDS);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!cp->c_bmp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!dbm_chunk_load(bmp, cp, bn, BMAP_NEW_CHUNK)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp->c_bmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_ccur++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_alloc
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate a chunk and return it. If the cache for the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * chunks is not fully used, a new chunk is created.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Otherwise, the first chunk from the LRU list is reclaimed,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * loaded and returned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic dbmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_alloc(dbitmap_t *bmp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int h;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_list_t *hp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmp->bm_ccur < bmp->bm_cmax)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (dbm_chunk_new(bmp, bn));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_chunk_reclaim++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = TAILQ_FIRST(&bmp->bm_lru);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (BMAP_CIS_DIRTY(cp))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) dbm_chunk_flush(bmp, cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_REMOVE(&bmp->bm_lru, cp, c_lru);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar h = HASH(cp->c_off);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hp = &bmp->bm_hash[h];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_REMOVE(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (dbm_chunk_load(bmp, cp, bn, BMAP_OLD_CHUNK));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunks_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Release the memory allocated for the chunks.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunks_free(dbitmap_t *bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_list_t *headp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar headp = &bmp->bm_lru;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!headp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (!TAILQ_EMPTY(headp)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = TAILQ_FIRST(headp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_REMOVE(headp, cp, c_lru);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp->c_bmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_reposition
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Re-position the chunk in the LRU and the hash table.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_reposition(dbitmap_t *bmp, dbmap_list_t *hp, dbmap_chunk_t *cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmp && hp && cp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_REMOVE(&bmp->bm_lru, cp, c_lru);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INSERT_TAIL(&bmp->bm_lru, cp, c_lru);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (TAILQ_FIRST(hp) != cp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_REMOVE(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INSERT_HEAD(hp, cp, c_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_find
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Find and return the chunks which holds the specified bit.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate the chunk if necessary and re-position it in the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LRU and hash table lists.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic dbmap_chunk_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_find(dbitmap_t *bmp, u_quad_t bn)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int h;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_list_t *hp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar h = HASH(bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hp = &bmp->bm_hash[h];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_FOREACH(cp, hp, c_hash) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn >= cp->c_off && bn < (cp->c_off + cp->c_clen)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_cache_hit++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbm_chunk_reposition(bmp, hp, cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_cache_miss++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (dbm_chunk_alloc(bmp, bn));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmp_setval
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set a range of bits in the bitmap specified by the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmp_setval(dbitmap_t *bmp, bm_iovec_t *vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t cl;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bn;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t max;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn = vp->bmv_base;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar max = bn + vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn >= bmp->bm_len || max > bmp->bm_len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-EINVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*vp->bmv_val) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_set++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_set_bits += vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_unset++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_unset_bits += vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = dbm_chunk_find(bmp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-ERANGE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (cl = cp->c_off + cp->c_clen; bn < cl && bn < max; bn++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = dbmp_set(cp, bn, vp->bmv_val);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (bn < max);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbmp_getval
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get a range of bits in the bitmap specified by the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * vector.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbmp_getval(dbitmap_t *bmp, bm_iovec_t *vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t cnt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t *ip;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t cl;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t bn;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t max;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bn = vp->bmv_base;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar max = bn + vp->bmv_len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bn >= bmp->bm_len || max > bmp->bm_len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-EINVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_get++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_get_bits += 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cnt = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ip = vp->bmv_val;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ip = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = dbm_chunk_find(bmp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-ERANGE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (cl = cp->c_off + cp->c_clen; bn < cl && bn < max; bn++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = dbmp_get(cp, bn);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ip |= rv << cnt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (++cnt >= BMAP_BPW) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *++ip = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cnt = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (bn < max);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbyte_apply_ifset
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Apply the function on the set bits of the specified word.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbyte_apply_ifset(dbitmap_t *bmp, u_quad_t off, uint_t b, int(*fp)(),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar void *arg)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int bmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t l;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar l = dbmp_getlen(bmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = dbmp2bmd(bmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (; b && off < l; off++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (b & 1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_set_applied++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((rv = (*fp)(bmd, off, arg)))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar b >>= 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_chunk_apply_ifset
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Apply the function on the set bits of the specified chunk.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_chunk_apply_ifset(dbitmap_t *bmp, dbmap_chunk_t *cp, int(*fp)(),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar void *arg)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t *bp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t i, m;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t q;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bp = cp->c_bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar q = cp->c_off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar m = cp->c_mlen / BMAP_WSIZE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < m; q += BMAP_BPW, bp++, i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*bp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = dbyte_apply_ifset(bmp, q, *bp, fp, arg);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * swfile_trunc
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Truncate the rest of the swap file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarswfile_trunc(int fd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar off_t off;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get the current offset and truncate whatever is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * after this point.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((off = lseek(fd, 0, SEEK_CUR)) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (ftruncate(fd, off) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * swfile_init
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Initialize the swap file. The necessary disk space is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * reserved by writing to the swap file for swapping the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * chunks in/out of the file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarswfile_init(int fd, u_quad_t len, int set)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t i, n;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t cl, ml;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t buf[BMAP_CHUNK_WORDS];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(buf, set ? 0xff : 0x00, BMAP_CHUNK_BYTES);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar n = len / BMAP_CHUNK_BITS;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < n; i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (write(fd, buf, BMAP_CHUNK_BYTES) != BMAP_CHUNK_BYTES)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cl = (uint_t)(len % BMAP_CHUNK_BITS);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ml = MEM_LEN(cl);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (write(fd, buf, ml) != ml)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (swfile_trunc(fd));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_alloc
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Allocate a bit map and return a handle to it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The swap file is created if it does not exist.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The file is truncated if it exists and is larger
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * than needed amount.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The hash table and LRU list are empty at this point.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * They are allocated and/or loaded on-demand.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_alloc(char *fname, u_quad_t len, int set)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int fd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int bmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fname || !*fname || !len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * When allocating bitmap, make sure there is enough
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * disk space by allocating needed disk space, for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * writing back the dirty chunks when swaping them out.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = dbmd_alloc();
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmd < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2dbmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((fd = open(fname, O_RDWR|O_CREAT, 0600)) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (swfile_init(fd, len, set) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) unlink(fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmd_free(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!(bmp->bm_fname = strdup(fname))) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) unlink(fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmd_free(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_alloc_cnt++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_alloc_size += len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_fd = fd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (set)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_SET_FLAGS(bmp, BMAP_BINIT_ONES);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar BMAP_UNSET_FLAGS(bmp, BMAP_BINIT_ONES);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_len = len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_ccur = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp->bm_cmax = BMAP_CHUNK_MAX;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TAILQ_INIT(&bmp->bm_lru);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hash_init((bmap_list_t *)bmp->bm_hash);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Free memory allocated for the bitmap and remove its swap file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_free(int bmd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2dbmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bmp && BMAP_IS_INUSE(bmp)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bitmap_stats.bs_free_cnt++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbm_chunks_free(bmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(bmp->bm_fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) unlink(bmp->bm_fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(bmp->bm_fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmd_free(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_getlen
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Return length of the bitmap.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaru_quad_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_getlen(int bmd)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2dbmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (dbmp_getlen(bmp));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_set
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set a range of bits.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_set(int bmd, u_quad_t start, u_quad_t len, uint_t val)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_io_t io;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_base = start;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_len = len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_val = &val;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iovcnt = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iov = &iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (dbm_setiov(bmd, &io));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_getiov
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get bits specified by the array of vectors.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_getiov(int bmd, bm_io_t *iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t *vp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (!(bmp = bmd2dbmp(bmd)))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (iop->bmio_iovcnt <= 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar vp = iop->bmio_iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < iop->bmio_iovcnt; vp++, i++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!vp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-EINVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv |= dbmp_getval(bmp, vp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_setiov
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set bits specified by the array of vectors.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_setiov(int bmd, bm_io_t *iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t *vp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!iop)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (!(bmp = bmd2dbmp(bmd)))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (iop->bmio_iovcnt <= 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (!iop->bmio_iov)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -EINVAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar vp = iop->bmio_iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < iop->bmio_iovcnt; vp++, i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv |= dbmp_setval(bmp, vp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_apply_ifset
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Call the callback function for each set bit in the bitmap and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * pass the 'arg' and bit number as its argument.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_apply_ifset(int bmd, int(*fp)(), void *arg)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_quad_t q;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbitmap_t *bmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbmap_chunk_t *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bmp = bmd2dbmp(bmd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bmp || !fp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-EINVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (q = 0; q < bmp->bm_len; q += BMAP_CHUNK_BITS) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = dbm_chunk_find(bmp, q);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!cp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -ERANGE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = dbm_chunk_apply_ifset(bmp, cp, fp, arg);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_set
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set a range of bits.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_set(int bmd, u_quad_t start, u_quad_t len, uint_t val)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_io_t io;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_base = start;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_len = len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_val = &val;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iovcnt = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iov = &iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bm_setiov(bmd, &io));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_get
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get a range of bits.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_get(int bmd, u_quad_t start, u_quad_t len, uint_t *buf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_io_t io;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_base = start;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_len = len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_val = buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iovcnt = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iov = &iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (bm_getiov(bmd, &io));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * bm_getone
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get only one bit.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarbm_getone(int bmd, u_quad_t bitnum)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bm_get(bmd, bitnum, 1, &i) == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (i ? 1 : 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_get
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get a range of bits.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_get(int bmd, u_quad_t start, u_quad_t len, uint_t *buf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_io_t io;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bm_iovec_t iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_base = start;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_len = len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar iov.bmv_val = buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iovcnt = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar io.bmio_iov = &iov;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (dbm_getiov(bmd, &io));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dbm_getone
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get only one bit.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardbm_getone(int bmd, u_quad_t bitnum)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar uint_t i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (dbm_get(bmd, bitnum, 1, &i) == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (i ? 1 : 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}